FreeRTOSマルチタスク対応UARTとガイガーカウンターキット
LCDをはずしてもFreeRTOSが動くようにする。ロジアナ大活躍(6/28/2011)
FreeROSのセマフォーが解決して、ちょっと一息ついた。たいしたことでもないものに、自分で自分を追い込んで解決に血道を上げる。確かに、前記事で頂いたコメントの通り、自虐趣味かもしれない(少しむきになって否定したけれど)。しかし、単調な日常生活にこれほどドラマを作ってくれる趣味は、ちょっと他に見あたらない。テニスやスキーなどにもドラマはあるが、ドラマを作るためには、多大な精進と肉体を苛めるトレーニングが要求される(これは自虐とは言わない)。
電子工作の場合は、こだわるものは目の前に無尽蔵に転がっている。盛んに研究されているプログラムライターなどもそうだ。別のライターで書いたからといってフラッシュに2倍のサイズが書き込めるわけではない。書き込みが速くなるといっても、精々数十キロのフラッシュROMにどれだけ早く書けたところでたかが知れている。しかし、みなさんのこだわりようは、尋常ではない。余程面白いに違いない。
それはともかく、当面解決すべき課題がなくなり、体の中にぽっかり空き地が出来たようだ。これまでのメモを取り出して、やろうとしていたことを整理し、優先順位をつけながら次のプロジェクトの準備をぼちぼち進め始めた。
本来なら、前にも書いたようにUARTのマルチタスク対応なのだが、どうも気分が乗らない。こういうときは手を動かしているのが一番だ。ブレッドボードに臨時に設置していたFreeRTOS用のI2C LCDを次のプロジェクトに備えて外す作業を始めた。
元のLPCMプレーヤー(テストベンチとしてブレッドボードに常駐)の方に戻し、LCDなしでARM(LPC2388)基板のFreeRTOSを動かそうとした。これが動かない。ふーむ、LPCMプレーヤーはLCDをはずしていても動いていたのに、何故、ARMでは動かない?
ソースを見て原因はすぐわかった。I2Cの初期化で、LCDからレスポンスが返ってくるのをループで待ち続けている。これは一番確実な方法だけれど、ここはLCDがなくても事情を理解して先に行って欲しい。いわゆるソフトウエアのRobustness(堅牢さ)というやつである。
必要とされる初期化待ち時間を仕様(300ms)の倍くらいにして、このループをはずす。あれえ、これでも動かない。どうしてだ。傍らを見ると、これまでの解析に使っていたロジックアナライザーが出たままになっているのに気づいた。そうだ、このロジアナ(ZeroPlus 16128)にはI2Cのプロトコルアナライザーがついているはずだが、まだ使ったことがない。ちょうど良い機会なのでロジアナでI2Cの波形を見てみることにした。
うーむ、待ち時間を倍にしても、レディにならずにスタックしている。ループを使った元の状態に戻す。何ということだ。10回ほどリトライした後レディになっているが、その時間は増やした待ち時間より短いではないか。
ちょっと待て、クロックはどうだ。おやあ、2.2μsしかない。このLCDのI2C最大クロックは400khz(2.5μs)のはずだ。これじゃあ速度違反だ。4μsまで下げる(250khz)。
なんだなんだ。これでも10回近くリトライし続ける。待っているだけではレディにならないのは同じ。おかしいな。元のAVRのLPCMプレーヤーのI2Cをついでにロジアナで見てみる。これは全く問題なくリトライせずに一回の初期化でACKを返している。
うーむ、どうしてだ。おかしい、ARMでは何故一回でOKにならない。同じ待ち時間なのに、と、さらに調べそうになって、先に進むのをかろうじてやめた。今自分が何をやっているかに気付いた。これはこれくらいにしておこう。セマフォーに続き、本筋に関係のないことに首をつっこみすぎだ。
愚直に、ARMのI2Cに有限回ループ処理を加えて戦線を撤収した(20回リトライして、動かなければLCDタスクをサスペンド)。これでARM基板のFreeRTOSはLCDなしでも動くようになった。
それにしても、大枚4万近くをはたいて導入したこのロジックアナライザー(ZeroPlus 16128)が大活躍だ。I2Cのデータの解析(スタートコンディションやデータ解析)がプロトコルアナライザーで大幅に楽になるだけでなく。宣伝にもあるデータ圧縮が素晴らしい。
電源をトリガーにしても、LCDがオープニングメッセージを出すところまでのデータが取れる。この間2秒以上離れているが、データ圧縮のお陰でメッセージデータが記録出来ている。
サンプリングクロックを10Mhzとするとメモリが128KBなので、普通にデータをとっていれば、2チャンネル(I2C)だけとしても、60msの間しかデータが取れないところである。ロジアナは事象の起きているところを正確に把握することが、とても難しいのだが(膨大な期間があるので)、こういう風に長期間測定できるとその時点の特定が簡単になり解析が非常に楽になる。
FreeRTOSのキューでUARTを動かす(7/2/2011)
道草を食っているときではない。FreeRTOSの残された課題を早く解決しておこう。まずは、UART環境の整備だ。これは、これからマルチタスクでロボットなどを動かして行く時の強力なデバッグツールになる。
これまでの記事にあるように、FreeRTOSのUARTを含めた割り込み環境はRTCと合わせ、やっとのことで何時間動かしてもフリーズしない安定した状況になっている。しかし、UARTそのものはまだ、リエントラントになっていない。誰でも(どのタスクでも)、任意にUARTに送信リクエストを送っても正しくメッセージが出るようにはなっていない。
マルチタスクOSであるFreeRTOSのUARTとしては、これはまずい。データが化けるくらいならともかく、下手をすると簡単にフリーズしてしまう。デバッグツールには使えない。
OSの持っている機能、キューでデータをやりとりすれば良いということはわかっているが、このあたりはソースリストをいじって簡単に解決できるレベルではない。もう少し抽象的なレベルに上げて検討する必要がある。
実装の対象は、ChaNさんのUARTソースである。抽象レベルではわかっていても、このFIFO、入出力バッファー付きのUARTを、どうキュー仕立てのマルチタスク対応UARTにすれば良いのか具体的な手順が見つからない。
うまい方法が見つからず、何枚もメモシートを書き潰していて、あるとき、突然気がついた。良く考えて見たら、ひとつのUARTの受信ポートに複数のタスクが集まって、データを取り合うことは現実にあり得ない。つまり競合を心配する必要がない。
これまでは、送受信を対称的に考え、両方を同じ仕様で作ろうとあれこれ考えていた。今度のUARTは送受信ともハードのFIFO、ユーザーのバッファーと、2段の非同期プロセスが存在する。送信は、検討の初期から別タスクを起こして処理することを考えていたが、どうしても受信プロセスがうまくいかなかった。
受信は難しく考える必要がない。単に受信割り込みでデータをキューに送るだけで、ユーザー関数はそれを待てば良いのである。UARTの受信の速度は、CPUのキューの処理に較べれば圧倒的に遅い。バッファーも必要ないくらいだ。
送信は、ユーザー関数をキューで受けて、別の常駐タスクを作り、ここで実際のUARTハードへの送り込みをキューイベントをトリガーとして行う。printfがリエントラントでないので、これに対しては、Mutexなどでガードしてやる必要があるが、こうしておけば複数のタスクからの送信要求は安全に処理される。
コンセプトが明確になったので、コーディングにとりかかる。ユーザー向けの送受信関数は、キューステートメント1行のえらい簡単な関数になった。UARTタスクからMonitorタスクを分離し(これが今後のモニターコマンド処理を担う)、UARTタスクはハードの初期化と、送信キューの送出のみに絞る。
テストしてみる。よーし、動いた。ロジアナで動作を確認する。ふーむ、Mutexを使ってprintfをガードしたけれど、このアプリでは重なることはまずなさそうだ。Mutexもはずす。Mutexだけで、フラッシュは560バイトも使っている。
さて、今のところFreeRTOSのマルチタスク対応UARTは長時間テストを続けて、順調に動作している。次は、FatFSか。まずシングルタスク用に入れてみよう。
FreeRTOSマルチタスク対応UARTのソースは以下に置きます。やり方は、これまでの記事を見てください。
SparkFunのガイガーカウンターキット到着(7/4/2011)
そうこうするうちに、4月の末に発注したSparkFunのガイガーカウンターキットが、遂に届いた。入荷は6月第二週の予定であったが、結局6月には届かず、ちょうど2ヶ月かかったことになる。
6月第二週の情報は、SparkFunの商品ページのコメント欄で得た。このガイガーカウンターキットのコメントには100を越す色々なメッセージが飛び交っている。このコメント欄に、6月にはいってすぐ、「6/1に出荷開始!」というコメントを入れた人がいたので、心待ちにしていたのだが、一向にその気配はなかった。
すでに代金は、5月末に、クレジットカードの支払いで引き落とされている。段々心穏やかではなくなってきた。それでもFreeRTOSのトラブルシューティングに熱中していて暫く忘れていた。
トラブルが解決して、一息ついてネットをぶらぶらしていたら、日本のブログでSparkFunのガイガーカウンターキットの制作を報告しているところを見つけた。この人は3ヶ月待たされたらしい。
やっと外国である日本向けの出荷が始まったのかな。久しぶりにSparkFunのページにログインして自分のOrder Historyを見てみる。おお、NewOderがin delivary に換わった!1日もしないうちに、ステイタスはshippedに換わり、めでたく品物は日本に向けて出発したようである。
4日ほどで品物が届いた。初めてのSparkFunからの荷物である。記念撮影をしておく。中から小さな赤いSparkFunの箱が出てきた。おやあ、全部配線が済んでいる。何だキットというから半完成品かと思ったら、全部の配線が終わっている。ガイガー管は、配線を束ねるタイラップで基板に固定され、グランド側は、線を巻きつけているだけだ。このあたりの工作が難しいので全部組み立ててあるのだろうか(外国人は、日本人に較べると驚くほど不器用である)。
取る物もとりあえず、USBジャックを付けて電源を入れる。赤いLEDが煌々と点いて、その隣の緑のLEDが一瞬点いた。シリアル端末を立ち上げて様子を見る。始めは何の反応もなし。暫くして、緑LEDの瞬きとともに端末に01と数字が出た。おお、動いているようだ。
CPUチップの横にあるのがISPピンらしい。SparkFunのサイトに行って、最新版のファームをダウンロードする。ソースの中を調べる。うーむ、このソースでは動いていない。サイトの記事を見ると、どうもV12という放射線量の数を乱数に使うプログラムが送られてきたキットには入っているようだ。その証拠に、端末の0や1が増えている。0はパルス間隔が前の時より短かったとき、1は長かったときを表すようだ。
これだけでは、全くガイガーカウンターとしては用をなさない。最新ファーム(V13)も似たようなもので、1秒間の発生したパルスの数を延々と出しているだけだ。まあ、これは覚悟していた。ISPピンが出ているのでファームの書き換えに支障はない。
電源LEDを点滅に換えたりファームを書き換えたり(7/6/2011)
このガイガーカウンターキットは、USBを通したUART(FT232RLがついている)が唯一のインターフェースで、パルスが来るとLEDが一瞬点くが、音が出るわけでもない。これをポータブルにするのは、独立電源にして、何らかの表示装置をつけないといけない。素人が使うなら音もあったほうが良いかもしれない。
ただ基板上にはGM管からの出力パルス(トランジスタでバッファー)しか出力が出ておらず、QFPのMega328の空きI/Oピンは全く引き出されていない。LCDをつけるには表面実装のパタンから線を引き出す必要がある。ピン配置と基板をにらめっこして、半田ごてが入りそうなピンを物色する。
ISPピンヘッダーはパタンがあるので、これをつけるついでに、パラレルLCDをつける半田付けのための練習を兼ねて、電源を入れると点きっ放しになる基板上のLEDをMega328のピンに移して点滅するようにした。パタンを切って銅面を出し、ピンをUEW線(0.2ミリ)でつなぐ。
順調に作業が済んだ。ソフトの方は手馴れたAVRのプログラミングである。プログラムを変えて、赤のLEDがブリンクするようになった。ただ、この基板はクリスタルをけちってCR発振のクロックなので、余り厳密なことは出来ない。出てくる数値もあくまでも目安程度だろう。
それでも、GM管から出てくるパルスの間隔を配列に蓄積し、10ヶの移動平均をとって、直近の平均のCPMを出すプログラムの開発にとりかかった。品物が来る前から構想は練ってあったので、コーディング半日、テスト半日で、所定の4桁のCPMがUARTに並ぶプログラムが動いた。
出てきた数値をPCのExcelでグラフにしてみた。地下室は一般的には、自然放射線量が多いということだが、我家では、明らかに地下の方が低い結果が出た。
あとは、LCDにこれを移しポータブル化することと、さらにμSv/hなどに換算するロジックや、データログ機能などが待っている。まあ、もともとは、「正しく怖がらなければ」などとブログで大見得を切った手前、何らかの自衛手段を持っておかねばと、はずみで買ってしまったようなガイガーカウンターである。深入りしていけばきりがないので、適当なところで切り上げるつもりだ。
ソースコードは、オリジナルソースがクリエイティブコモンズのAttributeオプションと言うことなので、ソースコードの原作者表示を残し、当ソースもこれを継承していくことにする(作者名を表示すれば、複製、改変、商用可能)。
暫定版ですが、とりあえずソースコードを、例によってAVRStudioのプロジェクトとして下に置きます。SparkFunのガイガーキットだけでなく、パルスの到着間隔を測定表示するプログラムとして他にも応用が可能です。
| 固定リンク
「AVR」カテゴリの記事
- ソフトI2Cはクロックストレッチまで手を出してあえなく沈没(2017.09.02)
- オシロのテストどころかソフト開発で大はまり(2017.07.26)
- 超音波方式の人感センサーI2C化と新しいオシロ(2017.06.29)
- motionの動体検知はRaspi3の電源が安定しない(2017.04.16)
- 赤外線学習リモコンはデータ再現で挫折したまま進まず(2016.07.21)
「電子工作」カテゴリの記事
- 生存証明2(2022.10.19)
- 生存証明(2022.01.23)
- パソコン連動テーブルタップの修理を諦めて自作(2021.02.16)
- 半年ぶりのブログ更新に漕ぎつけた(2019.09.19)
- 研究所活動は停滞したままでCCDカメラ顕微鏡導入など(2019.02.08)
「ARM」カテゴリの記事
- 心電計プロジェクト:スケールが出ると心電計らしくなる(2015.01.08)
- 心電計プロジェクト:TFT液晶に念願の心電波形が出た(2014.12.18)
- 心電計プロジェクト:STM32F103の心電波形表示で悪戦苦闘(2014.12.03)
- 心電計プロジェクト:CooCoxでARMの表示系ソフトを開発する(2014.10.16)
- 心電計プロジェクト:表示部のARM基板の開発環境を一新する(2014.09.19)
「FreeRTOS」カテゴリの記事
- WiFiモジュールESP32で画像付きサーバーの開発に成功(2017.09.28)
- FreeRTOSマルチタスク対応UARTとガイガーカウンターキット(2011.07.08)
- FreeRTOSのセマフォーの不具合がやっと解決(2011.06.25)
- FreeRTOSでバッファー付きUARTを動かす(2011.06.18)
- FreeRTOSでユーザー割り込み環境が動いた(2011.06.04)
コメント