“컴퓨터 분야에서 디버깅이란 컴퓨터 프로그램이나 하드웨어 장치에서 잘못된 부분, 즉 버그를 찾아서 수정하거나 또는 에러를 피해나가는 처리과정이다” -텀즈-
우리는 항상 문제가 있고, 이 문제를 해결하기 위해 노력을 한다. 수학 문제를 풀기 위해, 남은 업무를 마무리하기 위해 노력을 한다. 윈도우CE 개발에 있어서도 디버깅은 중요한 문제이며 어려운 작업이다. 윈도우CE 개발에 있어서 디버깅은 ‘하드웨어’와 ‘동시성’이라는 두 가지의 어려움을 내포한다.
윈도우CE시스템 개발은 새로운 하드웨어상에서 이루어지기 때문에 하드웨어의 문제와 어우러진 복잡한 문제가 발생할 수 있다. 하드웨어에서 발생한 문제인지 아니면 디바이스 드라이버의 코드상의 문제인지, 아니면 복합적인 문제인지 알기 어렵다는 것이다.
다른 하나의 문제는 운영체제라는 특성과 이 운영체제가 실시간 운영체제(RTOS)라는 점이다. 즉, 프로그램이나 드라이버가 동시에 실행되는 것을 가정하고 문제를 해결해야 한다는 것이다.
하지만 이런 문제들을 다 극복하고 제품을 만들어야 한다는 분명한 목표가 있다. 모든 문제에는 해결 방법이 있다. 다만 그 해결 방법을 찾아가는 과정이 어려울 뿐이다.
윈도우CE 개발에 있어서 디버깅에 관한 문제를 어떻게 다루어야 하는지 생각해보는 시간을 갖도록 하겠다. 일반적인 디버깅 방법과 방법론들은 이론적이나 책으로 접할 수 있는 방법이 많기 때문에 윈도우CE 운영체제 개발과정중에 사용해야 할 방법들에 대해 확인해 보고자 한다.
1. 원도우CE 운영체제 디버깅 방법에 대한 소고
처음 윈도우CE 운영체제에 대한 프로젝트를 시작했을 때 사용했던 디버깅 방법은 시리얼 포트를 통해 나오는 디버깅 메시지를 하이퍼터미널 프로그램을 통해 보는 것이었다. 드라이버나 응용프로그램에 추가해 두었던 디버그 메시지가 시리얼을 통해 출력하여 동작 중에 어떤 문제가 생기는지 확인하는 방법이다. 가장 원시적이고, 전통적이고, 효과적이고(?), 하지만 개발자의 인내심을 요구하는 디버깅 방법이다. 디버깅을 위한 특별한 장치나 소프트웨어의 도움이 없이도 할 수 있는 방법이다.
하지만 발생된 문제를 쉽게 찾을 수 없고, 문제에 대한 접근 방법이 막연하다는 단점이 있다. 이러한 디버깅 방법을 선택한 것은 개발 초기에 디버깅 환경에 대한 이해가 부족했고 프로젝트의 특성상 빨리 동작되는 윈도우CE 운영체제 장비가 필요했기 때문이다.
결국 잘못된 시작으로 프로젝트가 종료가 될 때까지 제대로 된 디버깅 환경을 갖추지 않은 체 개발을 진행하였다. 지금 와서 생각하면 만약 초기에 디버깅 환경을 제대로 준비 했더라면 개발이 좀더 빠르게 진행되지 않았을까 생각한다. 이러한 연유로 윈도우CE 운영체제 개발에 있어 디버깅 환경 구축 및 디버깅 방법에 대해 집고 넘어가고자 한다. 이번에 살펴보고자 하는 내용은 다음과 같다.
초기 개발 시 디버깅 환경의 중요성
디버깅 방법 및 종류 – 윈도우CE 개발 시 사용하는 디버깅 방법 및 종류
개발 시 사용되는 디버깅 방법
2. 윈도우CE 개발 시 최고의 디버깅 방법은?
물론 필자 역시 어떠한 방법이 가장 좋은 디버깅 방법인지는 지금까지도 알지 못한다. 어떻게 해야 문제를 빨리 찾아내고 해결할 수 있는지는 지금까지도 찾고 있는 문제다. 개발 기간 동안 한 문제를 해결하기 위해 6개월 이상을 소비한 버그도 있었으며, 발견된 즉시 해결된 문제도 있다.
문제의 난이도에 따라서, 문제의 성격에 따라서 디버깅하는 방법이 다양하기 때문이다. 하지만 지금 되돌아보면 다음과 같은 요인들이 윈도우CE에서 빠르게 문제를 확인하고 디버깅 하는 방법이라고 생각한다.
문제 상황 재현 - 문제를 풀기 위해서는 문제를 재현하기 위한 방법을 정확히 알고 있어야 한다. 어떤 식으로 동작을 시켰을 때 오류가 나며, 시스템의 문제를 일으키는지 찾을 수 있어야 한다.
하지만 윈도우CE 시스템에서 발생한 문제들은 한 소스 코드라인의 오류로 발생하는 간단한 문제에서부터, 이 간단한 문제가 누적되어 나비효과처럼 문제의 원인을 제공해 시스템의 문제를 일으키는 복잡한 문제까지 다양하다.
일례를 든다면 윈도우CE 운영체제에서 메모리 누수 문제의 경우 단시간 테스트 시에는 문제가 없지만 장시간, 반복 테스트의 경우 문제가 생기는 경우가 있다. 이런 경우는 메모리 누수가 생긴다는 것을 확인하지 않는 한 원인과 결과를 결부 시키기가 매우 어렵다. 디바이스 드라이버내의 함수에서 1Kbyte씩 할당을 하고 해제를 안 하도록 프로그램을 작성한다면 메모리 부족으로 시스템이 멈추기까지는 많은 시간이 걸릴 것이다. 따라서 어떻게 빠르게 재현할 수 있는가는 디버깅을 하기 위한 좋은 발판이 된다.
문제에 대한 정확한 이해 - 같이 여러 엔지니어와 일을 하다 보면 다양한 엔지니어의 모습을 보게 된다. ‘Copy & Paste’로 일관하는 개발자, 지극히 꼼꼼하여 프로그램 라인의 스페이스까지도 정렬 시키는 개발자, 속전 속결 개발자 등 다양한 개발자들이 있다. 이런 개발자중에 디버깅을 가장 잘 하는 엔지니어는 작성한 코드에 대한 내용을 세부적으로 잘 아는 개발자다. 당연한 이야기겠지만 이 원칙이 지켜지지 않는 경우는 흔히 볼 수 있다.
윈도우CE를 디버깅 하기 위해서는 윈도우CE라는 시스템의 이해, 임베디드 시스템이라는 하드웨어적인 이해, 문제를 해결하고자 하는 인내심, 그리고 마지막으로 문제에 대한 정확한 이해가 윈도우CE에서 디버깅을 하기 위한 중요한 요소라 하겠다.
필자는 윈도우CE 관련 커뮤니티에서 문의하는 질문을 볼 때 여러 가지 생각을 하게 된다. 수준 높은 질문을 통해 필자의 실력을 의심해 보기도 하지만 과연 윈도우CE라는 임베디드 시스템을 다룰 엔지니언가? 더욱더 나가 과연 C언어라도 제대로 공부하고 업무를 시작했는가?라는 의문을 가질 때가 있다. 말을 잘하기 위해서는 어법을 정확히 배워야 하듯 윈도우CE를 디버깅하기 위해서는 윈도우CE에서 사용하는 C/C++ 언어에 대한 기본기량은 필수 요소라 하겠다.
디버깅 방법 - 필자의 동료 중에 유난히 소프트웨어를 잘 다루는 이가 있었다. 새로운 PC 프로그램이 나오면 사용 방법을 익히고 어떻게 잘 사용하는지 연구하는 부류였다. 그는 윈도우CE 개발에도 동일한 행동을 보여줬다. 플랫폼 빌더에서 사용하는 디버거의 기능을 잘 이용하고 세세한 기능까지 파악하였다. 동작 중 문제가 발생하면 디버거의 다양한 기능을 이용하여 빠른 시간 내에 디버깅 하는 모습을 보여 줬다. 디버깅하기 위해 만들어진 디버거 프로그램을 잘 다루면서 갖게 되는 이점이다. 디버거에는 많은 기능이 있다. 이러한 기능을 잘 익혀두는 것도 디버깅을 빠르게 하기 위한 필수 요소라 하겠다.
3. 윈도우CE 개발 시 사용되는 디버깅 방법
플랫폼 빌더를 사용하면 윈도우CE에서 디버깅을 할 수 있다고 하였다. 플랫폼 빌더 뿐만 아니라 하드웨어 형태의 JTAG 디버거를 이용하여도 디버깅을 할 수 있다. 플랫폼 빌더에 포함된 디버거는 개발보드와 플랫폼 빌더 간의 통신을 통한 소프트웨어적인 디버깅 방법이다. 따라서 개발보드에 Eboot가 제대로 포팅이 되었다면 이용할 수 있다. JTAG 디버거를 이용한 디버깅 방법은 별도의 하드웨어 장비를 이용하는 디버깅 방법이다. 요즘 출시되는 대부분의 프로세서에는 JTAG이라는 포트가 있고 이 포트를 이용하여 디버깅을 할 수 있게 하는 장치이다. 하지만 장비의 대부분이 고가라는 단점이 있다.
4. KITL(Kernel Independent Transport Layer)
모니터 프로그램(Monitor Program)이나 디버거 모니터와 같은 용어를 들어 본적이 있는가? 필자의 경우 임베디드 시스템 개발을 처음 개발할 당시 이러한 프로그램을 구입해서 사용했었다. 그 당시(약 10년 전)에는 임베디드 시스템 개발을 하기 위해서는 컴파일러와 디버거를 별도로 구매해야 했었다. 이때 디버거에는 모니터 프로그램을 포팅하기 위한 간단한 라이브러리 및 소스가 제공되었다. 이 소스를 바탕으로 필자의 개발보드에 포팅을 해서 시리얼 포트를 통해 디버거와 연결하여 디버깅을 했었다.
윈도우CE 에서 이러한 기능을 제공하는 부분이 KITL이라고 정의할 수 있다. KITL은 시리얼 포트뿐만 아니라 이더넷, USB등 다양한 통신 방법을 제공한다. 플랫폼 빌더를 이용해서 디버깅을 하기 위해서는 KITL 부분을 먼저 동작되도록 만들어야 한다.
현재는 별도의 하드웨어 추가 없이 고속으로 통신할 수 있는 USB 포트를 통한 디버깅 방법이 주요한 KITL의 통신 포트로 사용된다. 물론 이 역시 프로세서를 공급하는 업체의 BSP가 USB를 통한 KITL을 제공하는가? 아닌가에 달린 문제다. KITL이 정상적으로 동작해야만 플랫폼 빌더에서 제공하는 모든 디버깅 기능을 이용할 수 있기 때문에 KITL에 관련된 작업을 초기에 중점적으로 하는 것은 중요한 일이라고 하겠다. <표1>은 KITL 동작 시 내부적으로 사용되는 주요 함수를 정리한 것이다.
5. 플랫폼 빌더를 통한 디버깅
이제 플랫폼 빌더를 이용하여 윈도우CE 디버깅을 하는 방법에 대해 살펴보도록 하겠다. 디버깅을 위해 준비해야 할 항목들은 다음과 같다. KITL이 정상적으로 동작할 수 있도록 포팅이 되어 있어야 한다.
플랫폼 빌더
시리얼 케이블
KITL 설정에 따른 이더넷 케이블이나 USB 케이블
테스트 할 개발보드
시리얼 터미널 프로그램(하이퍼터미널이나 NetTerm과 같은 프로그램)
윈도우CE에서 디버깅을 하기 해서는 우선 디버깅이 가는 한 운영체제 이미지를 만들어야 한다. 디버깅이 가능한 이미지라는 것은 KITL이 동작 가능한 운영체제 이미지를 말한다. 플랫폼 빌더를 통하여 윈도우CE 운영체제 만들 때는 현재 설정할 수 있는 모드는 디버그 모드와 릴리스 모드 두 가지다. 디버그 모드의 경우 디버깅 가능한 상태이기 때문에 특별히 설정할 필요가 없다. 릴리스 모드의 경우 아래 <그림 1>과 같이 설정하면 KITL을 사용하여 디버깅을 할 수 있다.
단, 릴리스 모드로 디버깅을 하는 경우에는 변수의 자세한 내용이나 값을 볼 수 없는 경우가 있다. 이러한 점을 감안하고 모드를 설정해서 디버깅을 해야 한다. 필자의 경우 보통 USB KITL을 디버깅 통신 방법으로 사용하고 릴리스 모드로 운영체제이미지를 선택하여 디버깅을 한다. 릴리스 모드이기 때문에 동작이 빠르고 이미지의 사이즈가 작다는 장점이 있다.
5. 플랫폼 빌더를 통한 디버깅
이제 플랫폼 빌더를 이용하여 윈도우CE 디버깅을 하는 방법에 대해 살펴보도록 하겠다. 디버깅을 위해 준비해야 할 항목들은 다음과 같다. KITL이 정상적으로 동작할 수 있도록 포팅이 되어 있어야 한다.
플랫폼 빌더
시리얼 케이블
KITL 설정에 따른 이더넷 케이블이나 USB 케이블
테스트 할 개발보드
시리얼 터미널 프로그램(하이퍼터미널이나 NetTerm과 같은 프로그램)
윈도우CE에서 디버깅을 하기 해서는 우선 디버깅이 가는 한 운영체제 이미지를 만들어야 한다. 디버깅이 가능한 이미지라는 것은 KITL이 동작 가능한 운영체제 이미지를 말한다. 플랫폼 빌더를 통하여 윈도우CE 운영체제 만들 때는 현재 설정할 수 있는 모드는 디버그 모드와 릴리스 모드 두 가지다. 디버그 모드의 경우 디버깅 가능한 상태이기 때문에 특별히 설정할 필요가 없다. 릴리스 모드의 경우 아래 <그림 1>과 같이 설정하면 KITL을 사용하여 디버깅을 할 수 있다.
단, 릴리스 모드로 디버깅을 하는 경우에는 변수의 자세한 내용이나 값을 볼 수 없는 경우가 있다. 이러한 점을 감안하고 모드를 설정해서 디버깅을 해야 한다. 필자의 경우 보통 USB KITL을 디버깅 통신 방법으로 사용하고 릴리스 모드로 운영체제이미지를 선택하여 디버깅을 한다. 릴리스 모드이기 때문에 동작이 빠르고 이미지의 사이즈가 작다는 장점이 있다.
그림1 - 윈도우CE 운영체제 생성시 디버깅 관련 설정하는 화면.
디버깅이 가능한 설정으로 운영체제 이미지를 만든 후 운영체제 이미지를 개발보드에서 동작할 수 있도록 개발보드의 플래시 메모리에 기록한다(Flashing). 이것으로써 디버깅을 위한 기본 준비는 다 된 것이다.
개발보드에 전원을 공급하여 동작시키면 보드가 정상 동작하게 되고 KITL 연결을 위한 준비를 하게 된다. 이때 플랫폼 빌더에서 디버깅할 소스부분을 읽어 들인 후 중단점을 설정하게 된다. 그 후 개발보드와 연결하여 [TargetAttach Device] 명령을 통하여 KITL 연결을 시도한다.
KITL 연결이 정상적으로 이루어졌다면 윈도우CE 운영체제의 동작관련 메시지가 출력되면서 디버깅을 위한 준비가 이루어진다. 정상적으로 진행이 된다면 중단점을 설정한 소스에 동작이 멈추면서 디버깅 가능한 상태가 된다. 비로서 윈도우CE 운영체제에서 디버깅을 위한 준비가 끝난 것이다.
디버깅이 가능한 설정으로 운영체제 이미지를 만든 후 운영체제 이미지를 개발보드에서 동작할 수 있도록 개발보드의 플래시 메모리에 기록한다(Flashing). 이것으로써 디버깅을 위한 기본 준비는 다 된 것이다.
개발보드에 전원을 공급하여 동작시키면 보드가 정상 동작하게 되고 KITL 연결을 위한 준비를 하게 된다. 이때 플랫폼 빌더에서 디버깅할 소스부분을 읽어 들인 후 중단점을 설정하게 된다. 그 후 개발보드와 연결하여 [TargetAttach Device] 명령을 통하여 KITL 연결을 시도한다.
KITL 연결이 정상적으로 이루어졌다면 윈도우CE 운영체제의 동작관련 메시지가 출력되면서 디버깅을 위한 준비가 이루어진다. 정상적으로 진행이 된다면 중단점을 설정한 소스에 동작이 멈추면서 디버깅 가능한 상태가 된다. 비로서 윈도우CE 운영체제에서 디버깅을 위한 준비가 끝난 것이다.
그림2 - 하이퍼터미널을 통한 개발보드 메시지 출력.
그림3 - 플랫폼빌더에서 중단점 설정.
그림4 - 개발보드와 플랫폼 빌더와 연결 후 동작 화면.
그림5 - 중단점에 멈춘 화면.
디버거의 사용법은 PC에서 응용프로그램을 디버깅하는 방법과 유사하기 때문에 도움말 파일을 통하여 디버거 사용에 관한 몇 가지 명령만 안다면 쉽게 디버깅을 할 수 있다.
윈도우CE 개발에 있어 디버깅 환경 구축은 중요한 문제다. 개발보드를 구입하고 입수한 BSP가 정상적으로 동작함을 확인하는 것과 동시에 디버깅 환경이 제대로 갖추어졌는지를 확인해야 한다. 현재 출시되는 많은 프로세서들이 윈도우CE를 지원하고 BSP를 제공한다.
하지만 디버깅 환경이 이더넷에 한정된 경우가 많다. 심지어 디버깅 환경으로는 제대로 동작 안 하는 경우도 있다. 이러한 사전 정보를 입수해서 개발은 준비한다면 디버깅 환경 구축을 위해 쓸 때 없이 낭비하는 시간을 줄일 것이다.
6. DEBUGMSG vs RETAILMSG
DEBUGZONE, DEBUGMSG, RETAILMSG 등의 디버깅 메시지 출력 매크로는 윈도우CE 운영체제에서 사용되는 메시지 출력 매크로다. 시리얼 포트를 통하여 하이퍼터미널이나 플랫폼빌더의 디버그메시지 창에 메시지를 출력하기 되어 동작 중에 발생된 문제에 대해 중요한 실마리를 주게 된다.
RETAILMSG의 경우 디버깅 정보가 없는 RETAIL 모드로 윈도우CE 운영체제를 만들었을 때 사용하게 되고, DEBUGMSG 매크로는 DEBUG 모드로 만들었을 때 사용한다. KITL이 제대로 동작하지 않아 플랫폼빌더의 디버깅 기능을 이용하지 못하거나 하드웨어 디버깅 장비가 없을 때는 디버그 메시지 출력을 통해 문제점을 확인한다. 실시간으로 변수의 내용이나 변화를 확인해 볼 수는 없지만 동작 중 생기는 문제를 확인할 수 있다는 장점이 있다.
디버그메시지를 일일이 소스상에 너어야 한다는 점과 문제에 대한 정보를 얻기 위해 윈도우CE 운영체제를 다시 생성해서 플래시에 다시 기록해야 한다는 단점은 있다.
다음 <그림6> 은 윈도우CE 운영체제 디버깅 중 나오는 디버그 메시지를 보여주는 화면이다. 디버그 메시지는 윈도우CE 동작 중 많은 양이 출력되기 때문에 일일이 분석하기가 쉽지는 않다. 또한 이 디버그 메시지를 보면서 문제점을 찾아내는 것도 결코 쉬운 일은 아니다. 문제점에 대한 열쇠를 찾기 위해서는 반복적인 테스트와 분석이 필요한 디버깅 방법이다.
디버거의 사용법은 PC에서 응용프로그램을 디버깅하는 방법과 유사하기 때문에 도움말 파일을 통하여 디버거 사용에 관한 몇 가지 명령만 안다면 쉽게 디버깅을 할 수 있다.
윈도우CE 개발에 있어 디버깅 환경 구축은 중요한 문제다. 개발보드를 구입하고 입수한 BSP가 정상적으로 동작함을 확인하는 것과 동시에 디버깅 환경이 제대로 갖추어졌는지를 확인해야 한다. 현재 출시되는 많은 프로세서들이 윈도우CE를 지원하고 BSP를 제공한다.
하지만 디버깅 환경이 이더넷에 한정된 경우가 많다. 심지어 디버깅 환경으로는 제대로 동작 안 하는 경우도 있다. 이러한 사전 정보를 입수해서 개발은 준비한다면 디버깅 환경 구축을 위해 쓸 때 없이 낭비하는 시간을 줄일 것이다.
6. DEBUGMSG vs RETAILMSG
DEBUGZONE, DEBUGMSG, RETAILMSG 등의 디버깅 메시지 출력 매크로는 윈도우CE 운영체제에서 사용되는 메시지 출력 매크로다. 시리얼 포트를 통하여 하이퍼터미널이나 플랫폼빌더의 디버그메시지 창에 메시지를 출력하기 되어 동작 중에 발생된 문제에 대해 중요한 실마리를 주게 된다.
RETAILMSG의 경우 디버깅 정보가 없는 RETAIL 모드로 윈도우CE 운영체제를 만들었을 때 사용하게 되고, DEBUGMSG 매크로는 DEBUG 모드로 만들었을 때 사용한다. KITL이 제대로 동작하지 않아 플랫폼빌더의 디버깅 기능을 이용하지 못하거나 하드웨어 디버깅 장비가 없을 때는 디버그 메시지 출력을 통해 문제점을 확인한다. 실시간으로 변수의 내용이나 변화를 확인해 볼 수는 없지만 동작 중 생기는 문제를 확인할 수 있다는 장점이 있다.
디버그메시지를 일일이 소스상에 너어야 한다는 점과 문제에 대한 정보를 얻기 위해 윈도우CE 운영체제를 다시 생성해서 플래시에 다시 기록해야 한다는 단점은 있다.
다음 <그림6> 은 윈도우CE 운영체제 디버깅 중 나오는 디버그 메시지를 보여주는 화면이다. 디버그 메시지는 윈도우CE 동작 중 많은 양이 출력되기 때문에 일일이 분석하기가 쉽지는 않다. 또한 이 디버그 메시지를 보면서 문제점을 찾아내는 것도 결코 쉬운 일은 아니다. 문제점에 대한 열쇠를 찾기 위해서는 반복적인 테스트와 분석이 필요한 디버깅 방법이다.
그림6 디버그 메시지 출력 화면.
8. 디버그 존(Debug Zone)
DEBUGZONE은 DEBUG 모드로 운영체제를 만들었을 때 출력되는 메시지를 조절할 수 있는 기능을 제공한다. 즉, 어떠한 메시지를 출력 할 것인가 선택하고 선택적으로 디버그 메시지를 확인하기 위해 사용한다. DEBUG 모드로 운영체제를 만들면 필요이상의 디버그 메시지가 출력되기 때문에 필요한 메시지만 확인하는 의도로 사용된다.
DEBUGMSG 등록 및 사용 아래와 같다. DEBUGZONE을 등록하고, 등록한 DEBUGZONE에 따라 디버그 메시지를 출력할 수 있도록 DEBUGMSG를 사용하는 예이다. DEBUGMSG의 DEBUGZONE 설정은 실시간 디버깅 환경에서 디버깅 메시지 출력을 선택적으로 조절하면서 좀 더 쉽게 디버깅하고자 하기 위해서 사용한다. 다음 <그림 >은 플랫폼빌더에서 디버그존을 선택하는 화면이다.
8. 디버그 존(Debug Zone)
DEBUGZONE은 DEBUG 모드로 운영체제를 만들었을 때 출력되는 메시지를 조절할 수 있는 기능을 제공한다. 즉, 어떠한 메시지를 출력 할 것인가 선택하고 선택적으로 디버그 메시지를 확인하기 위해 사용한다. DEBUG 모드로 운영체제를 만들면 필요이상의 디버그 메시지가 출력되기 때문에 필요한 메시지만 확인하는 의도로 사용된다.
DEBUGMSG 등록 및 사용 아래와 같다. DEBUGZONE을 등록하고, 등록한 DEBUGZONE에 따라 디버그 메시지를 출력할 수 있도록 DEBUGMSG를 사용하는 예이다. DEBUGMSG의 DEBUGZONE 설정은 실시간 디버깅 환경에서 디버깅 메시지 출력을 선택적으로 조절하면서 좀 더 쉽게 디버깅하고자 하기 위해서 사용한다. 다음 <그림 >은 플랫폼빌더에서 디버그존을 선택하는 화면이다.
그림7 디버그존 선택 화면
8. 호출 스택(Call Stack)
윈도우CE 운영체제를 디버깅할 때 가장 어려운 점(사실 응용프로그램을 개발 할 때도 문제가 되는 코드를 찾는 것은 매우 어려운 문제다) 은 어떠한 위치에서 문제가 되는지 확인하기가 어렵다는 것이다. ‘Data Abort’가 발생되거나 특정부분에서 시스템이 멈춘다면 문제점을 찾기가 비교적 쉽지만 일반적인 상황에서는 문제가 되는 정확한 위치를 확인하기가 어렵다는 것이다. 문제가 되는 지점이 다행히 중단점을 설정한 전후 지점이라면 쉽게 디버깅에 성공할 수 있지만 그렇지 않다면 반복적인 확인을 통하여 문제 코드 부분을 찾아야 한다.
이때 사용할 수 있는 기능이 호출 스택(Call Stack)기능이다. 호출 스택은 중단된 위치를 기준으로 호출된 함수의 목록을 표시해 주는 기능이다. 호출 스택을 이용하는 방법은, 윈도우CE 디버깅 시 중단점을 기준으로 호출 스택에 저장되어 있는 함수들을 확인하면서 어떤 부분에서 문제가 생기는지 확인하는 방법이다.
8. 호출 스택(Call Stack)
윈도우CE 운영체제를 디버깅할 때 가장 어려운 점(사실 응용프로그램을 개발 할 때도 문제가 되는 코드를 찾는 것은 매우 어려운 문제다) 은 어떠한 위치에서 문제가 되는지 확인하기가 어렵다는 것이다. ‘Data Abort’가 발생되거나 특정부분에서 시스템이 멈춘다면 문제점을 찾기가 비교적 쉽지만 일반적인 상황에서는 문제가 되는 정확한 위치를 확인하기가 어렵다는 것이다. 문제가 되는 지점이 다행히 중단점을 설정한 전후 지점이라면 쉽게 디버깅에 성공할 수 있지만 그렇지 않다면 반복적인 확인을 통하여 문제 코드 부분을 찾아야 한다.
이때 사용할 수 있는 기능이 호출 스택(Call Stack)기능이다. 호출 스택은 중단된 위치를 기준으로 호출된 함수의 목록을 표시해 주는 기능이다. 호출 스택을 이용하는 방법은, 윈도우CE 디버깅 시 중단점을 기준으로 호출 스택에 저장되어 있는 함수들을 확인하면서 어떤 부분에서 문제가 생기는지 확인하는 방법이다.
9. 중단점(Break Point)
플랫폼 빌더를 이용하여 윈도우CE 운영체제를 개발할 때 편리한 점은 소프트웨어적인 중단점이기 때문에 중단점 설정에 제한이 없다는 것이다. 따라서 필요한 만큼 중단점을 설정해서 디버깅을 할 수 있다.
윈도우CE 운영체제는 읽기/쓰기가 가능한 램(SDRAM이나 DDR-SDRAM, RAM)과 같은 메모리에서 동작하기 때문에 가능한 것이다. 만약 플래시메모리에서 동작하도록 윈도우CE 운영체제를 구성한다면 이러한 디버깅 기능을 사용할 수 없을 것이다. 중단점의 종류에는 아래와 같이 3가지의 종류로 다양하게 설정할 수 있다. 아래 조건을 잘 선택하여 중단점을 설치한다면 빠르게 문제점을 확인할 수 있을 것이다.
위치 중단점 – 특정한 위치에서 동작을 멈추도록 함
조건 중단점 – 특정 변수의 값이 지정한 조건과 일치했을 때 멈추도록 지정함
메시지 중단점 – 특정 함수에서 특정 메시지가 발생했을 때 멈추도록 지정함.
10. JTAG 디버거
“플랫폼 빌더가 있는데 왜 JTAG 디버거가 필요한가?”에 대해 의문을 가질 수도 있을 것이다. 물론 있으면 좋다는 것이다. 혹은 가능하면 있다면 개발 시간을 줄이거나 문제 발생시 좀더 빠르게 접근할 수 있다는 장점이 있다.
플랫폼 빌더로 디버깅하기 힘든 부분이 있다. JTAG 디버거를 이용하는 장점은 다음과 같다. JTAG 디버거를 이용하여 디버깅하는 방법은 내용이 많기 때문에 자세한 내용은 JTAG 디버거 매뉴얼을 참고하기 바란다.
플래시 굽기 – JTAG 디버거를 이용하면 개발보드 내에 장착된 플래시에 JTAG을 이용하여 프로그램 할 수 있다. 따라서 보드상에 장착된 플래시를 프로그래밍을 하기 위해 재 장착할 필요가 없기 때문에 개발 시 용이한 장점을 준다.
EBOOT 디버깅 – EBOOT는 부트로더라고 해서 프로세서가 처음 동작될 때 사용되는 프로그램이다. 따라서 이 프로그램이 초기부터 동작하지 않는다면 KITL을 이용한 플랫폼 빌더 디버깅 방법을 사용할 수 없다. 이런 경우 디버깅 할 수 있는 방법은 시리얼 통신을 사용한 시리얼 디버깅 방법이나 JTAG 디버거를 사용하는 방법밖에 없다. JTAG 디버거는 프로세서가 리셋(reset) 되고 나서부터 초기화하는 과정까지 다 검증할 수 있기 때문에 Eboot를 디버깅하기 위한 최상의 디버깅 방법이다.
전원관련 디버깅 – 전원관리는 임베디드 시스템에서 중요한 요소중의 하나다. 특히 밧데리를 주 전원으로 사용하고 휴대형을 추구하는 장치에서 전원 관리는 제품의 성능을 평가하는 요소 중에 하나다. 플랫폼 빌더로 전원관련 디버깅을 하기에는 어려움이 있다. 전원관리를 하기 위해 개발보드를 서스팬드(Suspend)모드로 진입시키면 플랫폼이 사용하고 있는 KITL 연결 통로도 같이 없어지기 때문에 플랫폼 빌더로 디버깅이 불가능하다. JTAG 디버거는 이러한 단점이 없기 때문에 전원관리 디버깅을 하는데 유리한 장점을 가지고 있다.
하드웨어 디버깅 – JTAG 디버거에는 플랫폼 빌더에 없는 다양한 기능들이 있다. 이 기능들을 이용해 개발 하드웨어 하드웨어 설정이 제대로 되었는지, 메모리나 주변장치들은 제대로 설정이 되었는지 간단히 확인해 볼 수 있다.
11. eXDI(Extended Debugging Interface)
지금까지는 플랫폼 빌더를 통한 디버깅, JTAG 디버거를 이용한 디버깅 방법에 대해 간략히 살펴봤다. 하지만 여기서 의문이 남는다. 플랫폼 빌더에서 JTAG 디버거를 이용하여 디버깅할 수 없는가? 물론 가능하다. eXDI를 통하여 가능하다. eXDI는 외부 디버거 기능을 플랫폼빌더에서 사용할 수 있게 하는 기능이다.
JTAG 디버거 업체에서는 디버거를 제공할 때 윈도우CE용 eXDI 드라이버를 제공하는 업체가 있다. 이 eXDI 드라이버를 설치하여 플랫폼빌더에서 JTAG 디버거를 사용하면 되다.(물론 대부분의 업체가 eXDI 드라이버를 제공하기는 하지만 일부 업체는 아예 제공 안 하는 경우가 있다. 이런 경우에는 플랫폼빌더를 이용해서 디버깅하는 것은 불가능하다.
JTAG 디버거용 디버거 소프트웨어를 사용해서 디버깅해야 한다.) 자세한 내용은 JTAG 디버거에 따라 다르기 때문에 확인이 필요하다. eXDI를 통해 플랫폼 빌더에서 JTAG 디버거의 사용이 가능하다는 점만 알고 사용하기 바란다.
12. 디버그 리스트(Debug list)
임베디드 시스템의 개발은 컴파일과 플래시 기록 작업의 반복이다. 필자가 처음 노트북을 이용해서 윈도우CE 임베디드 시스템을 개발할 당시에는 최종 운영체제 이미지가 만들어지기까지 40분의 시간이 걸렸다.
이 운영체제 이미지를 JTAG 포트(아쉽게도 그 당시에는 JTAG디버거가 없었다. 단지 JTAG 포트를 통해 개발보드에 있는 플래시를 기록할 수 있는 장치만 있었다.)를 통하여 약 50분 동안 플래시에 기록한 후 동작을 시키면서 테스트를 진행했었다. 이런 식으로 플랫폼 빌더를 사용해 디버깅을 한다면 한 문제를 디버깅하기도 벅찰 것이다. 다행이 플랫폼 빌더에는 이러한 시간적인 낭비를 줄이고자 디버그 리스트 기능이 있다.
디버그 리스트 기능은 디바이스 드라이버나 응용프로그램을 디버그 리스트에 등록해 놓으면 해당 모듈만 컴파일 및 빌드하고 변경된 소스를 디버깅 할 수 있는 기능이다. 즉, 디바이스 드라이버를 수정하고 운영체제를 다시 만들어 디버깅을 하는 것이 아니라, 디버그 리스트에 등록을 하고 플랫폼 빌더 디버깅을 시작하면 새로 변경된 디바이스 드라이버 소스 코드와 바이너리로 디버깅을 할 수 있는 기능이다. 이 기능을 사용하면 윈도우CE 운영체제를 다시 만들고 플래시 메모리에 기록하는 시간을 단축할 수 있기 때문에 디버깅을 효율적으로 할 수 있게 해준다.
끝으로
윈도우CE 운영체제 개발에 관하여 중요한 12가지 사항에 대해 확인해 봤다. 이 밖에도 디버깅을 위해 알아야 할 것들은 많이 있을 것이다. 하지만 가장 중요한 것은 개발하는 시스템에 대해 잘 아는 것이라고 하겠다. 윈도우CE 운영체제가 어떻게 동작 할 것인가?에 대해 항상 의문을 가지고 있다면 디버깅 하는데 많은 도움이 될 것이다.
새로운 코드를 만드는 것만큼 디버깅하는 것은 어려운 일이다. 개발초기에 코드에 대한 스스로의 검증을 통해 더 복잡한 문제가 발생하지 않도록 하는 태도를 지녀야 할 것이다. 디버깅보다 중요한 것이 좋은 코드를 먼저 작성하는 것이라는 것을 명심하길 바란다. @