'==가일의테크노트=='에 해당되는 글 20건
- 버스는 인체의 혈관과 같은것? (2) | 2009/02/14
- 플래시 메모리가 지워진다구? | 2009/02/09
- 임베디드에서 자주 사용되는 연산 (1) | 2009/02/09
- 임베디드 시스템 디버깅의 전략-ISP | 2009/02/09
- C Programming FAQs | 2009/02/09
- 나의 마이크로 프로세서 이야기 | 2009/02/09
- 임베디드 시스템 개발시 유용한 비트계산기(BITANALYZER) (3) | 2009/02/09
- memory mapped I/O 란 무엇인가? | 2009/02/09
- 라이브러리안 사용해 보기(리버스 엔지니어링 1편) | 2009/02/09
- 추억의 80-90년대 임베디드 시스템 개발 (1) | 2009/02/09
버스는 인체의 혈관과 같은것? - 2009/02/14 17:36
플래시 메모리가 지워진다구? - 2009/02/09 17:05
그림1의 플래시 메모리 인터페이스 는 임베디드 시스템 설계시 흔히 보는 일반적인 플래시 메모리의 인터페이스를 보이고 있습니다.
이 시간에는 올바른 플래시 메모리의 디지탈 회로 구성법에 대하여 알아보고 의도되지 않은 플래시 메모리의 지워짐 현상 발생에 대한 대책과 그 예방법을 함께 생각해 보도록 합니다.
[그림1] 플래시 메모리 인터페이스
문제의 발단과 그 증상
플래시 메모리 내용의 일부가 깨진다?. 플래시 메모리의 내용이 훼손된 시료들이 시스템의 일부에서 목격되었다. 이에 대하여 긴급 조사를 실시한 결과 회로, 소프트웨어 등. 설계상의 뚜렷한 오류는 없는 것으로 1차 진단 하였다. 이에 공정상의 오류 가능성을 위해 2차 진단 태스크 포스팀 구성을 진행중에 있다. 회로는 필드에서 흔히 사용되는 플래시 회로 인터페이스를 카피(copy)하여 사용하였고, 또한 플래시는 write 모드에서만 기록이 된다는 점 때문에 소프트웨어 문제일 가능성은 더 더욱 아닌것으로 추측 되었다. 중략 . . .
위의 내용은 가상의 시나리오를 하나 구성 해 본 것입니다.
인터넷 모 사이트에 올라온 플래시 지워짐 현상에 대한 문의 글을 보고 문득 생각이 나서 이렇게 한 자 적어 봅니다.
예상되는 원인(인자)들
플래시는 Vpp(12V 혹은 Vcc), WE#, CE#, WP#, 쓰기 모드 커맨드등의 여러가지 구비 요소가 모두 충족이 되어야 기록(writing)이 된다는 특징 때문에 시스템 설계자는 '그림1.플래시 메모리 인터페이스' 처럼의 회로 구성을 갖춘것 만으로 잠시 안심하기 쉽습니다.
하지만, 실상을 들여다 보면 이내 그 헛점들이 드러나게 됩니다.
(1)Vpp 에 대해서
블럭 지우기(BLOCK ERASE) 플래시가 등장한 이후부터는 플래시의 Vcc 전원을 Vpp 전원으로도 사용 할 수 있게 되었습니다. 12V의 별도 전원이 필요 없슴으로 그만큼 편해 진 것은 사실입니다. Vpp 전원이 공급되지 않으면 플래시로의 어떤 쓰기(writing) 시도도 무력 할 수 밖에 없습니다. 뒤집어서 이야기 해 본다면 Vpp 전원은 필요 할때만 공급 하도록 디지탈 회로를 설계 한다면 훌륭한 플래시 protection 대책이 됩니다. 이 이유는 후술 합니다.
(2)WE#, CE#, WP# 에 대해서
이 신호들이 플래시 기록시에 함께 액티브 되지 않으면 플래시에 쓰기가 성공할 수 없다는 점에서는 Vpp 와 그 맥락을 같이 합니다만, 유감스럽게도 이 신호들은 시스템의 POWER-UP, POWER-DOWN 순간에는 잠시나마 예측 할 수 없는 un-stable 한 상태에 놓여 있다는 것이 바로 우리가 생각해 봐야 할 첫번째 인자가 됩니다.
(3)쓰기 모드 커맨드 에 대해서
플래시는 기록을 위하여는 별도의 쓰기 모드 커맨드를 실행하여 해당 모드로 변경 후 쓰기가 가능해 집니다. 이것도 물론 정상적인 사용시에는 전혀 문제가 될 것이 없습니다. 하지만, 시스템의 POWER-UP, POWER-DOWN 에는 이 또한 이야기는 전혀 달라 집니다. 시스템의 전원이 안정화 되어 내부 디지탈 회로들이 steady 한 상태로 넘어갈때 까지 tri-state 신호의 특성을 가진 어드레스 / 데이터 버스 또한 위의 WE#, CE#, WP# 처럼 플래시가 이를 어떻게 받아들일지 알 수 없습니다. 데이터 버스상의 의도 되지 않은 값을 쓰기 모드 커맨드(0x40)로 플래시가 오해 하기란 확률적으로도 그리 어려운 일이 아닙니다.
고작 1바이트 즉, 256 경우의 수밖에는 되지 않기 때문이죠.
자, 그러면 문제는 이렇게 정리가 되겠네요. 위의 인자중 (2), (3)은 믿을 수 없슴.
이제 남은 (1)번은 과연 믿을 만 한 것인가 보도록 합니다. Vpp은 통상 [그림1] 에 보시는 것처럼 많은 플래시 응용 회로들은 Vpp 전원을 'Always' 공급하고 있도록 처리하고 있습니다. 시스템의 POWER-UP 시에 Vpp 전압은 Vcc 가 안정화 상태에 돌입하기 전에 이미 플래시 쓰기가 가능한 전압인 VppL에 도달 할 수가 있습니다.
만약, 이것이 가능해 진다면 어떻게 될까요?. 시스템의 POWER-UP 시에는 (1), (2), (3) 항목의 모든 조건이 만족이 되어 얼마든지 플래시에 잘못된 쓰레기 값들이 채워 질 수 있게 되는 것입니다.
대책과 그 예방
(1)Vpp 전원은 필요시에만 공급한다.
: 가장 중요하며 확실한 대책이 됩니다.
(2)시스템 리셋(RP#) 단자를 POWER-GOOD 리셋으로 처리한다.
: 시스템의 전원이 안정화 된 이후에 시스템 리셋이 풀리도록(해제 되도록) 처리합니다.
[그림2] 시스템 파워 온/오프시 리셋 회로
(3)플래시 전용 쓰기 신호(WE#)을 이용한다(그림3.WE# Gating 참고)
: 마이크로 프로세서의 WR# 신호를 플래시에 직접 입력 시키지 않고 GPIO 을 이용하여 안전하게 처리하여 플래시에 입력되도록 조치합니다.
[그림3] WE# Gating
[그림4] WE# Gating 을 적용한 회로 구성 도면
FAQ
Q. 플래시 지워지는 현상이 발생했는데 어떻게 조치하면 좋을까요?
A. 플래시 지워지는 유형은 크게 시스템의 런타임 동작중 발생 가능성(유형1)과 전원의 켜고 꺼질때 지워지는 가능성(유형2)으로 나누어 볼 수 있으며 이에 대한 대책은 각기 구별되어야 겠습니다. 유형1에 대한 원인을 파악코저 다음과 같은 검사를 우선 해 보시기를 권합니다.
동작중 플래시가 지워졌고 이의 재현이 가능하다면 위에서 이미 언급한 바 있던 플래시의 WE# Gating 조치를 취한후 시스템의 개선 여부를 확인 해 보세요.
만약 이 조치만으로 문제가 해결된 것처럼 보인다면 아마도 현재 작업 중이신 시스템의 플래시 칩셀렉트(인에이블) 조건이 다른 I/O장치와 충돌이 생기고 있지는 않은지 확인해 보십시오. 한편, 계측기를 이용하여 의도되지 않은 플래시의 칩셀렉트 신호가 발생하는 일은 없는지도 조사 하여야 할 것입니다.
다음은 유형2에 대한 조치입니다.
증상으로 보아 현재의 문제가 유형2에 해당 된다고 판단 되신다면 다음의 검사를 실시하는 것을 우선적으로 행 하시길 권합니다.
계측기를 이용하셔서 플래시 메모리의 주요 신호인 Vpp, WE#, CE#, WP#, RP# 을 프로빙(probe) 하신 후 전원의 켜고 꺼짐 동작시 이를 면밀히 주시 하시기 바랍니다. 이를 이용하여 정확한 원인을 찾아 낼 수만 있다면 가장 효과적인 대책이 나올 수 있겠지만 상황이 그렇지 못할 경우에는 단계별 개선책을 시도하여 이의 효과를 확인하는 방법으로 진행 하는것이 좋겠습니다. 아래의 조치를 단계적으로 혹은 동시 처방하여 그 개선 여부를 확인하여 보십시오.
(1)Vpp 전원은 필요시에만 공급한다.
(2)시스템 리셋(RP#) 단자를 POWER-GOOD 리셋으로 처리한다
Q. 바람직한 플래시 메모리 회로 설계 ABC는?
A. Vpp 전원을 필요시에만 인가 할 수 있도록 하는것이 가장 안전하면서도 또한 중요 합니다. 만약 이것이 여의치 않을 경우 시스템 리셋(RP#) 단자를 POWER-GOOD 리셋으로 처리한 후 이의 신뢰도(개선여부)를 꼭 확인 하여 보시길 권합니다. 마지막으로 플래시 메모리는 통상 임베디드 시스템의 내장 소프트웨어가 존재하는 곳이므로 중요하고도 또한 안전하게 처리 해야 함을 항시 잊지 않는 다면 비극적인 사태(catastrophe)는 발생하지 않을 것입니다.
posted by 가일(GUILE)
♡ 포스팅이 유익 하셨다면 E-mail로 가일의 임베디드 스쿨을 구독하세요-> 
임베디드에서 자주 사용되는 연산 - 2009/02/09 17:03
제목처럼 임베디드에서 자주 사용되는 비트 연산자들을 정리해 봅니다.
이외에도 ~, ^ 등의 연산자들이 있겠으나 금번 칼럼에서는 <<, >> 연산자 , &= [~], |= 연산자 이처럼 딱 몇 개만 다룹니다.
<< , >> 쉬프터
<<, >> 연산자는 비트 조작을 수행하며 크게 2가지 방법으로 대개 사용됩니다. 로케이터와 곱하기/나누기가 그것입니다.
▶로케이터
비트의 위치 선정
예1) rGPECON = (0x1<<3);
예2) rGPECON >>= 16; // select upper byte 16
해설: 예제에서도 알 수 있다시피 어떤 값(비트)를 비트 이동 시키는 기능입니다. (예1)에서는 레지스터(rGPECON)의 특정 비트를 '1'로 만드는 일을 수행하고 있습니다. 다음으로 (예2)에서는 32비트 레지스터인 rGPECON 의 상위 16비트만을 취하는 방법으로 해당 연산자가 사용되고 있어 (예1)과 (예2)는 그 사용 용도가 약간의 차이가 있음을 또한 알 수 있습니다.
▶곱하기/나누기
정수배의 산술 곱하기/나눗셈
예1) SUM <<= 2; // multiply by '4'
예2) SUM = value >> 1; // divide by '2'
해설: 이번 (예1)에서는 SUM 이라는 변수를 해당 연산자('<<') 을 사용하여 자리 이동 시킴으로써 실제로 곱하기 효과( 2^2 ; 2의 2승 )를 일으키고 있습니다.
한편, (예2)에서는 연산자('>>') 을 사용하여 반대로 나눗셈 효과( 2로 나눈 결과 )가 일어 나게 됩니다.
'&= '와 '|= ' 마스커
이제부터 살펴 볼 연산자들은 특정 비트를 '0' 으로 만들기도 하고 '1'으로 만들기도 하는 기능들을 수행 합니다.
▶&= [~]
선택된 비트 패턴 '클리어(zero fill 마스킹)'
예1) rGPECON &= ~((0x3<<22) | (0x3<<24));
예2) rGPECON &= 0xFFFF0000;
해설: (예1)에서는 22번, 23번 비트를 무조건 '0'으로 만들고 24번, 25 비트를 무조건 '0'으로 만드는 일을 수행합니다. (예2)는 0번 비트부터 15번 비트까지를 모두 '0'으로 만드는 일을 수행합니다. (예1)과 (예2)는 둘다 특정 비트들을 '0'으로 만드는 일을 수행하나 (예1)은 ~ 연산자가 같이 사용된다는 점이 차이점이겠습니다. (예1)과 (예2) 모두 즐겨 반복적으로 사용되는 유형이므로 이에 아직 익숙치 않은 분들은 아예 유형 자체를 암기를 해도 좋을듯 싶군요.
▶|=
선택된 비트 패턴 '세트(기록)'
예1) rGPEDAT |= (0x1<<11) | (0x1<<12);
예2) rGPEDAT |= 0x00ff0000; ('1' fill 마스킹)
해설: &= [~] 연산이 특정 비트를 '0'으로 만드는 것이었다면 이번에 설명할 연산자는 이와 반대로 특정 비트를 무조건 '1'로 만드는 일을 수행합니다. 자, 예를 보도록 하죠. (예1)에서는 11번, 12번 비트를 무조건 '1'으로 만듭니다. (예2)는 16번 비트부터 23번 비트까지를 모두 '1'으로 만드는 일을 수행합니다.
Posted by 가일[GUILE]
♡ 포스팅이 유익 하셨다면 E-mail로 가일의 임베디드 스쿨을 구독하세요-> 
임베디드 시스템 디버깅의 전략-ISP - 2009/02/09 17:02
여러가지 임베디드 시스템 디버깅 메소드중 다른 방법과 비교. 특히 ISP(In System Programming)의 장점을 부각시켜서 설명하고 있는 글이다.
C Programming FAQs - 2009/02/09 16:59
나의 마이크로 프로세서 이야기 - 2009/02/09 16:58
필자의 이야기를 해 보려고 한다.
1994년 겨울에 당시 8비트 컨트롤러였던 모토롤라의 M68HC11 을 가지고 씨름 했었더랬다.
키패드를 붙이고 GPIO을 이용하여 9개의 키를 입력 받는 소프트웨어를 작성하였다. 디버깅까지 마치고 나니 다음 일정 스케쥴은 리모컨을 붙여다 한단다(붙인다는 표현 많이 쓰죠? 그쵸? ^^). 리모컨 수광부 에 마이크로 컨트롤러의 INPUT CAPTURE(PWM 타이머)을 인터페이스 했다. 그리고 항상 그렇듯이 코딩, 디버깅, ㅠㅠ
전번 과제에서는 어셈블리로 진행 했었지만, 이번 과제에서는 대부분을 C/C++ 을 사용 하기로 마음 먹었다. 또한, UI 관련된 부분은 C++의 클래스(CLASS) 라는 놈을 한번 적용 해 보면 좋겠다는 생각도 했다. '앞으로는 PCI 버스도 임베디드에서 사용되니까 미리 공부 해 둬야 한다'는 얘기도 왕왕 들려 오던 때이다.
지금은 UM강좌에서 나의 경험을 바탕으로 강의도 하고 있지만 내가 마이크로프로세서를 이용해 시스템을 개발하면서 가장 많은 시간을 할애 했었고 또한 어려워 했던 것은 BUS에 대한 이해로 기억 한다.
개발에 착수한지 1년이 지난 후엔 M68340 데이터북은 하도 많이 봐서 이미 너덜 너덜 해져 있었다.
하지만, 현업에서 개발일을 1년 남짓 해왔고, 프로젝트도 이번까지 하면 이미 2번째인데 다른 거는 대충 다 이해가 가고 소프트웨어 구현도 직접 할 정도로 문제가 안되는데( 그로부터 10년이 지난 지금에도 당시에 접했던 기술들인 TIMER, DMA, PWM, I2C, SPI, UART 장치들은 지금도 많이 사용 되고 있다 ) 유독 이 분야 즉, 버스 인터페이스 만큼은 잡힐듯 잡힐듯 하면서도 부족한 항상 2% 정도의 아쉬움이 남아 있었다. 이것은 항상 나의 뒷덜미를 간지럽혔다. 아직도 완전하게 이해 하고 있질 못하고 있는 것 같다는 즉, 불안함이었다.
어느덧 프로젝트가 1년여에 걸쳐 개발이 종료 되고 난 후에 1997년도에 다시 동일한 프로세서(M68340)를 이용하여 새로운 프로젝트를 하나 더 할 기회가 생겼다. 이전에 보던 데이터북은 너무 더러워져서 업체에게 부탁하여 새로 한 권을 선물 받았다. 당시 웬지 좋은 선물을 받았을 때의 어린아이처럼 기뻐 했었던 것 같다.
다시금 이 책은 나의 손 때를 타기 시작하였다. (지금도 소지 하고 있다. ^^;)
놀랍게도 이 두번째의 프로젝트를 하면서 우연히 나도 모르는 사이에 부족한 2% 가 마저 채워지게 된다.
마이크로 프로세서에서 버스의 이해는 내가 가장 강조하는 (1)버스, (2)CPU, (3)인터럽트 3대 주제 중에서도 첫 손에 꼽는다. 디지탈 하드웨어 엔지니어는 말 할 것도 없고 펌웨어 엔지니어도 당연히 이에 대해서 완벽하게 알고 있어야만 한다.
왜 중요하냐구?. 디지탈 하드웨어를 설계(1) 할 수 있고, 소프트웨어외의 하드웨어 버그의 원인을 찾아(2) 낼 수 있을려면이라구 정의 하고 싶다.
펌웨어는 PC 소프트웨어와 분명한 차이가 있다는 것을 생각 해야 한다. 내가 작성 한 코드에 문제가 없어도 시스템 동작에 오류가 발생 할 수 있다. 이를 찾아내고(해결하고) 못 찾아내고는(해결하고는) 바로 이 2%에 좌우될 수도 있다.
-홍익컴닷컴-
http://www.hongikcom.com
♡ 포스팅이 유익 하셨다면 E-mail로 가일의 임베디드 스쿨을 구독하세요->

임베디드 시스템 개발시 유용한 비트계산기(BITANALYZER) - 2009/02/09 16:56
임베디드 시스템 개발시 우리는 다음과 같은 계산을 할 때가 왕왕 있다.
어드레스 16진수 계산, 오프셋을 더하고 빼는일, 특정값을 마스킹 하는 경우, 반전(1's complement),
특정 수 만큼 자리이동(쉬프트) 것들이 그 예이다.
MS윈도우 내장 공학용 계산기로는 할 수 없는 바로 이런 모든 기능을 가진 계산기를 하나 소개 한다.
'BIT분석기' 예전 나의 동료 김홍준씨의 작품이다.
예전 가일랜드(www.guile.pe.kr) 자료실에서 내가 소개 하였던 바로 그 프로그램이다.
[그림]BIT분석기의 모습
다음은 프로그램 창의 주요 기능 설명입니다.
(1)해당 비트에 마우스를 가져다가 클릭해 보세요. 값이 변화를 보일 것입니다.
(2)직접 값을 입력하고 싶을 때는 HEX 창이나 DEC창에 값을 입력 한 이후 TEST 버튼을 눌러보세요.
(3)해당 값의 반전(NOT) 을 취하고 싶을 경우 해당 버튼을 누르세요
(4)해당 값을 원하는 수만큼 쉬프트 시키고 싶을 경우 쉬프트 할 비트수를 입력하고 좌/우 화살표(<<, >>)을 눌러 보세요.
(5)두개의 이진값을 &(AND), |(OR), ^(XOR) 합니다.
(6)To Result 버튼은 연산의 결과를 (1)번의 비트표시창으로 연동시켜 줍니다. 눌러보세요. 1번 윈도우의 비트값이 변화를 보일 것입니다.
(7)어드레스 베이스 값에 원하는 오프셋값을 더하고 빼는 것을 도와 줍니다.
(8)연산의 바로 직전 값을 확인 할 수 있도록 해 줍니다.
(9)Mapping Bits 버튼은 비트 값을 파일로 만들어서 INPUT 시킬 수 있는 기능 인데 사용법을 모르겠습니다.
다운로드를 원하시는 분은 본문 우측 상단의 파일첨부를 확인하세요.
memory mapped I/O 란 무엇인가? - 2009/02/09 16:53
memory mapped I/O 란 무엇인가?
임베디드시스템 에서 소프트웨어라 함은 마이크로프로세서가 주체가 되어 실행하는 일련의 프로그램(PROGRAM)을 말한다.
즉, memory mapped I/O 와 non-memory mapped I/O 의 형태라 할 수 있다.
memory mapped 장치의 대표적인 것은 메모리류(FLASH,RAM,SDRAM)와 LCD DRIVER IC, Ethernet controller, USB controller 등
마이크로 프로세서의 제어를 받는 다양한 종류의 컨트롤러 들이다.
그러면, non-memory mapped 장치는 어떤 것들이 있을까? I2C 인터페이스를 가진 모든 디바이스(video encoder, tuner, eeprom, etc), SPI 인터페이스 장치, GPIO 인터페이스 장치. 기타 등등.
당장 생각나는 것은 모두 적은 것 같은데, 찾아보면 아마도 또 있을것이다.
이제 두 가지 형태가 있다는 것은 알았는데 그럼 각각은 어떻게 구분 되는가?
memory mapped 형태의 특징을 설명하면 자동적으로 non-memory mapped 설명이 될 것이므로 이제 설명을 해 보겠다.
memory mapped 형태는 두 가지 분명한 외관 상의 특징을 갖는다.
첫번째 특징은 칩셀렉트 신호인 /CS(혹은 /CE), 와 어드레스인 ADDR 을 가진다.
두번째 특징은 어드레스가 앞서의 설명과 같이 존재 하므로 해당 장치는 MEMORY MAP 에 그 영역을 할당 받는다(할당한다).
소프트웨어 개발을 한다는 것은 위의 두가지 형태의 장치 리소스 들을 가지고 상상한 무형의 것을 만들어 내는 것이 될 것이다.
참고로, 과거 인텔의 i80xx 계열에서는 memory map 와 또한 대비되는 용어인 I/O map 을 함께 사용 하였었다.
지금도 하이엔드 프로세서에서 그 명맥이 유지되어 사용 되고 있는지는 모르겠다.
-홍익컴닷컴-
http://www.hongikcom.com
♡ 포스팅이 유익 하셨다면 E-mail로 가일의 임베디드 스쿨을 구독하세요->

라이브러리안 사용해 보기(리버스 엔지니어링 1편) - 2009/02/09 16:52
개발 환경 중 컴파일러라고 하면 우리는 흔히 어셈블러(ASSEMBLER), C/C++ 컴파일러(COMPILER), 링커(LINKER)를 떠 올리고 나서 마지막으로 컴파일러에 포함되는 것은 아니지만 디버거(DEBUGGER)도 있다고 얘기 하곤 한다. 디버거가 상용제품 들에는 대개 기본적으로 따라오는 것이기 때문인 듯 하다.
어쨋든 우리가 잘 사용하는 것은 아니지만 위에 열거에는 한가지가 빠져있는데 필자가 금번에 얘기 해 보려는 주제인 라이브러리안(LIBRARIAN) 이라고 하는 놈이다. 개발자들은 맞아 이런 것도 있었지 하면서 손뼉을 칠 바로 그 놈이다.
자세한 내용은 해당 매뉴얼을 참조하길 바라며 여기서는 armar 의 간단한 사용법과 주요 기능을 우선 설명하겠다.
쉘프롬프트상에서 armar[ENTER]이라고 입력 해보자. 그러면 다음과 같은 사용법을 설명하는 HELP가 표시된다.
ARM Archiver, ADS1.2 [Build 805] - archive creation and maintenance tool Command format: armar options archive [ file_list ] Wildcards '?' and '*' may be used in file_list Options:- -r Insert files in <file_list>, replace existing members of the same name. -d Delete the members in <file_list>. -x Extract members in <file_list> placing in files of the same name. -m Move files in <file_list>. -p Print files to stdout. -a pos Insert/move files after file named <pos>. -b pos Insert/move files before file named <pos>. -u Update older files only, used with -r. -n Do not add a symbol table to an object archive. -s Force regeneration of archive symbol table. -t Print table of contents of archive. -zs Show the symbol table. -zt Summarize the archive contents (sizes + entries). -c Suppress warning when a new archive is created. -C Do not overwrite existing files when extracting. -T Truncate file names to system maximum length. -v Give verbose output. -create Force creation of a new archive. -via file Take additional arguments from via file. -sizes List the size of each member and the library total. -entries List sections containing ENTRY points. -vsn Print the current Armar Version. -help Print this message. Examples:- |
armar 에는 여러가지 기능이 있지만 오브젝트 모듈(.o 혹은 .obj)을 합쳐서 라이브러리를 만들어주고, 특정 모듈을 추가, 삭제, 추출, 리스트하는(보여주는) 것이 핵심 기능이 되겠다.
여기에다 특정 모듈에서 사용된 함수 리스트(정확하게는 심볼테이블)를 보여주는 기능도 있는데.
이 기능이 금번 시간에 필자가 설명 하려는 것과 밀접한 관련이 있다.
앞으로 몇가지 시도를 해보겠다.
먼저, 표준라이브러리에는 어떤 것들이 들어 있는지 한번 보도록 하자.
ADS 툴의 경우에 라이브러리는 다음의 경로에 위치해 있다.
C:\Program Files\ARM\ADSv1_2\Lib\armlib>
ARM라이브러리는 c_a__se.l 등으로 표시되어 파일명에 'a'가 포함되어 있으며 THUMB라이브러리는 c_t__se.l 로서 't'로 표기되어 있는 것을 볼 수 있다.
쉘프롬프트상에 다음과 같이 입력해 본다.
armar -zt c_a__se.l [ENTER]
많은 량의 출력이 화면상에 표시될 것이다.
Code RO Data RW Data ZI Data Debug Object Name 152 0 0 0 116 __dup.o 168 0 0 0 56 __main.o 172 0 0 0 56 __main_nshl.o 중략... 44 0 0 0 80 stats.o 1648 0 0 204 584 stdio.o 492 0 0 0 204 stkheap1.o 중략... 124 0 0 0 88 vsnprintf.o 96 0 0 0 84 vsprintf.o 80 0 0 0 80 wcstombs.o 28 0 0 0 60 wctomb.o 54664 2788 0 1030 31700 TOTAL ENTRY at offset 0 in section !!! of __main.o ENTRY at offset 0 in section !!! of __main_nshl.o |
표준라이브러리 내의 많은 오브젝트 모듈 모습이 보인다.
익숙한 이름인 '__main.o', ' stdio.o', ' vsnprintf.o' 들이 눈에 띈다.
다음으로는 이 라이브러리(c_a__se.l)에서 'stdio.o' 을 추출하고 이 오브젝트에는 어떤 것들이 들어 있는지 보겠다.
armar -x c_a__se.l stdio.o [ENTER]
실행 후 현재 폴더에 stdio.o 파일이 하나 새롭게 보이게 될 것이다.
방금 실행 결과 라이브러리에서 해당 오브젝트 모듈이 추출된 것이다. 한편 라이브러리의 크기나 내용에는 변화가 없다.
stdio.o 만을 구성원으로 하는 새로운 라이브러리(test.l)를 하나 만들겠다.
armar -r test.l stdio.o [ENTER]
새로 만들어진 라이브러리test.l의 심볼테이블을 확인하기 위해서는 다음의 옵션('-zs')을 입력한다.
armar -zs test.l [ENTER]
다음과 같이 해당 라이브러리(오브젝트)에서 사용된 변수, 함수가 출력된다.
__stdin from stdio.o at offset 256 __stdout from stdio.o at offset 256 __stderr from stdio.o at offset 256 _seterr from stdio.o at offset 256 _writebuf from stdio.o at offset 256 _flushlinebuffered from stdio.o at offset 256 _fflush from stdio.o at offset 256 _deferredlazyseek from stdio.o at offset 256 fclose from stdio.o at offset 256 freopen from stdio.o at offset 256 fopen from stdio.o at offset 256 _initio from stdio.o at offset 256 _terminateio from stdio.o at offset 256 |
이제 'stdio.o' 안에는 우리가 즐겨 사용하는 fopen, fclose, __stdout 같은 류의 함수나 변수가 들어 있는 것을 눈으로 확인 할 수 있게 되었다. 이로써 우리는 대충 라이브러리안이 이런 일을 할 수 있다는 것을 알게 되었다.
이를 응용하면 다음과 같은 것도 가능 할 수 있다. 본 글의 주제 이기도 하다.
armar -d c_a__se.l stdio.o [ENTER]
'-d' 옵션은 라이브러리에서 특정 오브젝트 모듈을 삭제하는 명령이다.
new_stdio.c 코드를 사용자가 직접 작성하여서 표준라이브러리를 커스터 마이징 할 수 있다.
armar -r c_a__se.l new_stdio.o [ENTER]
여기서의 '-r' 은 라이브러리에 오브젝트를 추가 하는 옵션이다.
만약에 사용자가 fopen() 을 재 명명하여 다음과 같이 수정하여 빌드(new_stdio.o) 하여 기존의 'c_a__se.l' 에 추가 시켜 놓았다면?
| FILE *fopen(const char *filename, const char *mode) { static FILE fd; printf("미안합니당.\"); return & fd; } |
fd= fopen("파일명", "r");
열리 라는 파일은 안 열리고 화면에 "미안합니당." 란 단촐한 메시지 만을 보게 될 것이다.
당연히 위의 fopen류의 함수는 함수의 모양(명칭, 인자의 유형 갯수, 리턴유무)이 알려져 있지만 모르는 함수는 짐작으로 때려 맞춰서라도 만들 수는 있다.
마지막으로 필자가 라이브러리안을 사용 하여 개발시 문제를 해결한 하나의 사례를 소개 하는 것으로 본 글을 마치려 한다.
일전에 voip 인터넷 전화 장비를 개발 할 즈음에 호(CALL) 처리용 DSP 라이브러리를 사용 하였는데 이상하게도 사용된 호 처리 함수 라이브러리(소위 SDK 라고 하는것)에서 아웃바운드 콜 호출 함수는 지원되는데 반대의 개념인 인바운드 콜 호출 함수가 매뉴얼에 보이질 않는 것이 었다.
이상한 일이 었다.
DTMF_OUTBOUND(); DTMF_INBOUND();
예를 들면 위의 함수가 둘 다 있어야 하는데 SDK 매뉴얼 상에는 DTMF_OUTBOUND 만 설명 되어 있고, DTMF_INBOUND 는 보이질 않는 것이었다.
이 글을 적고 있는 지금와서는 내가 당시 SDK 을 정확히 이해 못해서 그랬던 것으로 생각하고 있고, 믿고 싶지만 어쨋든 당시에는 심각한 문제였다. 늘 상 그렇듯이. . .
업체에 질문도 넣어보고 하다 하다 날만 보내다 어느날 번뜩 떠오르는 것이 있어 즉시 하나의 시도를 해보았다.
armar -zs sdk.l [ENTER]
순간 깜짝 놀랐다. 예상했던 함수 이름인 DTMF_INBOUND 와 정확히 일치하지는 않지만 비슷한 이름의 함수 이름이 보였다. 예를들면 _dtmf_INBOUND 이런식으로 말이다.
아무 생각없이 이 출처 불명의 함수를 DTMF_OUTBOUND와 입/출력 인자(아규먼트)가 같다고 가정하고 그냥 사용 해 보았다.
그런데, 설마. 이 함수가 놀랍게도 내가 원하는 작동을 하는 것이다.
이때 기쁨과 한숨이 동시에 튀어 나온다. 한숨보다는 기쁨이 훨씬 크지만 말이다.
개발 목표 일정은 목전에 다가온 빠듯한 상황에서 가뭄에 단비와도 같은 것이었다.
지금의 소개 글이 바람직한 상황은 절대 아니다. 출처 불명의 코드를 사용하였기 때문이다. 이로써 사후 문제가 발생시 해당 공급 업체(DSP SDK)에서 보상은 물론이고 지원을 받을 수가 없을 지도 모른다.
하지만, 최악의 상황이라는 것은 언제라도 있을 수 있다는 것을 생각해 본다면 이러한 꼼수가 분명 돌파구 역할을 했음은 누구도 인정할 것이라고 생각한다.
본 칼럼은 악의적인 편법을 알리려는 의도 보다는 하나의 꼼수를 공유하려는 것이며 임베디드 뿐 아니라 일반적인 소프트웨어 분야에서도 '꼼수'는 특정 상황에서 어떤 문제를 풀어 나가는데 중요한 열쇠가 되기도 한 다는 것을 많은 이들이 또 공감 할 줄로 믿는다.
-홍익컴닷컴-
http://www.hongikcom.com
♡ 포스팅이 유익 하셨다면 E-mail로 가일의 임베디드 스쿨을 구독하세요->

추억의 80-90년대 임베디드 시스템 개발 - 2009/02/09 16:51
제가 임베디드 시스템을 개발하던 90년도 초에는 소프트웨어 개발 환경으로는
롬라이터라고 부르는 장비와 롬이레이져라는 장비가 소프트웨어 개발 주력 장비로서
개발 방법으로는 지금 생각해 보면 아찔 하기 짝이 없었죠.
코드 만들어서 EPROM이라는 메모리에 전용장비 롬라이터(ROM Writer)를 이용하여 기록합니다.
소위 굽는다(fusing) 고 표현을 하곤 하였습니다.
[그림]ROM Writer의 모습
코드를 기록하고 타깃보드 소켓에 올려서 동작 시켜 본 후에
버그가 있으면 다시 롬(ROM)을 마찬가지 방법으로 교체하여 동작시키고
이전의 롬은 롬이레이저(ROM Eraser)라는 장비에서 수분간 UV(자외선)에 노출시켜
기록된 정보를 모두 지우는 일련의 과정이 반복 되었습니다.
[그림]ROM Eraser의 모습
당시에도 현재의 부트로더라 불리울 만한 '모니터롬(MONITOR ROM)'
프로그램이라는 것이 있었고 이를 이용하면 간단한 프로그램 정도는
타깃보드에 다운로드하여 실행 해 볼 수 있었습니다.
하지만 대개 이를 개발에 응용하지 않았던 것은 아마도
19,200baud 이하의 느린 UART 다운로드 전송 속도와
그리 크지 않은(커봐야 1MB) 메모리(램/롬)의 제한 때문이 아니었는가 생각해 봅니다.
한편, 당시에도 지금과 같은 ICE라 불리우는 장비가 있었고 실제로 사용 하였습니다.
그 이름은 MDS(Microprocessor Development System)라 많이 불리웠습니다.
하지만 덩치가 왠만한 노트북 몇개를 포개논 정도의 크기로써 자리도 많이 차지하고
장비도 1천만원 이상의 고가(지금 기준으로는 2천만원 이상 호가)로서
다루기도 조심스러워서 꼭 필요 할 때에만 사용 하였었죠.
[그림]MDS의 모습( 사용된 그림은 본 글의 내용과 관련이 없슴을 밝힙니다 )
이런 방법(위와 같은 방법)으로 개발하다가
지금의 JTAG을 이용한 장비를 처음 접 하였을적에는
얼마나 놀라웠고 또한 감동적 이었는지 모릅니다.
케이블에 작은 POD가 달려있는 형태였으며,
그 크기는 지금의 MULTI-ICE 와 유사한 바로 그것이었습니다.
개발 호스트(PC)의 LPT포트에 연결하여 사용토록 되어 있었죠. 지금처럼. . .
당시에 제가 가장 사랑(?) 하던 장비는
MDS(혹은 JTAG)와 로직분석기(LOGIC ANALYZER) 였던 것으로 기억합니다.
[그림]로직아날라이져의 모습( 사용된 그림은 본 글의 내용과 관련이 없슴을 밝힙니다 )
로직아날라이져는 어려운 문제점에 봉착하였을때
엄청난 위력을 발휘하여 단숨에 해결하는 위용을 자랑 하였 더랬습니다.
기회가 있다면 나중에 이와 관련한 자세한 스토리를 공개 하도록 하지요.
-홍익컴닷컴-





02200603058.pdf
cfaq.zip