페블 프로그래밍 한달 후기

"시간만 있으면 이것 저것을 해볼 수 있을 텐데~" 노래를 불러댔었다.  그래서, 지금처럼 시간이 주어졌을 때 한 껏 해보고 싶은 프로그래밍을 해보았다.

 

말이 한달이지 실제로 페블 코딩은 2주 정도 걸린듯하다. 그 나머지 2주는 Pebble 프로그래밍에 적용하기위한 “비동기 이벤트 프레임워크“를 만드는데 소비했기 때문이다.  또 … 왠 프레임워크냐고 할 개발자도 있겠으나, Pebble SDK 를 사용해서 어플을 만드는 과정은  쉬운 과정에 속하지만  재사용하기 용이한 모듈을 만들어 즐겁게 코딩하기에는 느므 느므 느므… 귀찮고 성가신 부분도  있기  때문이다.

 

Pebble SDK 2.01https://developer.getpebble.com/2/ 은 C 언으로 페블 어플리케이션을 개발하기에 꽤 근사한 수준의 API를 제공한다. 물론, 당연히 콜백 (Callback API) 덩어리지만,  그래도 1.0 버전에 비하면 상당히 나아졌다는 평가가 많고 나 역시 배우는데 크게 부담스럽다든가 힘든 것은 거의 없었다.   십여년 넘게 손 놓았던 C언어를 다시 해야함에도 불구하고 페블코딩을 하게된 것은  $150 달러로 대폭? 할인된 기계값이 영향이 컸다.  나름 만들고 싶은 시계를 때때로 끄적거리며 스케치하기도 했었고 빤짝~ 하는 아이디어를 구현해 보고 싶기도 했다.

거의 다시 시작하는 기분으로 C 코딩을 하였지만 어찌된 일인지 크게 어려움은 없었다. 당연히 그렇게 어려운 사항이 C 언어에 있을리가 없지 ㅋ  더블포인터를 다시 쓰고 있자니 C언어로 골치아프던 때의 향수가 아른거릴 지경이다.  최신 스펙인  C11 규약으로 C 프로그래밍을 할 수 있다고해도 어쩔 수 없이 엉키게되는 콜백덩어리를 손쉽게 다룰 방법이 필요하다.  특히  MenuLayer와 함께 여러 기능을 묶어 제대로된 기능을 구현하려고 할 때면 꼬여만 가는 실타래 마냥 콜백의 향연이 펼쳐지면서  그냥 때려치우고 싶을 때가  오기도 하였다.   그 덕분에 비동기 이벤트 프레임워크를 만들게 되었지만 시작한지 2주 정도 사이에 한번의 고비가 왔다고나 할까..

 

그때는 멋진 프레임워크를 만들려고 하지않고 그저 눈앞에 떠오른 생각을 최대한 간단하게 구현하는 것이 도움이 된다고 생각한다.  조금씩 조금씩 눈에 보이게 하면서 살을 붙여간다는 말은 참으로 별것 아니지만, 아이폰이나 안드로이드 앱을 통해 눈이 높아질때로 높아진 상태에서 “Hello World” 수준의 앱을 보는 것은 그렇게 멋지지 않다 ㅋ

 

게다가 가용 메모리가 25K 미만인 페블 환경에서 코딩한다는 것은 브라우저에서 코딩할 때와는 달리 사소한 것까지 신경써야 한다. 무엇보다 메모리를 마구마구 쓰지 않도록 조심해야하고 메모리 할당에 대한 해제를 확실해 해줘야 한다. 이것만 제대로 맞춰도 문제될 것이 거의 없다고해도 과언이 아니다.  static 변수를 많이 쓰면 귀찮음은 덜 수 있지만 어느순간 BSS 사이즈가 커서 제대로 동작하지 못한다는 경고를 받을 수도 있다.

 

흑백 표시밖에 되지 않는다해도 이미지를 로딩하면 리소스용량도 꽤 먹는다. 특히 폰트는 메모리 먹는 하마인데  Custom 폰트를 사용할 수는 있어도 메모리를 꽤 먹는 편이라 이것 저것 닥치는대로 사용하기엔 부담이 간다.  한글 폰트에 대한 공식적인 지원은 없고 Firmware 수정으로 한글을 지원하는 프로젝트2http://ipkn.github.io/pebble/를 통해  한글 Firmware를 사용해볼 수는 있다. 

 

시계내에 데이타를 저장하는 사항에도 리소스제한이 걸려있다. 하나의 리소스당 256B를 넘지 못하고 모두 합쳐 4K를 넘지 못한다.  Pulse 앱을 만들면서 생각지도 못한 황당한 상황중에 한가지가 바로 그 리소스 제한 때문에 3시간 넘게 삽질한 경우이다.  24개의 struct data를 저장하는 단순 로직이었는데 앱을 종료하고 다시 시작할 때 마다 그래프 일부분이 잘려버리거나 enum 타입 값이 변동이 되는 현상을 캐치할 때 까지 무한 로딩-크래쉬-재코딩-로깅을 반복해야했다.  한참을 삽질하고 나서야 sizeof()로 출력되는 값이 256B를 넘는 320B 인 것을 눈치챘고, 그렇게 수정하기 까지 몇시간이 걸린 것 자체가 디버깅의 난감함을 여실히 보여주는 사례라 하겠다.

 

Pebble 공식 시뮬레이터는 없다. 그러나, 몇몇 모듈을 사용하지 않는다면 Pebble 기기에 설치하지 않고 Local 시뮬레이터3https://github.com/Helco/PebbleLocalSim.git를 통해 결과를 미리 볼 수도 있다.  꽤 유용하다. Sublime Text를 편집기로 사용한다면 시뮬레이터용 Build 메뉴를 추가할 수 있어 단 한번의 단축키로 컴파일/빌드/시뮬레이터 작동까지 일사천리로 진행되므로 손쉽게 개발 할 수 있다:

{
    "shell_cmd": "cd ../sim/ && make clean && make && ./PebbleSim",
    "file_regex": "^../src/(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$"
}

Pebble-Build-in-Simulator.sublime-build

 

하지만, 사용하지 못하는 그 몇몇 모듈이 문제다. 데이타를 처리하는 대부분의 앱에서는 MenuLayer를 사용하는 것이 일반적인 UI 인데,  안타깝게도 현재 상태에선 SImulator용 MenuLayer 구현이 없어 링크 오류가 발생한다. MenuLayer 및 몇몇 모듈을 사용해야한다면  시뮬레이터를 사용할 수 없고 따라서 머리속의 꿈나라 상상으로만 진행할 수 밖에 없다.  꽤나 고역인 작업이다.  시뮬레이터의 Graphic 표시는 실제 기기에서 표시되는 것과 사뭇 다른 경우을 종종 보았다.  아무래도 해상도 차이때문이거나 시뮬레이터 자체의 버그일 가능성도 있을 것이다.  또한, 메모리 누수를 파악할 수 없기 때문에 실제 디바이스에 설치 후 몇가지 테스트 동작을 진행한뒤 종료시켜야  혹 발생할지 모르는 메모리 누수 잡아낼 수 있다. 좀 많이 아쉬운 부분이다.  더 많이 아쉬운 것은, 디버깅 상태의 연결에서 나오는 메세지 때문에 전반적인 실행시간이나 타이밍이 실제 동작과는 다르다는 점이다.

 

몇몇 아쉬운 점에도 불구하고 분명 시뮬레이터는 페블 개발에 큰 도움이 되는 것은 확실하다. 어느 정도 익숙해지면 시뮬레이터없이도 대부분의 문제점을 파악할 수 있으나,  “App Crashed” 경고를 본다면  공식 시뮬레이터 지원을 학수고대하게 될지 모른다. 이 메세지를 보더라도 어떤 부분을 수정한 뒤에 오류가 났는지 알 수 없다면 유격장 가스실 들어가기 전 상황과 다를바가 없는 셈이된다.  얼마나 뺑이 쳐야할지 감이 오지 않고 답답~하기만 .. 한 그 느낌.. 그대로이기 때문이 ㅎㅎ    내 경우는 가능한 작은 단위로 잘게 잘라 부분 기능을 완성한 후 합치는 과정을 되풀이 했다.  (이 방법외에 달리 적용할 수 있는 방법이 없을듯?)

 

SDK 1.0 버전에서는 조그만 실수라도 시계자체를 먹통으로 만들거나 리셋시키는 경우가 다반사였다고 하지만, 현재 SDK 2.0 버전에서는 memory protection이 강화되어 어플리케이션의 영향으로 시계자체가 리셋되는 경우는 거의 보지 못했다. 그러나 메모리 처리를 소흘히해서 누수가 계속될 경우 불가피하게 리셋해야하는 경우가 올수도 있다고 한다. 이 때문에 개발과정에서 메모리 누수여부를 점검하는 것 자체가 큰 일중의 하나였고, 간혹 40B, 108B 등의 메모리 누수가 있다고 로그가 떨어지면 … -_-) 압박이 장난 아니었다.  겨우 몇바이트이지만 쌓일수록 가용메모리가 줄어들기 때문에 그냥 둘순없다.  간혹 멋져보이는 어플리케이션이라도 메모리 누수가 발견되면, 재고할 필요없이 삭제해버렸다.  페블은 시계라기 보다는 손목에 찬 매트릭스의 전화기와 같다고 생각들기도 한다.

 

가장 적은 시간동안 빨리 페블 코딩에 적응하는 방법 가운데 하나는 SDK에 포함된 예제를 요리 조리 고치며 감각을 얻는 것이 확실한 방법일 것이다. 거의 대부분의 영역에 대해 예제가 제공되므로 API 문서를 보는 것보다 훨씬 직관적이다.  물론 한계는 명확하고  평소 자신이 아는 만큼  예제를 통해 방법이 보이기 때문에 사람마다 편차가 있으리라 생각한다.  다른 언어, 다른 프레임워크, 다른 개발 환경.. 에서의 경험치 만큼 쉽게 보이기 때문에 프론트엔드 개발로 꽤나 머리 굴렸던 개발자라면 페블 프로그래밍은 그야말로 껌? 포장지 벗기는 수준이라고나 할까… ㅎ

 

지난 몇주동안 페블 프로그래밍에 전력투구하며 나름 쓸만한 것을 몇개 만들었다. 그중에 맘에 드는 몇가지는 모두 JavaScript 프로그래밍에서의 경험치에서 나온 것이다.  JavaScript 코딩이 C언어를 이렇게 쉽게 보이게 할 줄이야;;; ㅎㅎㅎ

 

제일 먼저 만든 것은 var 타입을 구현한 것인데,  지금 생각해보면 왜 그런 짓을 했을까.. 생각들지만, 한달이내에 이렇게 재밌게 된 것도 이 var 타입 변수를 구현한 덕분인것같다.  그후에 Array, KeyList, vdict,  reference type들을 구현하였고 이 것들을 조합해서 복잡한 구조의 유틸리티 자료구조를 만들수 있었다. 몇가지 기본 구조를 복합적으로 사용해서 JavaScript의 이벤트 시그널을 보내고 받는 것과 동일한 bind, unbind, emit, trigger 등을 구현했고 샘플 코드는 아래 코드처럼 단순하다  (gist 삭제됨)  ㅋ  거의 JavaScript 구문과 비슷하다.  위의 함수는 다 non-block async 함수들이다. 덕분에 모듈간의 간섭을 크게 줄일 수 있었고 얽히고 섥히는 Pebble SDK C 콜백구문이 허전할 정도로 깔끔해질 수 있었다.  특히 ProgressBar를 구현할 때에, malloc() 받은 포인터에  이벤트를 결합시킬 수 있게하여 반쯤 객체지향 코딩스타일을 사용할 수 있게되었다.

 

계속해서 Analog Window Layer 라는 모듈을 작성해서 시계와 관련된 대부분을 라이브러리화 할 수 있었고,  setTimeout, clearTimeout, setInterval등의 JS쪽에서 사용하던 이름 그대로 유틸리티 함수들을  모두 손쉽게 비동기 넌블락함수로 구현하였다.  한달이 다되는 시점에서 유한상태머신을 만들고나서는 JS코딩을 하는 것인지 C코딩을 하는 것인지 조금 의아해졌다 😉

 

Pulse - Pomodoro timer
Pulse – Pomodoro timer

이런 것들을 적용해서 나름 쉽게 제작하게된  뽀모도로 어플을 페블 앱스토어에 등록4http://forums.getpebble.com/discussion/11444/watch-app-sdk2-pulse-pomodoro-timer-for-pebble-뽀모도로-타이머-앱#latest하였다.  제작 과정을 생각한다면야 결코 쉽사리 만들어진 것은 아니지만 JavaScript 개발 경험이 답답하기만 했던 C 프로그래밍에 적용될 때, 고리타분했던 C 프로그래밍도 나름 재미난 분야가 될 수 있다는 것을 알게된 계기가 된 셈이다.

 

프론트엔드와 페블, 이른바 웨어러블 디바이스와의 결합이란 부분에서 참 재밌고 흥미로운 생각들이 점점 쏟아져 나오는 이때에 페블앱 개발이란 영역을 맛본 것이 도리어 프론트엔드의 확장에 많은 도움이 되었다고나 할까..  어떤 언어를 사용하든 각각의 환경에서의 경험치가 서로간에 도움을 준다는 말은  그저 잘난체하려는 그런 소리가 아니다.  돈이 되는 것을 만들어야 한다는 부담에서 벗어나 무모해 보이고 별 소득없어 보이는 분야라도 어느 부분에서는 개발자에게 도움을 준다는 것은 확실하다.  한달이란 시점은 무엇인가를 판단하기엔 너무 이르긴하다.  그러나 오랜만에 열정을 쏟아냈던 터라, 이렇게 기록으로 남긴다.

 

References   [ + ]

1. https://developer.getpebble.com/2/
2. http://ipkn.github.io/pebble/
3. https://github.com/Helco/PebbleLocalSim.git
4. http://forums.getpebble.com/discussion/11444/watch-app-sdk2-pulse-pomodoro-timer-for-pebble-뽀모도로-타이머-앱#latest