부트로더 제작 8편. startup (II) LED의 활용례 - 2009/02/10 23:13
지난시간에 부트로더의 relocation(재배치) 기능을 소개하였다.
이번 시간에는 프로그래머라면 한번쯤은 궁금하게 생각하였던 부분을 건들여 보는 것으로 금번의 강좌를 시작해 보겠다.
바로 프로그래밍 모델이라고 부르는 것이다.
설명을 위해 간단한 'c' 코딩을 즉석에서 해보자.
1 int glvar1 = 0; // '0'으로 초기화
2 int glvar2; // 초기화 하지 않음
3
4 int main(void)
5 {
6 int i; // 지역변수(자동변수)
7 char* pIMG;
8
9 glvar2 = 70;
10 pIMG = malloc(1024); // using heap memory
11 중략...
12
전역변수와 지역변수
코드라인 1과 2의 변수를 우리는 뭐라고 부르는가? 전역변수 맞다. 영어로는 'global variables' 라고도 부른다.
이에 반해 코드라인 6의 변수를 우리는 지역변수 혹은 자동변수라고 불러서 이는 통상 CPU의 레지스터 혹은 스택에 그 영역이 확보되고 사용된다. 지역변수는 또한 필요할 경우 생성되었다가 소멸되는 특징을 가지고 있다.
초기화 된 변수와 초기화 되지 않은 변수
둘다 전역변수인 코드라인 1과 2의 차이점이 보이는가? 코드라인1의 glvar1 은 프로그래머가 의도적으로 0으로 초기화 한 반면 glvar2 는 현재 초기화 되어 있지 않다.
그렇다면 glvar2 에는 어떤 값이 들어가 있을까? 쓰레기값이 들어가 있을까? 마이크로프로세서 내장 임베디드 시스템의 거의 모든것들은 이에 대한 처리로서 이렇게 프로그래머가 의도적이든 의도적이 아니든 초기화 하지 않은 모든 변수들을 일괄적으로 'zero out(clear)' 시키는 기능이 들어가 있다. 보통 부트스타트업 코드에 이러한 기능을 하는 코드를 넣어둔다.
( 만약에 여러분이 사용하는 임베디드 시스템 'start.s' 코드내에 이러한 기능을 하는 코드가 없다면 아마도 이의 처리를 컴파일러가 직접하는 경우다. 이 설명까지 하게 되면 강좌가 너무 복잡하게 전개되기 때문에 본 강좌에서는 생략한다. )
결론적으로 코드라인 1과 2 모두 0으로 초기화 된다고 할 수 있다.
임베디드 시스템에서는 glvar1 처럼 초기화된 변수 영역을 지칭하여 .data 혹은 RW 영역이라고 칭한다.
한편, glvar2 처럼 초기화 하지 않은 변수 영역을 BSS 영역이라고 부른다.
전시간 강좌 부트로더 제작 6편의 '그림2. start.S 소스코드' 을 참고 하기 바란다. 'AE' 섹터를 보면 바로 이 영역(BSS)의 처리를 하고 있음을 확인 할수 있다.
다음과 같이 정리해 보도록 한다. 부트스타업 코드의 역할중 하나는 바로 '프로그래머 메모리 초기화' 인것이다.
임베디드 시스템에서의 malloc
우리는 보통 동적 메모리 할당(Dynamic Memory Allocation)을 할때 new() 나 malloc() 함수를 이용하곤 한다.
그리고 이렇게 사용자가 요청한 메모리는 소위 힙메모리(HEAP)라는 곳에서 할당 받게된다.
이의 처리는 실제로는 메모리관리자라고 부르는 코드(소프트웨어)가 담당한다. 이 코드는 우리가 사용하는 컴파일러내의 라이브러리에 들어 있다.
그렇다면 임베디드 시스템에서 HEAP 메모리는 어떻게 초기화 시켜야 하는가? 아니 어떻게 사용할 수 있는가.
그림2. start.S 소스코드 내 'AD'섹터 와 그림3. blob 의 프로그램 메모리(SDRAM상) 구조도를 함께 보면 좋겠다.
첫째, 다른 프로그램들에 의해서 방해받지 않는 별도의 메모리 영역을 확보한다. 둘째, 컴파일러에게 HEAP 메모리의 존재 유무와 그 위치를 알려주어야 한다. 통상 링커환경파일(blob의 예로는 'ld-script')에 그 내용을 기재해 주도록 되어 있는 경우가 많다. 현재 우리가 사용하는 'blob' 에는 아쉽게도 그 한가지 처리가 들어가 있지 않다. 따라서 HEAP 을 사용하는 malloc 류의 함수는 사용 할 수 없다고 말 할 수 있겠다.
이상과 같이 '프로그래머 메모리 모델'을 간단히 살펴 보았다. 비록 추가적으로 언급하지는 않았지만 메모리 모델에는 몇가지 테마가 사실상 더 있다. 임베디드시스템에서의 const 변수의 의미라든가 volatile, static 변수의 의미, 초기화된 배열및 스트링데이타 등이 있겠다.
이후에 시간이 허락하면 '프로그래머 메모리 모델'을 한번 정리해 보겠다.
임베디드시스템의 디버깅 방법론 하나! LED
이번 시간에는 누구나 알고 있슴직한 LED(light emitted diode) 라고 부르는 발광다이오드에 대한 이야기를 해보도록 한다.
전자공학을 전공하지 않은 이라도 누구나 잘 알고있는 즉, 전기가 통하면 불이 들어오고 반대로 하면 불이 꺼지는 바로 그 부품이다.
버스타고 도심을 가로지르면 상점들 간판이나 윈도우에 장식한 전광판들이 요즘 눈에 많이 들어온다.
우리가 지금부터 살펴 볼것은 이의 다른 특별한 사용례 정도가 될 것이다.
UART 장치는 통상 콘솔(CONSOLE) 이라고도 불리워서 임베디드 소프트웨어 디버깅시에 즐겨쓰는 도구이다. 프로그래머가 원하는 문자열을 화면에 디스플레이 하게끔 해서 내가 실행한 코드가 정확히 수행되었는지. 실행시 중단되지는 않았는지를 확인하기 위하여 사용되는 필시 좋은 도구임이 틀림없다.
하지만, 이러한 도구를 이용하기 위하여는 적절한 초기화가 필요하다. 이후의 강좌에서 다룰것인데. main() 루틴에 와서야 UART 장치의 초기화가 이루어 짐으로 인해 불행히도 우리가 'start.s' 라는 코드를 디버깅 할때는 사용할 수가 없다. 이쯤와서 눈치 빠른 분들은 필자가 무슨 이야기를 하려는지 짐작 하실 것이다.
바로 main() 루틴이 실행되기전의 절대적인 디버깅 도구로서의 LED 역할을 지금부터 설명하려는 것이다.
'start.s' 소스중 'AF' 섹터의 184라인을 보면 두개(각각 녹색/적색)의 LED를 모두 끄는 함수(clr_lightled)가 실행되고 있다. 또한, 'main.c' 소스중 7라인을 보면 두개의 LED 켜는 함수(set_lightled)가 실행되고 있다.
위의 프로그램을 실행 시켜 보아 만약 LED가 하나만 켜져 있거나 모두 꺼져 있다면 시스템은 어떤 상태임을 의미하는가? 알지 못하는 어떤 문제가 발생하여 main() 함수를 진입하지 못하였음을 알 수 있고 LED 켜고 끄는 함수를 적절히 위치를 바꾸어 가며 실행해 본다면 어떤 함수를 실행중에 시스템 critical failure 가 발생하였는지를 확인 할 수 있다.
LED는 필경 단순한 장치임에 틀림없으나 이렇게 사용하기에 따라서 우리에게 간단한 설정만으로 꼭 필요한 기능을 잘 수행해 주도록 임무를 부여 할 수도 있다.
이후의 프로그램 그리고 강좌에서는 이 LED가 적극적으로 활용된다.
NEXT. . . 다음 시간에
posted by 가일(GUILE)
♡ 포스팅이 유익 하셨다면 E-mail로 가일의 임베디드 스쿨을 구독하세요-> 




