現状FreeRTOS提供のFunction使用例<現状>現時点(10月10日時点)での最新版は、V.6.1.0です。私はV.6.0.3をベースに使用しています。解凍すると多くのディレクトリに展開されますが、LPC1768を使用する場合はRB1768の基板を利用したデモ用ファイルを流用します。..\FreeRTOS.v.6.0.3\Demo\CORTEX_LPC1768_GCC_RedSuite\src少し古い情報(2010年3月)ですが、ここに最初にインストールした内容を書き記しています。その後の動作確認で、USB、TCP/IP等が動き始めました。私の作成しているデータロガープログラムは、タスクを下記の様に分配しています。10msモニタープログラムを使用して、各タスクの状況を観測し、表として整理すると下記のような情報が得られます。この例は、各タスクの最大負荷を想定して計測していません。従って、あくまでも参考としてご覧ください。50.0%タスクが占有している時間は下記の情報を参考にしてください。task_running_condition.pdf表で判るように、アプリケーションタスク(現在9個)以外に、システムが制御しているタスクが多く存在します。IDLEが重要で、CPUの占有率がどんなときにも100%を越えるわけにはいきませんので、IDLE時間がどのくらい残っているかはシステムの安定性に影響します。上記測定中は、USB経由でファイルをPCからMicro-SDへコピーしている場合で、コピー終了後はUSBタスクが23%から2%に減少しました。その分、IDLEが18%から23%に増加しています。現時点では、USBはPCからの要求をポーリング処理で監視し続けている為、占有率が増えていますが、割込み処理に移行出来ればもっと改善出来ると思います。残念ながら、検討したところかなりの変更が必要で落ち着いてから再チャレンジ(多分出来ない?)とします。<FreeRTOS提供のFunction使用例>アプリケーションで使用しているFunctionを紹介します。素人なので、FreeRTOSの提供する機能を充分に使いこなしていなくて、下記だけです。機能の詳細は、FreeRTOSのホームページでpdfファイルを購入する必要があります。Reference)です(英語のみ)。下記で確認出来るようにリアルタイムOSを簡単に使うには、それほど深い知識が無くても利用可能だと思いますので、pdfを購入して理解を深める前に先ずは使ってみることが重要だと思います。難しいのは、スタック管理を含むメモリ管理でしょう。私の経験では、プログラムが上手く動かない理由の多くがスタックの問題と、あるタスクがCPUを占有してリソースを解放しないでタスクがディスパッチ出来ずに動作不良を起こしていることが多いです。xTaskCreate今回のアプリケーションでは、初期化の際に下記の様にタスク生成をしています。xQueueCreateタスク間の同期を保っての情報伝達に使用するキューを生成します。今回は、下記のようにGPS情報、LCD表示、ADC情報用に3つのキューを用意しました。xQueueSendToBackキューにデータをセットして、発行します。portMAX_DELAY);}では、TASK6がADCデータの準備が出来たことを知らせています(TASK2のSDカード制御タスクが記録中あれば)。xQueueReceiveキューにデータがセットされるまで、タスクは待ち状態となります。logging}となって、データが送出されてくるまで待っています。vTaskDelay指定した時間、タスクの制御が中断されます。ring_rx2.dt_got;}の場合は、リングバッファにデータが入っていない時に、1ms毎にタスクは制御を中断して、他のタスクを実行出来ることになる。vTaskDelayUntilvTaskDelayとの違いも含め、ここに書いた内容を参照ください。プログラム構成ソースファイル構成オリジナルファイル<ソースファイル構成>現時点(2010年10月10日)で、私の作成しているデータロガーで使用しているファイルの構成を下記に示します。現在も開発完了していませんので、今後も変更する予定です。生成されるObjectが格納されます。docは関係資料が入っていますが、ソフトウェア開発には関係しませんより詳しい内容は、このファイルリストを参照ください。<オリジナルファイル>下記の多くのプログラムを直接もしくは間接的に参考にさせていただきました。ソース以外の関係情報に辿りつくことが出来ませんでした。以下のライセンス・ポリシーの下で公開されています。FatFsモジュールはフリー・ソフトウェアであり、また無保証です。用途に制限はありません。ソース・コードを再配布するときは、上記の著作権表示を保持しなければなりません。NXPのアプリケーションノートAN10916で紹介されていて、使用し始めましたが、まさか日本人の方が作成したソフトウェアとは、2009年暮れまで知りませんでした。このGPSデータロガーはすごいです。2005年頃、Webで入手。コメントを見つけ出せなせんでしたいくつかの事例ROM&RAM使用方法MONプログラムUARTプログラムLPCUSB関連MicroSD(ファイル)プログラムuIP関連プログラムGPSプログラムADCプログラムRTCプログラムLCDプログラム<ROM&RAM使用方法>LPC1768には下記の様に、ROMとRAMがアサインされています。0x20083fff問題は、RAMが合計64KBあるのも関わらず連続していないことです。従って、64KBのRAMと言っても実際には使いずらい仕様になっており、最初使い始めた時には戸惑いました。言っても今更ユーザーの立場で動的に配置変更出来ませんので、現実を直視して下記の作業をしました。Cソースファイル内で下記の様に宣言します。RAMの割付けにセクション指定します。__attribute__((section(".ex_ram2")));Makeファイル(rtos_lpc1768_Debug.ld)では、下記のように設定し、先のセクション指定した場所を指定します。}この設定で、0x20080000からからのRAM領域16KBを色々な目的に使うことが出来ます。初めに、0x2007c000からの16KBも使おうとしたのですが、ここは既にLAN制御で下記の様な宣言で使っていました。uIPを利用してLAN制御する場合には、0x2007c000からは使用しないでください。EthDev_LPC17xx.h内には、0x2007c00からの使用宣言が書かれています。この宣言ではRAM配置にリンカが関与しませんので、*.mapファイルを見ても使用の有無が判りません。これに絡んだBugで悩みました。24Bなどから、24+24+16+8+(1536*i)だけ、使用されるようです。emac.c内でETH_NUM_BUFFERSに設定されていますので、2+3+1=6となり、RAM合計=24+24+16+8+(1536*6)=9288Bが使用されています。16KBの領域で約9KBですから、(上記計算が間違ってなく、且つ他に使っていなければ)残り7KBはまだ上手く使えば利用可能です。現時点での、データロガーでのROM/RAM使用状況は下記の様な状況です。28.7%<MONプログラム>今回、一つのタスクとしてモニタープログラムを動作させて利用しています。PCとはシリアル通信をしていますが、1UARTと2USBのどちらかを選択できるようにしています(別項UARTとUSBを参照)。使用例を下記に示します。現在対応しているコマンドを下記に示します。オリジナルのソースファイルに入っていたものをそのまま使用しています。FatFsのリエントラント機能を使用していないために、データロガーとして使用中にコマンドを実行するとフリーズしてしまいます。従って、ほとんど使用していません。16:24)を参考にしています。モニタープログラムに使用するソースファイルを下記に示します。monitor.c<UARTプログラム>シリアル通信に使用するモジュールは下記です。ring.h現在は、下記のように設定しています。UART2は、モニタープログラム(上記のようにPCとの通信)用に使っています。ボーレートは、115200baudの目標で実際には、116062baud(誤差+0.74%)となっています。UART3は、GPSのデータ受信と初期設定値送信に使用しています。ボーレートは、4800baudの目標に対して、4818baud(誤差+0.38%)です。UART2の送受信関係を下記に示します。受信は、割込みを使用してリングバッファにデータを蓄えていますが、送信はバッファなしでそのまま書き込んでいます。LPC1768のUARTには、16バイトのFIFOが付いており、送信には割込みなしで対応しても大きな問題はないでしょう。UART3はGPSの受信が主で送信はコマンドのみなので、このままで良いでしょうが、UART2は、送信するデータ量が多いので、ボーレートを遅くする場合には、下記のようにプログラムを変えたほうが良いかもしれません。stop))ですから、下記のようにします。115200baudであれば、1バイト送信は86.8μsですのでポーリングで充分でしょう。0xFF;}受信の場合にはデータが無い時には、FreeRTOSに制御を渡しています。ring_rx2.dt_got;}UART3も同様な構造で、受信用にリングバッファを用意しています。リングバッファに対する操作は、下記の図のようになっています。<LPCUSB関連>LPCUSBで出来ること私が、現時点(2010年10月16日)で動作確認したのは、下記の二つのクラスです。Class)CDCは、USB経由の仮想COMとしてPCとのシリアル通信が可能です。今回はモニタープログラムの入出力をUART2経由かこの仮想COM経由かを切り替えて使っています。MSCは、PCから見たときにUSBメモリとして、Micro-SDカードの入出力を制御します。具体的には、FreeRTOSConfig.hの中で、下記のように選択します。この設定で、USBはCDCとなります。0仮想COMでモニターを起動した画面と、コンパイルし直してMSCとしてMicro-SDをPCから覗けるようにした時の画面です。USBをCDCに設定して、仮想COMとしてPCへ接続。TermでCOM9を開けてモニタープログラムとの接続を設定する。TermでUARTの状況を確認して、UART2が使われていないことを確認。注意点:FreeRTOSのデモファイルには、元々USB_CDC.cが入っていました。stackをダウンロードしてUSB部分を再構築しました。その際に、CDC関連のソースファイルは、main_serial.cの名称になっていました。現在は、このファイルを修正して使っています。従って、今後の説明には両方のファイル名が出てきますので注意願います。サンプルの原型は、下記のようになっていました。0;}当初は、mon()の入出力に、上記のVCOM_getchar()とVCOM_putchar()をそのまま使おうとしましたが、使えませんでした。理由は、VCOM_getchar()が下記のようにデータ受信(PCからLPC1768)の際にキューを待ってしまい。制御が戻ってこない点です。c;}更に、USBのタスクとMONタスクが別々に動作しているので、両タスク間でのデータやり取りの方法を考えなければなりません。そこで、下記の様にリングバッファを多用して各制御を同期させました。リングバッファを3つ用意して対応しました。仮想COMということで直接関係ありませんが、プログラムはuart.c内に入れました。VCOM_getchar()とVCOM_putchar()を基準に、二つのタスクの同期をuart.cの中で吸収しています。monitor.c内(上記赤の四角部分)で、UART2と仮想COMを条件によって使い分けています。下記は、xputs()の例です。*)str);#endif}更に、VCOM_getchar()が制御を戻さない問題も、下記のようにUSB_ChkESnd()を追加して解決しています。(&ring_txu);}MSCの設定USB経由で、PCからLPC1768システム上のMicro-SDカードをマスストレージと認識させることが目標です。プログラムのメインとなるのは、main_msc.cのファイルです。このプログラムを解析していくと下記の様な関係が判ります。小さくて見づらいと思いますので、pdfファイルがリンクしてあります。表の中で判りづらいところがありますので、下記コメントも参照ください。この表は、全てのファンクションを網羅することを目的としていません。作表の目的は、SDカードを制御しているFatFsとどのように共存させるかを目的としています。結果として、オレンジ色のファンクションがFatFsと関係するモジュールとなりました。BlockDevInit()、BlockDevGetSize()、BlockDevWrite()、BlockDevRead()の各ファンクションで全てblockdev_sd.c内です。結果として、黄色のファンクション(Check_Idle())を新規作成して、usbhw_lpc.c内に収めました。USBHwISR()には、階層化表現として何も書かれていませんが、色々な機能が登録されています。この部分は別項を参照ください。'x'が書かれているのは、FatFSとのインターフェイス解析の目的では、それ以上の階層化解析は不要とした結果です。FatFsモジュールとの(実際には、FatFsとではなく、よりハードウェアに近いドライバーとの)インターフェイスを作るために、blockdev_sd.cの中で修正した内容を下記に示します。disk_read()があるので、それを呼び出し..\fat_sd\lpc17xx_sd.c内既存USBHwISR()の機能CDCの場合には、USBHwISR()は割込み処理として呼び出されます。}}これに対して、MSCでは、下記のように呼び出しています。}}SPI経由で512バイト単位の読み書きもあり、割込み処理では対応できないとの判断だと思います。FreeRTOSの機能を使って割込みとの協調で対応するのが良いと思います。USBHwISR内では、様々な割込み要因で機能分岐しています。最上位のものは、下記の3つです。(USBDevIntSt)"をポーリングして素早い対応をする必要があります。今回は、Check_Idle()を新規作成して、割込み要因の有無を判定して要因が無ければ1msの待ちをタスクに与えています。この対応で、USBタスクのCPU占有率を下げることが出来ました。現時点でいくつかの問題点があります。CDC使用時、USBケーブルをPCに接続したまま立ち上げると、その後PCに仮想COMとして認識してもらえません。Termを立ち上げています。MSC使用時、8GBメモリが認識されません。一様解決済(下記MicroSDを参照ください)カードのサイズを返す関数のオーバーフローが原因と思われます。プログラム修正が必要です。8GBのMicro-SDでもFatFsがデータロガーとして書き込む動作には支障が出ていません。<MicroSD(ファイル)プログラム>SDカード(MicroSD)の制御プログラムは、下記のファイルにて構成されています。lpc17xx_spi.hChaNさん提供のソースファイルに対して、SPI経由のSDカード制御プログラムを下位レイヤ・インターフェイスを提供する必要があります。今回は、NXP提供のサンプルプログラムを修正して使用させていただきました。ハードウェアとしては、下記SPIを利用しています。p14速度は、まだ改良すべき課題です。現状は、537,400,028バイトの1つのファイルをPCからUSB経由でMicroSDに書き込んだところ45分かかった。(218KB/sec)となった。BSCRA26U2にて同じファイルを転送すると、30秒で完了しました。17MB/SEC)512バイト単位でのDMA転送が出来そうですが、これも課題ですが当分(永遠に)解決できそうにありません。ファイルシステムのBUG修正2010年10月17日時点で、”MSC使用時、8GBメモリが認識されません”と書きましたが問題点がはっきりしたので、現時点(11月6日)での対応内容を残します。問題点4GBのMicroSDを装備して、USB経由でPCと接続すると正しく認識されるが、8GBではPCから正しく認識されずエクスプローラでドライブ内部を観ることが出来ない。SDCFG;となっており、sizeが32bitで表現している点です。これでは、8GBではオーバーフローしてしまいます。(4バイトでは赤字部分がオーバーフローしてしまう)64bitでsizeを構成する必要があります。そこで下記変更を加えました。longやU32などが混在していますが、流用元の流儀をあまり変えないようにしている為です。FreeRTOSの形式(portBASE_TYPEなど)やDDWORDの表現も入っていて、全体としてはかなり混沌としています。dwDevSize;これで直ったと思ったのですが、下記の様な表示になります。修正後に(私のPCの場合には)F:ドライブとして正しく認識されるようになりましたが、モニタープログラムで"fl"コマンドを実行すると未だ正しく表示されません。追加修正した部分を下記に示します。disk_size_inf();}これでようやく解決しました。XP)の認識容量とモニタープログラムの容量表示が微妙に違う!?<uIP関連プログラム>内容検討中<GPSプログラム>内容検討中<ADCプログラム>内容検討中<RTCプログラム>内容検討中<LCDプログラム>。