« FreeRTOSのウェブサーバーが動いた | トップページ | FreeRTOSでユーザー割り込み環境が動いた »

2011年5月27日 (金)

雑誌付録ARM基板でSDカードとRTCを動かす

失礼しました。プライオリティが逆でした(5/20/2011)
 このOS、プリエンティティブじゃないなどと言っていたが、こちらの間違いだった。FreeRTOSでのタスクプライオリティは数字が大きいほど優先度が高いのだ。uIPは他のタスクより優先度が高いとばかり思っていたので(実際は普通より低いところで動いていた)、UARTの数字をこれより大きくして、さらに優先度を上げてしまっていた。これではUARTがループウェイトすると、uIPにはCPUが渡らない。同一プライオリティの時しかラウンドロビンでCPUは廻らない。

 設定を逆にしたら、めでたくUARTでどれだけCPUを喰っていても、Webサーバーの処理は遅れないようになった。UARTはセマフォーを使った割り込み待ちを考えていたが、その必要もなくなった。やれやれ、どうも済みませんでした。

S_p5193932

 コマンドシェルは一番低いプライオリティにしておけば、他のタスクの邪魔をしない。ただ、LCDのタスク状態表示には、何かエラーがでている。同じプライオリティのタスクがどこかにあるからだろうか、良くわからない。まだ、このあたりは手探り状態だ。

 とにかく、いつものようにPCのUART端末からモニターとして動くよう、コマンドプロンプトのロジックを作る。まずはエコーバックだ。キーボードから入れたデータをリターンキーで送り返すだけだが、これは、このあと入力データ(コマンド)を解析して各種の作業を行うコマンドシェルになる。

 この辺の開発は、AVRなどと同じなので簡単にできる。ファームを書き直してテストする。うむ、ちゃんとエコーバックされてくる。同時にLEDが点滅し、Webサーバーが順調に2秒ごとにHTTPデータを送り続ける。いやあ、だいぶコンピューターらしくなってきたな。

LPC2388の割り込み環境の設定は難しい(5/23/2011)
 プロンプトまでは快調だったが、その後のFreeRTOSのテストベンチの作業ははかどらない。本来のコマンドプロンプトは、UARTの受信割り込みで処理を開始するのが筋だ。タスクのプライオリティで誤魔化すのは邪道である。しかしUARTの割り込み関数がうまく入らない。

 LPC2388の割り込み関数の指定が良くわからない。現在のソースには、割り込みを使っているUARTが、Buffered UARTとして既にコードが用意されているが、これを動かそうとすると(#ifdefで入れ替わる)、コンパイルエラーになる。

 どうもコンパイラーによって割り込み関数の定義が違うようなのだ。環境変数の__GNUC__を定義すると、割り込みの定義のところの__irqオプションが消えるのでビルドは通るが、このファームではFreeRTOSそのものが全く動かない。他に影響がでているようだ。

 あちこち探し回るが、ソースごとに設定の方法が違っていてどうして良いのかわからない。ChaNさんの雑誌のソースもあるので、ここでの割り込みを調べるが、ここは肝腎なところはすべてアセンブラーで実装されており、残念ながら参考にならない。

 結局、割り込みを使ったUARTは断念することにした。ウェブにあったように、UART受信バッファーを10ms程度のウェイト(OSにCPUを返す)を入れて覗く方式(ポーリング方式)で妥協することにする。UART入力は端末のキーボードからだけなのでこれで何の問題もないのだけれど、何となく気に入らない。それでもこれでLCDでのOSエラーはなくなった。

 同じARMでもNXPの開発環境は、I/Oレジスターのヘッダーファイルが用意されているだけで、アセンブラーのようにせっせと設定していく方法である。STMに較べると遅れているようだ。それでmbedのクラウドIDE方式で一気に飛躍しようとしているのだろうか。そういえばまだmbedは、LEDチカチカを確認しただけで、全く先に進んでいない。こいつはPHY層も含めたイーサネットインターフェースがあるらしいので早くいじってみたいのだが、現在はおあづけである。

LPC2388でSDカードを動かす(5/24/11)
 割り込み環境が思ったように導入できず、少し手詰まりになったので、気分を換えてLAN基板の横にスペースをあけて用意してあったSDカードスロットの実装を始めることにした。アートワークは、これまでの作業の合間に少しづつ描いていて既に完成している。

S_p5273949

 思ったより早くできた。まあ、プルアップ抵抗を5本ほどつなぐだけだけだから大した作業ではない。このあたりのハンダ付けは、汎用基板、プリント基板あわせて10回以上やっている。手馴れた作業である。回路図は、雑誌(インターフェース2009年6月号)記事を使う。もっとも、定数を含めてこれまでに紹介された回路図と殆ど変更はない。MCIモジュール(SDモード4ビットバス)が動くための結線部分が違うだけだ。

 これでLPC2388のLAN&SDカード基板(雑誌付録の拡張基板とほぼ同じ仕様)のハード工作は大体予定通り終わった。SDカードの動作テストを早くやりたいのだが、現在のFreeRTOSのテストベンチに、FatFSを組み込むのは大変だ。

 ねむいさんのFreeRTOS_V6のMakeFileにはFatFSを入れようとした痕跡が残っているが、実際のリソースは入っていない。単に1タスクのファイルシステムだけなら簡単そうだが、FreeRTOSの標準ファイルシステムにするのは、結構大変なはずだ(FatFSそのものはリエントラントなので十分対応可能だが)。

 どうしようか迷ったが、FreeRTOSの1タスクとして入れるのも先に延ばし、雑誌記事のChaNさんの単独システムを先にいれて、SDカード周りの動作だけでも確認することにした(慎重と言うか臆病である)。雑誌のダウンロードサイトから、2009年6月号のソース一式を頂く。以前にご本人のページからダウンロードしてあったソースとFatFSの部分は大きく変わっていないようだ。

 コンパイラーは、WINARMのarm-elf-gccだったが、うちのWINARM環境は自信がないので、いつものようにCodeSourceryのarm-none-eabiに換える。OLED液晶の部分はついていなくても動くと言うことなので、ソースには手を入れない。

 ビルドはリンクしているライブラリもないので、あっさりNo Errorで終了した。しかし、ファーム書き込みは時間がかかる。LFN用の64KBものコードブックをフラッシュに書いているからだ。遅いはずだ。少し待って書き込みは終了した。

 早速、動かしてみる。うんともすんとも言わない。そういえばREADME.TXTにOLEDかファイルモニターの切り替えは、ESCキーを押せとあった。シリアルの速度を合わさないとキーを押してもESCの区別がつかないはずだ。230Kbpsに合わせて、ESCを押す、よーし、Monitorの開始を知らせるオープニングメッセージが出た。手近のSDカードをさしてテスト。うーむ、Disk Errorだ。

 ディスクが入っていないことを示すエラーコードである。さて、動かないとなると最初から腰をすえて調べなければならない。ファームはまず間違いがないだろう。とすると、ハードだが、昔に較べると配線技術は、格段に向上していて最近は配線ミスが殆どない。あっても事前にチェックできている。誤配線よりもっと簡単なところのミスを疑う。

 ここに入っているファームは、ソースコードを見るとSDカードの所在や、ライトプロテクトまでチェックしているフルバージョンだ。まず、これが動いているかどうか調べてみよう。このあたりはSDカードを始めて動かそうとしたとき、散々苦労したところだ。

 CD(カード検出)は負論理なので、このピンはカードを入れたときグランドに落ちていないといけない。テスターで測る。あれえ、グランドになっていない。ややや、このピンはスロット筐体とはつながってる。何だと筐体とグランドピンは浮いているのか。何と、何と、ここは明示的につながないと駄目なのだ。これまでの実装は、このあたりを無視していたことが多いので、分離しているのに気がつかなかった(スロットは秋月で買ったノーブランドの小型のもの)。

Lpc2388_fatfs

 これで動くのではという淡い期待に胸を膨らませながら、筐体とグランドピンをハンダ付けしてテストを再開する。こんなもので動けば楽なもんだけど、そうはうまくいかないだろうな。

 電源を入れる。モニターを出す。初期化コマンドdiを入れる。エラーなし。おっ、動いたか。ファイルリストを出すコマンドを入れる。やった。やりました。お馴染みのファイル名が並んだリストがUARTに並んだ。いやあ、ここも、配線間違いなし。気分が明るい。

 アクセス速度を測る。雑誌の記事によれば、データアクセスは、LPC2388のMCIモジュールを使ったSDカード4ビットバスで、ぶっちぎりの早さ(ねむいさん)だそうだ。測ってみた。すごい。どのSDカードも64KBくらいなら、4MB/sec近辺という猛烈な早さだ。これなら動画も送れそうだ。これは楽しみになってきた。

 このFatFSは、FreeRTOSで動かすという大仕事が残っているが、LPC2388のLAN&SDカード基板はこれで完成した。これまでにかかった費用を計算してみる。PHY層チップ(DP83848C)は1枚こわしたので2枚として¥1200(失敗しなければ¥600)、ピッチ変換基板(アイテムラボ)1ヶ¥180、べたアース基板(サンハヤト)¥250、モジュラージャック(秋月パルストランスLED付き)¥300、SDカードスロット¥150、50Mhzオシレーター¥260、CRは全部で¥100するかしないか、ヘッダーピンソケット¥80くらい(この辺は全て手持ち)。あれこれ合わせて¥2,520。

S_p5273941

 そもそものきっかけ、法外な価格で買うのを反発した雑誌のタイアップLAN&SDカード拡張基板は¥6800だったから、これのほぼ1/3というところか。自分の作業工賃をどう考えるか? DigiKeyのゲタに買ったmbedの¥5400はどう考えるかって? え、まあ、こういうことは聞かないお約束と言うことで。そうかmbedも動かしてやらないといけないな。

FreeRTOSにRTCを入れる(5/26/2011)
 雑誌付録ARM基板LPC2388のLAN&SDカード拡張基板が両方ともうまく動いたので意気が上がっている。矢でも鉄砲でも持ってこいくらいの状態である。調子に乗って、FatFSをFreeRTOSで動かす前に、残っていた課題を片付けることにする。LPC2388のRTC(リアルタイムクロック)機能である。

 この雑誌付録基板は、LPC2388が、バッテリーバックアップのできるRTCを持っているのに、そのバックアップ電源Vbatピンを基板上でVccにつないでしまっており、せっかくの機能が台無しになっている。

 これでは何のためのRTCかわからないと思っていたら、ChaNさんが動画サイトで器用に、0.5ミリピッチのICの足を切ってVbatを独立させている工作を見て、感嘆した。

 当研究所でも、これに刺激され、早くにバッテリーバックアップに挑戦して成功している。しかし、電池をつないだだけで、まだ動くかどうかの確認をしていない。ここは是非試しておきたいところだ。動けば、FatFSのタイムスタンプにも使える。

 今動いているFreeRTOSのソースチェーンには何故かrtc.cは入っているが、どこにもこれを動かすコードは入っていない。ねむいさんのサイトを見てみると、FreeRTOSではなく、単独で実装されているようだ。とりあえず有難くソースを頂く。

 FreeRTOS上では動かなかったのだろうか。ソースを調べていく。そうでもないらしい。ただ、このRTCのコード(rtc_support.cとmain.c)には、割り込みルーチンが入っていて、簡単には入りそうにない。FreeRTOS上の割り込み環境は、結構難しく、UARTの割り込みを使ったコードはうまくビルドできないであきらめている。

 __irqというオプションが割込みハンドラー宣言に入っていて、ここでコンパイルエラーを起こす。ウェブの情報によれば、これをはずして、__attribute__ (((interrupt("IRQ")) に換えると良いというので、そうすると今度は、このオプションはthumbモードではサポートしないとコンパイラーに怒られる。ねむいさんのコードの割り込みにも__irqオプションが入っている。ねむいさんにお助けメールを出したが、忙しいらしく返事は前のようにすぐには戻ってこない。

 出来ないとなると悔しくて余計意地になるのが性分である。色々ウェブをさまよう。解決策は見当たらない。しかし落ち着いて考えてみると、RTCの機能はハードなので、何も割り込みを使わなければ動かないというものではない。では何故割り込みを使っているかというと、1秒ごとにディスプレイに出すためだけのようである。

 ここで閃いた。1秒ごとなら何も割り込みを使う必要ない。OSの元で動いているのだ、別タスクを立ち上げて、1秒ごとにRTCを調べれば良いはずだ。そうか、割り込みを使わないでも出来そうだ。

 思い立った時の手の早さには自信がある。rtc_support.cの割り込み部分を全部とり、見よう見まねで、FreeRTOSの新しいRTCタスクを新設する。このタスクはRTCを初期化して動かした後は、1秒の待ちを入れてUARTに時間を表示する。目覚ましのようなタイマーだってこれで作ろうと思えば作れる。OSにだいぶ慣れてきた。

Lpc2388_rtc

 喜び勇んでビルド。よーし、No Errorだ。ファームを書き込む。UARTを立ち上げる。おおお、初期設定をうながすメッセージがでたぞ。年月日を入れていく。やった。動いた。RTCが時間を表示し始めた。ありゃ、止まっちまった。どうもprintfが大きすぎてスタックがあふれたような止まり方だ。ウェブも止まって暴走している。

 年月日時分秒すべてを出す表示を縮めて再トライ。ついでにタスクのスタックサイズをUARTと同じに広げる。よーし、順調に時間が表示されてきた。バックアップは大丈夫か。電源を切って暫くしてからもういちど動かす。良いぞ、バックアップされている。ほぼ2年ぶりの確認である。いやいや、これで32.767Khzの時計用クリスタルと、コイン電池の顔が立った。

|

« FreeRTOSのウェブサーバーが動いた | トップページ | FreeRTOSでユーザー割り込み環境が動いた »

電子工作」カテゴリの記事

ARM」カテゴリの記事

FreeRTOS」カテゴリの記事

コメント

問い合わせに、親切にお答えいただきありがとうございました。メールで既にご報告していますが、その後の話と、こういうやりとりは他の方にも参考になると思いますので、ここで報告することにします。

RTCHandlerでコンパイル不調になる件、仰せの通りの#includeでエラーはなくなりました。しかし、依然として、RTCの割り込みは通りません。調べたところでは、RTCIsrInit()のinstall_irqでベクターテーブルに書き込んだ時点で、何かを壊すらしくここでcrashしています。

不思議なことに、ねむいさんのFrerRTOSソースにある、UARTでは、同じように割り込みルーチンをenableにすると(ここも同じコンパイルエラーだった)、UARTだけがハングし、他(Webサーバー、LED点滅など)は無事動きます。

いずれにしても、FreeRTOSの問題というより、そもそもStartUpルーチンが違うので、他で動くソースを持ってきても、何らかの不整合でおかしくなると思われます。

FreeRTOSで、割り込みが動いているサンプルがあれば、一番良いのですが、見つけられていません。

あの、MartinThomas氏の割り込み付きUARTは動いていたのでしょうかね。コメントアウトしてあることを見るとFreeRTOSでは動いていなかったのではないかと推測していますが。

投稿: がた老 | 2011年5月30日 (月) 14時31分

ねむいです。こんにちは。

hotmailが調子悪いみたいでメールがエラーで返ってきてしまったのに
気づいたのでこちらで返信を代えさせていただきます。
すみません、気づくの遅れました。

がた老さんの推察の通り、"RTCHandler(void) __irq"の部分で引っかかる
のはGCCとほか開発環境の差異を吸収するために設けられたマクロ"__irq"の
定義がされていないからです。プロジェクト内ディレクトリの./lib/Common/inc
にある"irq.h"に__irqのマクロが定義されていますので、irq.hをインクル
ードしてやるとコンパイルが通ると思います。

また、私のブログの"おきば"にあるLPC2388向けのTFT-LCD制御プログラムで
はFatFsとRTCをアレンジし直し連携させていますので参考にしてください。
むしろこちらの方が参考になるかと思います。

投稿: ねむい | 2011年5月28日 (土) 15時36分

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック


この記事へのトラックバック一覧です: 雑誌付録ARM基板でSDカードとRTCを動かす:

« FreeRTOSのウェブサーバーが動いた | トップページ | FreeRTOSでユーザー割り込み環境が動いた »