<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3084076692842398657</id><updated>2012-01-07T01:50:55.309-08:00</updated><title type='text'>ちょい(Choi)のEmbedded Systems</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kmchoi0703.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3084076692842398657/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kmchoi0703.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>崔剛敏(チェ カンミン), Choi Kangmin</name><uri>http://www.blogger.com/profile/18380461159096818123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3084076692842398657.post-6963378457095454776</id><published>2010-02-14T18:43:00.000-08:00</published><updated>2010-02-14T18:56:06.695-08:00</updated><title type='text'>__use_no_semihosting_swiエラー対策</title><content type='html'>&lt;br&gt;&lt;br /&gt;セミホスティングとはアプリケーションによるサービス要求を、デバッガを通してホストコンピュータで動作する機能です。サービス要求方法としては標準ライブラリ関数を呼び出すことによる間接的な方法もありますが、SWI命令語を直接呼び出す方法もあります。&lt;br /&gt;&lt;br /&gt;例えば、ある関数で時間を得るためにtime関数を呼び出したとします。time関数は以下のようになっています。&lt;br /&gt;&lt;br /&gt;time&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;（省略）&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0x00008028: ef123456 V4.. SVC #0x123456 ; formerly SWI&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;（省略）&lt;br /&gt;&lt;br /&gt;標準ライブラリの大半は上記のようにSVCを呼び出してホストにサービス要求を依頼します。これは通常デバッグ環境で必要であり、出荷するバージョンだと困ります。スタンドーアロンで動作できるように、すなわちそれ自体の持っている機能だけで動作しなければなりません。&lt;br /&gt;&lt;br /&gt;解決方法としてセミホスティング機能を使っている箇所を見つけ、直接実装する方法があります。&lt;br /&gt;以下のように明示的にセミホスティングを使わないように指定できます。&lt;br /&gt;&lt;br /&gt;C言語の場合&lt;br /&gt;#pragma import(__use_no_semihosting_swi)&lt;br /&gt;&lt;br /&gt;アセンブリの場合&lt;br /&gt;IMPORT __use_no_semihosting_swi&lt;br /&gt;&lt;br /&gt;再度ビルディングすると以下のようなエラーが発生します。&lt;br /&gt;&lt;br /&gt;Error: L6915E: Library reports error: __use_no_semihosting_swi was requested, but time was referenced&lt;br /&gt;&lt;br /&gt;エラーは“セミホスティングを使用しないと宣言したのにどこかでtimeを参照している”という意味です。&lt;br /&gt;さて、どこで参照しているでしょうか？希望が大きいプロジェクトだとソースコードが多くて見つけるのも大変です。またサードーパーティー会社から提供して頂いたライブラリが参照しているかも知れません。&lt;br /&gt;&lt;br /&gt;以下のようにリンカーオプションを追加しますと参照している箇所を教えてくれます。&lt;br /&gt;&lt;br /&gt;armlink (オプション省略) --list info.map --verbose&lt;br /&gt;&lt;br /&gt;そして生成されたinfo.mapファイルから「__I_use_semihosting」を検索します。&lt;br /&gt;&lt;br /&gt;Loading member sys_time.o from c_4.l.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;definition: time&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reference : __I_use_semihosting&lt;br /&gt;&lt;br /&gt;すなわち、time関数でセミホスティングの機能を使っていました。&lt;br /&gt;セミホスティング機能を使わないようにtime関数を直接実装して解決できます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3084076692842398657-6963378457095454776?l=kmchoi0703.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kmchoi0703.blogspot.com/feeds/6963378457095454776/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://kmchoi0703.blogspot.com/2010/02/usenosemihostingswi.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3084076692842398657/posts/default/6963378457095454776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3084076692842398657/posts/default/6963378457095454776'/><link rel='alternate' type='text/html' href='http://kmchoi0703.blogspot.com/2010/02/usenosemihostingswi.html' title='__use_no_semihosting_swiエラー対策'/><author><name>崔剛敏(チェ カンミン), Choi Kangmin</name><uri>http://www.blogger.com/profile/18380461159096818123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3084076692842398657.post-1044066626757550260</id><published>2010-02-12T03:10:00.000-08:00</published><updated>2010-02-14T18:58:10.192-08:00</updated><title type='text'>コンテキストスイッチング速度の測定方法</title><content type='html'>&lt;br&gt;&lt;br /&gt;リアルタイムOSをターゲットに移植（ポーティング）するためにはいくつかのプロセッサ依存コードが必要です。例えば、タスク間に切り替えを行うためには現在動作している最中のタスクのコンテキストを保存します。この後、何らかの理由（例。セマフォに待つ）でディスパッチャはレディー状態になったより優先順位が低いタスクのコンテキストを復帰させます。このようになタスク間の切り替えを“タスクレベルのコンテキストスイッチング”といいます。&lt;br /&gt;&lt;br /&gt;一般的にC言語ではプロセッサのレジスタを自由自在にシステムスタックに保存したり、復帰することは不可能です。こういう制限を解決するためには直接プロセッサに依存するアセンブリコードを書くしかありません。プロセッサに依存する部分を“ポート”といいます。ポートを開発するためにはプロセッサの知識とリアルタイムOSに関する知識が必要であり、単純な作業ではありません。&lt;br /&gt;&lt;br /&gt;ここではポートの一部であるタスクレベルのコンテキストスイッチングを測定する方法について説明します。 外部から観察するためには特定GPIOとオシロスコープが必要です。まず次のように優先度が高いタスクと低いタスクを用意します。&lt;br /&gt;&lt;br /&gt;void HPT_Task(void)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LED_ClrLED0();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(;;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OS_Suspend();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LED_ClrLED0(); // D&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void LPT_Task(void)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(;;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LED_SetLED0(); // A&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LED_ClrLED0(); // B&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LED_SetLED0(); // C&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OS_Resume( &amp;amp;HPTaskTcb );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;１．リアルタイムOSが起動すると優先順位が高いHPT_Taskを動作させます。&lt;br /&gt;２．HPT_TaskはOS_Suspend関数を呼び出して待機状態になります。&lt;br /&gt;３．カネルのディスパッチャにより次の優先度を持つLPT_Taskを動作させます。&lt;br /&gt;４．LPT_TaskはLED_SetLED0関数を呼び出して特定GPIOをハイレベルにしておき、 HPT_TaskのTCBを引数としてOS_Resume関数を呼び出します。再びディスパッチャによりHPT_Taskが 動作されます。&lt;br /&gt;５．HPT_TaskはOS_Suspend関数の続きから実行し、今度は特定GPIOをローレベルにします。&lt;br /&gt;&lt;br /&gt;オシロスコープで各空間を測定しますと(A-B)はGPIO出力関数にかかる時間になり、(C-D)はタスクレベルのスイッチングにかかる時間になります。(C-D)－(A-B)を計算したら、タスクレベルのコンテキストスイッチングにかかる正確な時間を確認できます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3084076692842398657-1044066626757550260?l=kmchoi0703.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kmchoi0703.blogspot.com/feeds/1044066626757550260/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://kmchoi0703.blogspot.com/2010/02/blog-post.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3084076692842398657/posts/default/1044066626757550260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3084076692842398657/posts/default/1044066626757550260'/><link rel='alternate' type='text/html' href='http://kmchoi0703.blogspot.com/2010/02/blog-post.html' title='コンテキストスイッチング速度の測定方法'/><author><name>崔剛敏(チェ カンミン), Choi Kangmin</name><uri>http://www.blogger.com/profile/18380461159096818123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3084076692842398657.post-5922192757400502300</id><published>2009-10-29T18:01:00.000-07:00</published><updated>2009-10-30T02:28:33.805-07:00</updated><title type='text'>Introducing to uC/OS-III</title><content type='html'>&lt;div&gt;&amp;nbsp;    &lt;p align="center"&gt;&lt;a href="http://1.bp.blogspot.com/_2WKihwV3s68/Suo86sqSU_I/AAAAAAAAAAk/hFIo4jiHnj8/s1600-h/uCOS-III_Book.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5398194082475561970" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 226px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_2WKihwV3s68/Suo86sqSU_I/AAAAAAAAAAk/hFIo4jiHnj8/s320/uCOS-III_Book.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;font size="2" face="맑은 고딕"&gt;얼마 전 RTOS 구현을 명쾌하게 해설한 uC/OS-II의 후속작인 uC/OS-III – The Real Time Kernel이 발간되었습니다. 800페이지에 달하는 엄청난 분량의 서적과 타겟에서 uC/OS-III를 평가해 볼 수 있는 평가보드로 구성되어 있습니다. 전작을 보신 분들은 아시겠지만 Jean J. Labrosse의 저술 스타일이 워낙 간결하고 자세하게 설명되어 있어 원서로 봐도 무리가 없습니다. 평가보드에는 STM32 프로세서가 탑재되어 있는데 Segger사의 J-Link가 빌트인 되어 있는 것이 특징입니다.&lt;br&gt;&lt;br&gt;다음은 uC/OS-II와 uC/OS-III를 비교한 자료입니다. Micrium에서 제공하는 Data Sheet에서 인용했습니다. &lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;p align="center"&gt;&lt;img id="BLOGGER_PHOTO_ID_5398197032158989778" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 349px; CURSOR: hand; HEIGHT: 400px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_2WKihwV3s68/Suo_mZFnjdI/AAAAAAAAAA4/vLfJLkEmfgk/s400/uCOS-III_ComparisonChart.JPG" border="0" /&gt; &lt;/p&gt;&lt;br /&gt;&lt;div&gt;    &lt;p align="left"&gt;&lt;font size="2" face="맑은 고딕"&gt;위 표에서도 알 수 있듯이 uC/OS-II와의 큰 차이점은 생성할 수 있는 태스크 수에 제한이 없어졌다는 것입니다. 또한 전작은 태스크에 부여할 수 있는 우선 순위가 유일해야 하나 uC/OS-III는 동일한 우선 순위의 태스크를 생성할 수 있으며 라운드 로빈 방식으로 스케쥴링 됩니다.&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;font size="2" face="맑은 고딕"&gt;서적을 탐독하다 감탄한 몇 가지 내용들을 소개하고자 합니다.&lt;/font&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;strong&gt;&lt;font size="2" face="맑은 고딕"&gt;우선 순위 검색 최적화&lt;/font&gt;&lt;/strong&gt;&lt;font size="2" face="맑은 고딕"&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;MCU가 CLZ (Count Leading Zeros)와 같은 명령어를 지원한다면 최상위 우선 순위의 태스크 검색을 최적화 할 수 있다고 합니다. CLZ 명령어 셋은 MSB로부터 비트가 설정되어 있는 카운트 값을 반환하는 명령어입니다. MSB가 높은 우선순위를 나타낼 때 메모리에 상주한 프로그램 코드로 비트 설정 유무를 확인하는 것보다 명령어 셋을 이용하는 것이 나을 것입니다. 아시겠지만 메모리가 외부 버스에 있던 내부 버스에 있던 MCU 명령어 셋보다 빠르진 않을 것입니다. 최적화를 위해 많은 고민을 한 저자의 노력이 돋보입니다.&lt;/font&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;strong&gt;&lt;font size="2" face="맑은 고딕"&gt;인터럽트 지연 최소화&lt;/font&gt;&lt;/strong&gt;&lt;font size="2" face="맑은 고딕"&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;커널 코드 조차도 ISR과 커널 자료구조를 공유하고 있으므로 크리티컬 섹션을 보호하기 위해서는 인터럽트를 disable 해야 합니다. 이는 인터럽트 응답 지연으로 이어져서 응답 시간이 크리티컬한 애플리케이션에서는 문제가 있다는 것입니다. 커널 코드가 최소한의 인터럽트만 지연시키도록 구현했을 것임에도 불구하고 이것도 용납할 수 없다는 (?!) 저자의 세심하고 꼼꼼한 성격을 알 수 있습니다.&lt;br&gt;uC/OS-III는 커널 코드로 인한 인터럽트 지연을 최소화하기 위해 Deferred Post Method라는 방법을 제공합니다. 틱이 발생할 때 Interrupt Queue라는 자료 구조로 Interrupt Queue Task에 시그널을 보냅니다. (아주 짧은 인터럽트만 지연 시킨다고 했는데 소스 코드가 공개되어 있지 않은 관계로 확인은 못했습니다.) Interrupt Queue Task는 우선 순위가 가장 높은 태스크로 예약되어 있어 ISR 종료와 함께 반드시 실행됩니다. Interrupt Queue Task에서는 Tick 서비스나 라운드 로빈 스케쥴링과 같은 커널 서비스 수행합니다.&lt;br&gt;이 때 중요한 것은 크리티컬 섹션을 보호하기 위해 인터럽트를 disable하는 것이 아니라 스케쥴러를 잠궈 uC/OS-III 커널 코드 자체가 태스크 수준에서 동작한다는 것입니다.&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;strong&gt;&lt;font size="2" face="맑은 고딕"&gt;커널 오브젝트 타입&lt;/font&gt;&lt;/strong&gt;&lt;font size="2" face="맑은 고딕"&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;uC/OS-II에서는 세마포어나 뮤텍스와 같은 커널 오브젝트를 모두 OS_EVENT 타입으로 정의했는데 어떤 용도로 사용할 것인지에 따라 쓰임이 달랐습니다. (물론 이벤트 플래그는 예외입니다.) uC/OS-III에서는 커널 오브젝트에 대기 중인 태스크 리스트나 Name 필드와 같은 커널 자료 구조의 공통적인 필드들을 동일한 오프셋에 위치 시키고 새로운 타입으로 정의하고 있습니다.&lt;br&gt;&lt;br&gt;소스 코드를 확인하지 못했지만 공통적인 필드들을 동일한 오프셋에 위치 시킨 이유는 커널이 커널 오브젝트를 다루는 방법이 거의 비슷하기 때문일 것입니다. 커널 오브젝트에 대기중인 태스크 리스트를 얻어 오거나 대기할 태스크를 등록하는 코드 등이 예일 것입니다. 커널 코드 자체도 공용으로 사용하여 줄이자 라는 심보(?!)인 것 같습니다.&lt;/font&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;strong&gt;&lt;font size="2" face="맑은 고딕"&gt;커널 오브젝트 대기 시간 측정&lt;/font&gt;&lt;/strong&gt;&lt;font size="2" face="맑은 고딕"&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;커널 오브젝트에 공통으로 TS (Timestamp) 필드가 선언되어 있습니다. 예를 들어 세마포어 대기 함수의 시그너처는 다음과 같습니다.&lt;br /&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;font size="2" face="맑은 고딕"&gt;OS_SEM_CTR OSSemPend( OS_SEM * p_sem, OS_TICK timeout, OS_OPT opt, CPU_TS * p_ts, OS_ERR * p_err);&lt;br /&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;font size="2" face="맑은 고딕"&gt;p_ts라는 인자에 CPU_TS 타입의 변수를 넣고 호출하면 OSSemPend가 깨어나는 시점에 Timestamp 값이 저장됩니다. (깨어나는 시점에는 시간 경과, 세마포어 획득, 세마포어가 삭제 등 다양한 경우가 있을 것입니다.) Timestamp 값은 시그널 용도로 세마포어를 사용할 때 의미가 있다고 합니다. OSSemPost로 시그널을 보내면 OSSemPend()에서 대기 중이던 태스크가 깨어나게 되고 이 때 Timestamp 값을 얻습니다. 현재 Timestamp 값과의 차를 이용하면 시그널을 받는데 얼마나 경과되었는지 알 수 있습니다. 시간에 예민한 애플리케이션에는 아주 유용할 것 같습니다. 물론 바이너리 세마포어로 공유 자원을 보호하는 목적이라면 Timestamp 값은 큰 의미가 없을 것입니다.&lt;br&gt;&lt;/font&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;&lt;font size="2" face="맑은 고딕"&gt;Timestamp 값으로 Tick 카운트를 저장하면 충분할 것이라 생각했는데, Free-running counter를 사용하라고 권고합니다. Tick 카운트가 대략 100 hz ~ 1000 hz 정도로 발생하는 것을 감안하면 ms 단위이나 하드웨어 타이머 컨트롤러를 사용하면 us 혹은 ns 단위의 Resolution을 얻을 수 있겠습니다.&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;&lt;font size="2" face="맑은 고딕"&gt;‘uC/OS-III – The Real Time Kernel’은 많은 영감과 깨달음을 주는 훌륭한 지침서임에는 틀림 없습니다.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;    &lt;p align="center"&gt;&lt;b&gt;&lt;i&gt;&lt;font size="2" face="맑은 고딕" color="red"&gt;본 블로그는 정보 제공을 목적으로 작성된 것으로서 인용된 사진이나 글은 본 저작권자에게 있음을 알립니다.&lt;/font&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3084076692842398657-5922192757400502300?l=kmchoi0703.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kmchoi0703.blogspot.com/feeds/5922192757400502300/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://kmchoi0703.blogspot.com/2009/10/introducing-to-ucos-iii.html#comment-form' title='2개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3084076692842398657/posts/default/5922192757400502300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3084076692842398657/posts/default/5922192757400502300'/><link rel='alternate' type='text/html' href='http://kmchoi0703.blogspot.com/2009/10/introducing-to-ucos-iii.html' title='Introducing to uC/OS-III'/><author><name>崔剛敏(チェ カンミン), Choi Kangmin</name><uri>http://www.blogger.com/profile/18380461159096818123</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_2WKihwV3s68/Suo86sqSU_I/AAAAAAAAAAk/hFIo4jiHnj8/s72-c/uCOS-III_Book.JPG' height='72' width='72'/><thr:total>2</thr:total></entry></feed>
