'Personal Computer/debug, iom_v2'에 해당되는 글 12건

  1. 2009.03.19 cups-pdf: [ERROR] failed to create user output directory 2
  2. 2007.04.18 Making CrossToolChain 2
  3. 2007.02.08 A팀, B팀
  4. 2007.01.26 coding style 3
  5. 2005.09.28 iom v2.1 spec.
  6. 2005.07.04 memory leak...
  7. 2005.06.30 analysis of low battery routine (IV)
  8. 2005.06.29 analysis of low battery routine (III)
  9. 2005.06.28 analysis of low battery routine (II)
  10. 2005.06.28 analysis of low battery routine (I)
PC에서 ubuntu 8.04 또는 그 이후 version을 설치하면 (아마 이전 version도 될 듯)
cups-pdf라는 package가 설치된다. adobe PDF writer같은 프로그램인데, 설치하면 PDF라는 printer가 생긴다. 그리로 출력하면 ${HOME} directory에 PDF directory가 생기면서 그 아래에 PDF file이 생기는 편리한 놈이다.

몇일전 PC가 맛가서 이전 PC에 이것저것 복구해서 쓰고 있는데,
이게 동작하지 않는거다. 분명히 출력했는데, 파일은 없는...
이상해서 log를 보니까 다음과 같이 나오면서 출력이 안되는 거였다.
root@moria:/var/log/cups# tail -f cups-pdf_log
Thu Mar 19 11:11:50 2009  [ERROR] failed to create directory (/mnt/hda3/tolkien/PDF)
Thu Mar 19 11:11:50 2009  [ERROR] failed to create user output directory (/mnt/hda3/tolkien/PDF)
Thu Mar 19 11:13:29 2009  [ERROR] failed to set file mode for PDF file (non fatal) (/mnt/hda3/tolkien/PDF/FormattingAnAndroidSdCard___WRSeng___TWiki.pdf)
Thu Mar 19 11:18:21 2009  [ERROR] failed to set file mode for PDF file (non fatal) (/mnt/hda3/tolkien/PDF/PPR_Test_Page.pdf)
원인은 apparmor의 문제. CUPS쪽 security를 담당하는 놈이라고 한다.
(지금까지 이런게 있는 줄도 몰랐다. --;;;)
나는 용량증설도 있고, 관리의 편리함때문에 /home/tolkien -> /mnt/hda3/tolkien 으로 link를 걸어놨는데, apparmor가 link를 처리하지 않아서 생기는 문제였다.
/etc/apparmor.d/usr.sbin.cupsd 에 다음 두줄 추가하고 apparmor를 다시 시작하니까 깔끔하게 된다.
  /mnt/hda3/tolkien/PDF/ rw,
  /mnt/hda3/tolkien/PDF/* rw,

Making CrossToolChain

Personal Computer/debug, iom_v2 2007. 4. 18. 13:39 posted by tolkien
크로스컴파일 환경 구축하기 - Monaca님의 글

개발 tool은 신뢰할 수 있어야 한다.

Embedded Linux System을 개발하는데, 마주치는 bug는
1. CPU or Chip의 bug
2. H/W 설계 bug
3. OS bug
4. Application bug
5. 개발자의 오타
6. 시나리오 부재 또는 오류
이들과 싸워야 하는 programmer에게 gcc와 같은 기본적인 toolchain에 있는 버그는 악몽과도 같다.

단순히 build가 되는 조합만 찾아서 build하면 ToolChain을 쓸 수 있는 것이 아니다.
그 다음에 반드시 해야 하는 것은 ToolChain에 대한 검증이다.

GNU toolchain에서는 이것을 regression test라고 부른다. 이 test는 많은 항목으로 이루어져 있고, 결과는 성공, 실패, 예상한 실패, 예상하지 못한 실패에 대한 항목 숫자로 나온다. (물론 실패에 대한 log도 제공한다.)

이 regression test는 native toolchain은 검증하기 쉽다. test tool을 설치하고 돌리면 그만이다. 그런데, cross toolchain은 그게 안된다. 각 file를 compile해서 해당 target에 돌린다음 그 결과를 봐야 하기 때문이다. 2만 항목이 넘는 것을 전부 수동으로 돌릴 수 없다. 따라서, 해당 tool에 대한 약간의 hacking과 host system 준비, NFS가 가능한 target board 환경이면 하루정도 꼬박 돌리면 결과를 볼 수 있다.

그리고, 그 결과를 분석해야 한다. 특히, 예상하지 못하게 성공하거나 실패한 항목에 대한 대비를 세워야 한다. 그 항목이 자주 쓰이는가, 관련 patch는 존재하는가, 그것을 피하는 방법은 있는지. patch가 있다면 patch해서 build한 다음에 문제는 없는지, 다른 부정적 효과는 없는지. 다시 regression test를 돌려봐야 한다.
그리고, gcc mailing list를 계속 monitor해서 현재 쓰고 있는 toolchain 조합에 보고된 문제가 없는지 확인해야 한다. 그 문제가 단순하게 정리가 되면 다음 gcc release에 test 항목으로 추가된다.

위 방법대로 하면 약 10개정도 내외의 bug를 지닌 ToolChain이 나온다. 남아 있는 bug들은 잘 쓰이지 않는 재현경로를 사용해서 발생하는 것들이다. 정석대로라면 toolchain에 README.BUG와 같은 file을 만들어서 해당 내용 및 재현방법을 기술해야 한다. 이에 대해서 피할 수 있는 방법까지 담고 있으면 더 좋다.
하지만, 그런 내용을 담은 file을 같이 배포하는 SDK를 보지 못했다.

결국 이 모든 악몽에서 벗어나는 방법은 검증된 ToolChain을 쓰는 것이다. 다음과 같은 방법으로 입수가 가능하다.

가. 상용으로 제공되는 것을 사는 경우, 비용은 약간 들지만 한두번 ToolChain Bug에 대한 경험을 가지고 있다면 상쇄할만하다. 특히 2~3년씩이나 오래 쓰는 경우, 기꺼이 치룰만하다.
나. 학생이거나 시험삼아 사용하는 경우, http://kegel.com/crosstool/ 와 같은 site에서 제공하는 ToolChain이 쓸만하다. 그들은 여러 version에 대한 (build 가능한) 조합을 제공하고, 조합한 결과에 대한 test 결과도 제공한다. 대개 toolchain의 bug는 잘 알려지지 않은 방법을 사용하는 경우에 발생하고, 약간의 위험을 감수할 만하다면 쓸만한다. 더우기 스스로 toolchain을 build해보는 즐거움도 맛볼 수 있다.
다. 몇몇 ToolChain 전문업체의 web site에 들어가서 download 받을 수 있다. 그들이 제공하는 ToolChain의 품질은 믿을만하고, 약간의 개인정보 (이름, e-mail과 같은)를 제공하고 받을 수 있다. 단지, 최신 CPU에 제공되는 새로운 instruction이나 최신 s/w version에서 제공하는 최적화 기능을 쓰지 못한다는 것은 감수해야 하지만. :-)

A팀, B팀

Personal Computer/debug, iom_v2 2007. 2. 8. 12:20 posted by tolkien
Ten Weeks 제도
20% 프로젝트, 성공의 조건
피자 두판의 법칙

(위에 것은 그냥 link다. 본 글하고 약간의 상관은 있을 것같다.)

꿈을 꾸었다. A/B팀과 13번 자리에 대한.

가. A/B팀은 어떤 업무에 대한 책임을 가지고 수행하는 팀과
그 팀을 지원 또는 대체하는 팀이라는 개념이다.

미 해군은 승무원을 A팀, B팀으로 나누어서 운영한다고 한다.
아마 미 핵잠수함은 비싼 장비고,
사람들을 장시간 물속에 갇혀지내게 할 수 없어서.라는 이유가 아닐까 생각한다.
A, B팀간 구별은 없다.라고 생각한다.

영화 "아폴로 13호"에 보면 우주선 승무원도
한번 발사시 두개 팀으로 나누어서 운영한다.
떠날 팀중에 문제가 생기면 같은 모듈로 갈아치우거나
팀을 바꾼다. (예비로 정해진) B팀은 또 다른 일정이 있는 A팀인 거다.

나. 13번 자리.라는 것이 있다.
(왜 하필 13인지 모르겠다. 꿈에서 L모씨가 그렇게 설명했다.)
일종의 블랙홀.
어떤 업무를 수행하는 사람 또는 업무 그 자체인데,
제대로 진행이 되지 않고 있고
더 큰 문제는 교체할 수 없는 상황인거다.

다. 이 꿈을 오늘 새벽에 꾸고 바로 깼다.
아마 요즘 내 고민중 하나인 어떻게 팀을 구성할까.에 대한
무의식적인 해답 도출 노력의 일부가 아닐까.

coding style

Personal Computer/debug, iom_v2 2007. 1. 26. 11:36 posted by tolkien
코딩도 글쓰기... - 시즈하님의 글

kernel code는 읽기 쉽습니다.
왜냐면 만든 사람만 보는 code가 아니거든요.
중심으로 가면 조금 복잡해지긴 하지만...

coding style은 개개인 생각도 중요하지만,
같이 일하는 팀원끼리 호흡도 중요합니다.
제가 잘 범하는 오류중 하나는
제가 본 code를 제가 읽기 쉬운 형태로 바꾸는 겁니다.
아무리 좋은 약이라고 직접 떠 먹지 않으면 효능이 없다는 거거든요.

시즈하님이 생각하고 있는 바를
같이 일하는 사람에게 논리적으로 지속적으로
얘기를 해서 모두 공감하도록 하는게 이상적입니다.

그게 안되는 경우, 본인이 짜는 code를
다른 사람들이 이용하게 될 경우 "편하다"라는
인상을 주어서 공감대를 형성하게 하는 방법이 있습니다만,
기존 code라는 벽때문에 고생하실 겁니다.
- 시즈하님의 글에 단 댓글 -

몇가지 coding style에 대한 글의 link를 적어놓습니다.
Style Guide for Python Code
리눅스 코리아 PHP Coding Standard

CodingStyle, NamingRule에 관해서는
밤새 토론해도 결론이 나지 않을 내용중 하나라고 생각합니다.
이럴 때 필요한 것은 총대를 메는 사람.

그들 후보는...
1. 팀장. (직급으로 누른다.)
2. 시즈하. (패기와 열정으로 앞도한다.)
3. 사장님. (Nice!)

iom v2.1 spec.

Personal Computer/debug, iom_v2 2005. 9. 28. 14:58 posted by tolkien
에 대한 구상이 잠시 떠올라서 적어둔다.

1. Information Center를 browsing할 수 있게 web interface를 사용하자. (http://localhost:8010/...)
3. object -> directory, misc/object's attribute -> file 로 구현한다.
4. object 추가는 http://localhost:8010/cgi-bin/add?node=...&value=object
2. attribute를 추가/수정은 http://localhost:8010/cgi-bin/add?node=...&value=... 로 통일
5. connection에 대한 속성을 준다. http://localhost:8010/cgi-bin/conn?node=...&value=...
5.1 node/ value
5.1.1 format: html/raw

6. connection은
6.1 named pipe(PHN, SKY, KMR등 reserved address에 사용)
6.2 domain socket(iom client)
6.3 inet socket(debugging or 기타 용도)

memory leak...

Personal Computer/debug, iom_v2 2005. 7. 4. 17:27 posted by tolkien
라고 생각하면 source의 bug라고 생각한다.
하지만, 다음과 같은 경우도 결국 memory 부족을 유발한다.

syslog를 ramdisk에 저장하도록 하고 2분 10초간격으로

[CODE]Jan 4 01:40:46 (none) daemon.info /sbin/kmsgd[40]: clock: set for PAL_TV or NTSC_TV? Jan 4 01:40:46 (none) daemon.warn /sbin/mrouter[38]: warning: queue [/tmp/mb_CB9] open failed...No such device or address Jan 4 01:40:46 (none) daemon.warn /sbin/mrouter[38]: warning: queue [/tmp/mb_CB9] open failed...No such device or address Jan 4 01:40:47 (none) daemon.warn /sbin/mrouter[38]: warning: queue [/tmp/mb_CB9] open failed...No such device or address[/CODE]
와 같은 msg를 담으면 (총 455byte) 나중에는 memory가 부족해진다.
그럼 이제 정리해보자. (아직 구상중이지만...)

1. PDA battery low
[CODE]/* check whether battery is low or not */ if ((info->dat.ac == AC_OFF_LINE) && (info->dat.level == BATTERY_LEVEL_BAR_0)) { . update battery_status as low_battery if (!(info->stat & BATTERY_SENT_ALARM)) { info->stat |= BATTERY_SENT_ALARM; . send "battery=low" msg } /* add time counter */ b_time_inc(info, BATTERY_LOW_MSG_TIME); /* time to send msg? */ if ( (info->dat.voltage < BATTERY_VOL_LOW) && (info->time[BATTERY_LOW_MSG_TIME] >= BATTERY_MSG_LOW_INTERVAL) ) { if (info->dat.voltage < BATTERY_VOL_PDA_OFF) { /* system off */ if (info->time[BATTERY_OFF_MSG_TIME] >= BATTERY_MSG_PDA_OFF_INTERVAL) . send "battery=off" msg else b_time_inc(info, BATTERY_OFF_MSG_TIME); } else { b_time_clr(info, BATTERY_OFF_MSG_TIME); . send "battery=low" msg b_time_clr(info, BATTERY_LOW_MSG_TIME); } } } else { . it is not low battery. }[/CODE]
PHONE이 요구하는 것은 다음과 같다.

1. PHONE에서...
[CODE] if (info->dat.voltage < BATTERY_VOL_LOW) { if (info->dat.voltage < BATTERY_VOL_PHN_STBY/CALL_OFF) { . send "phone=off" msg to PDA . blah blah... } else { . send "battery=low" msg to PDA }} . send "battery bar 0/1/2/3" msg to PDA[/CODE]


2. PDA에서...
[CODE] if (info->dat.voltage < BATTERY_VOL_PDA_OFF) { /* system off 하기 전에 PHN이 안죽었으면 먼저 꺼라! */ if (info->fsm[BATTERY_FSM_PHONE] != BATTERY_FSM_PHONE_OFF) { . turn off PHN . wait for another 12 seconds } else { . turn off PDA } }[/CODE]

가 전부라고 생각했다. BUT!!!

3. PHONE & PDA
A. PHN에서 bar3, bar2, bar1, bar0(warn), off msg가 PDA쪽으로 보냄
B. bar0(warn)에 대해서 "battery=low" msg display
off에 대해서 "phone=off" & Turn PHN Off
C. 고려해야 할 상황 on "battery=low/off"
가. PHN-On PDA-On
나. PHN-On PDA-Sleep
다. PHN-On PDA-Sleep->Wakeup
라. PHN-Off PDA-Sleep
마. PHN-Off PDA-Sleep->Wakeup
(I)에서 code로 된 것을 말로 풀어보자

1. 기본 low battery 흐름
[CODE] /* check whether battery is low or not */ if ((info->dat.ac == AC_OFF_LINE) && (info->dat.level == BATTERY_LEVEL_BAR_0)) { . update battery_status as low_battery if (!(info->stat & BATTERY_SENT_ALARM)) { info->stat |= BATTERY_SENT_ALARM; . send "battery=low" msg } /* add time counter */ b_time_inc(info, BATTERY_LOW_MSG_TIME); /* time to send msg? */ if ( (info->dat.voltage < BATTERY_VOL_LOW) && (info->time[BATTERY_LOW_MSG_TIME] >= BATTERY_MSG_LOW_INTERVAL) ) { . send "battery=low" msg b_time_clr(info, BATTERY_LOW_MSG_TIME); } } else { . it is not low battery. }[/CODE]


2. PDA off가 들어가면...
[CODE] /* time to send msg? */ 안을 다음 routine으로 대체 if (info->dat.voltage < BATTERY_VOL_PDA_OFF) { /* system off */ if (info->time[BATTERY_OFF_MSG_TIME] >= BATTERY_MSG_PDA_OFF_INTERVAL) . send "battery=off" msg else b_time_inc(info, BATTERY_OFF_MSG_TIME); } else { b_time_clr(info, BATTERY_OFF_MSG_TIME); . send "battery=low" msg b_time_clr(info, BATTERY_LOW_MSG_TIME); }[/CODE]


3. PHONE 추가
지금까지는 평화로왔는데, PHONE이라는 손님 등장...
라고 하면 거창한데, 내가 짠 code를 내가 헥갈려서 정리한다는 거다. (자폭 모드 T.T)

일단, 어디 어디 있는지 정리부터 해볼까.

1. phone.c
[CODE]static int b_phone_power(batt_info_t *info, phone_pkt_t *pp) {[/CODE]
[CODE]if (pp->action == LXT_PHN_POWER_BATTERY_STATUS_NOTIFICATION) { switch (stat) { case PHONE_POWER_IS_NORMAL: case PHONE_POWER_IS_WARNING: case PHONE_POWER_IS_OFF:[/CODE]

[CODE]int handle_phone_off(batt_info_t *info); int handle_phone_warning(batt_info_t *info);[/CODE]


2. misc.c
[CODE]void b_set_battery_low(batt_info_t *info); int b_check_battery_low(batt_info_t *info) {[/CODE]
[CODE] if (!(info->stat & BATTERY_SENT_ALARM)) { ... } if (info->dat.voltage < BATTERY_VOL_PDA_OFF) { } else { /* if (info->dat.voltage < BATTERY_VOL_PDA_OFF) */ }[/CODE]


3. handler.c
[CODE]int b_handler_normal(batt_info_t *info, BATTERY_RET *bat) {[/CODE]
[CODE] /* check whether battery is low or not */ if ((info->dat.ac == AC_OFF_LINE) && (info->dat.level == BATTERY_LEVEL_BAR_0)) { /* update battery_status except mz_battery_stat(0xff) */ info->dat.battery = bat->battery & ~mz_battery_stat(0xff); b_set_battery_low(info); MSG_INFO(1, "battery_low: %dv\n", info->dat.voltage); if (info->dat.voltage <= BATTERY_VOL_LOW) b_check_battery_low(info); } else { info->dat.battery = bat->battery; b_time_clr(info, BATTERY_OFF_MSG_TIME); } return 0;[/CODE]