« 2009年5月 | トップページ | 2009年7月 »

2009年6月の6件の記事

2009年6月26日 (金)

電子工作の次の方向が決まらない

 BeagleBoardへのUbuntu導入で時間をとられてしまったが、本来の電子工作を全くやってなかったわけではない。日にちは前後するがこの一週間の出来事を報告しておこう。

リチウム電池の充電実験をブレッドボードでする(6/19/09)Dslitebatt1
 このあいだ千石に行ったら、店が拡張されていて新装セールをやっていた。道路上のかごに任天堂のゲーム機(DS-Lite)の補充用リチウムバッテリーが山盛りにされ、¥480という安値で出ていた。最近、我が家でもこのゲーム機がはやっている。予備があれば喜ばれる。この前の携帯の余った電池より少し厚いが面積は小さい。3.7Vで1000mAhと容量も十分だ。PCMプレーヤーなどの電池に使えば、さらに小型化できる(6/24まだ少し残っていた)。

 もちろん純正品ではないが、純正品なら¥2000近くするバッテリーだ。思わず2つ買ってしまった。そういえば充電用のICのLTC4054もこのあいだここで買ったきり試していない。ちょうど良い機会なので、このバッテリーを充電してテストすることにした。Dslitebatt2

 あらためてLTC4054のデータシートをダウンロードし仔細に調べる。殆ど何もしないで完全な充電が出来そうだ。これは楽だ。ただ、チップが小さい。ピッチ変換基板にはベタアースなどない。700mAまで充電できるそうだが発熱が心配だ。データシートにちゃんと熱抵抗値がでていたので計算してみる。

 うむ、50mm平方(7mm四方)の金属接続面積で、接合点と表面の間の150°C/Wで計算してみても、400mAぐらいまで流して平気なようだ。安全のため200mAくらいから始めることにする。

 ブレッドボードで組む。ものの5 分もあれば組みあがる。実験を開始する。LEDが点き、充電が始まった。用心のため、テスターふたつをつけ、充電電流と電圧を測る。ついでに温度計をICの上にセロテープで固定し、温度も測る。制御抵抗を5KΩにしたら、180mAくらい流れた。この程度では、チップは殆ど熱をもたない。Ltc4054test

 定電圧充電に入ってICが充電を終えるのに3時間余りもかかってしまった。10分ごとに測っていたのだが、電流がシャットダウンされる最後の瞬間を見逃す。サッカーのゴールシーンを見逃した感じだ。もう午前3時近い。慌てて床に就く。

いずれにしても、これで安全にリチウム電池を充電する基盤はととのった。これは楽しみである。注文を受けているLPCMプレーヤーに充電回路を内蔵すれば実用性はいっそう高まる。人にあげるのでなく自分のためにも2号機が作りたくなってきた。

秋月で買った小さなケースがこの電池にピッタリ(6/24/09)
 最近は仕事で事務所に出ても、仕事の合間は電子工作のことを考えていることが多い。充電ICが思いのほか順調に電池を充電することがわかったので、今までの電子工作のロードマップをあれこれ検討した。

 これまでのロードマップでは、次はARMのSTM32 でのSDカードアクセスだった。しかし、SDカードは既にAVRやH8で実現しているので新味は薄い。それにSDカードは手段で目的ではない。フォトフレームが最終目的だが、LPCMプレーヤーの演奏中の経過表示を適当なOSを入れて作ってみたい気もする。DACにひたすらデータを送り、バッファーのデータが少なくなればSDカードを読みに行き、そのかたわらLCDにデータを表示すると言うマルチタスクをOSなしで作るのは至難の業である。Photo_2

 しかし、OSを入れるには準備が必要だ。それにSTマイクロのファームライブラリをV3に上げておきたい。あれやこれやでなかなか具体的な行方が定まらない。そんな日の仕事の帰り、秋月に寄ったら、これまでのLPCMプレーヤーに使ったケースよりさらに小さなケースを見つけた(アクリルケース蝶番式[小] 117-TSS 77x51x22)。

 Photo_3ここまで小さくするのは無理だと思うが、¥100と安いので試しに買ってみた。家に帰って、先のDS-Liteの電池を入れてみる。何とこれがピッタリ入ってしまう。1ミリの狂いもない。それに前々から気になっていた、ここの(ストロベリーリナックス)の3Vで動く超小型LCD(¥700) の長さが、これがまた測ったようにきれいに入る(はずだ)。これはもうLPCMプレーヤーの2号機を作れと言う電子工作の神の天啓だ。作るしかない。

 はずみというのは恐ろしい。LCDを発注するときに、どうせ同じ送料ならと前から欲しいと思っていたXbeeチップ(¥2730 2ヶ)も一緒に注文してしまう。確かに1ヶだけではテストもできないし、2つというと¥5000以上になるのでためらっていたパーツである。これは前から計画している電力ロガーの無線通信手段になる。

 いやいやプロジェクトの方向が定まらなくなってきた。嬉しい悲鳴である。旅行はその時より計画しているときの方が楽しいと言う。電子工作も同じようなものだ。作り始めると苦しいことばかりだものね。I2c_lcd_4

UbuntuがWindowsのファイルを壊したが何とか修復(6/25/09)
 ついでに、Linuxネタをひとつ。BeagleBoardの騒ぎの後、ふとPCのデスクトップを見ていて見かけないアイコンを発見した。アイコンの名前が000で特定のicoファイルのない裸のアイコンである。誰がこんなゴミを作った、と気楽に消そうとしたら、これが消えない。このPCは、このあいだ2つあるハードディスクのひとつをデフラグして、10GばかりのスペースをつくりUbuntu9.04のLinuxをインストールしたばかりである。

 これはおかしい。そういえば昨日、LinuxからこのCディスクを色々いじった。そのとき悪さをしたのだろうか。用事があったのでMy Documentを開く、あれれ、ここにも000のファイルがある。同じように消せない。Windowsでは全くこれを操作することが出来ない。

 顔が段々青ざめていく。これはまずい。バックアップは今年の始めにやって以来さぼっている。思い当たることは、Ubuntuのインストール以外考えられない。とるものもとりあえずWebで調べてみる。

 キーワードを「000 Ubuntu ファイルが消えない」で検索をかけたら、一発でそれらしいサイトにぶつかり、原因が判明した。やっぱりUbuntuの仕業だ。インストールのとき、すべてのパーティションに対してファイルチェックをするのだが、ファイルタイプvfat(Windowsファイル)に対してもLinuxのfsck(ファイルチェック)をかけてしまい、シフトJISの日本語名ファイル・フォルダーを不良として修復をかけてしまうのだ。被害にあうのは、FAT32のファイルだけで、NTFSでは起きない。「ポソ表構十申」などの日本語がファイル名に使われるとやられる。

 Ubuntu7.10のときの問題だというけれど、現実に9.04でも同じことが起きている。フォーラムをよく読む。良かった。Ubuntu上では、renameが可能だ。本体は消されていない。悪さをするのはインストールの時だけで、そのあとは大丈夫らしい。色々な修復方法が載っている。DOS窓で、dir c:\ /A- /S > HOGEHOGE.TXTとやってすべてのディレクトリ名をファイルに書き、000のファイル・ディレクトリを探せとある(同一フォルダー内では001,002と増えていく)。

 やってみた。15MBのテキストファイルが出来た。行数にして32万行。結構なサイズだ。指定の秀丸エディターはなかったので、Linux上で、grepをかける。いやあ昔を思い出す。数だけ示す-cでやると1582と出た。肩の力が抜ける。こりゃ人間の力では無理だ。少しlessなどで見てみる。ああこれはファイルサイズが XXX,000などの場合もヒットしているので実体はもっと少ない。

 ' 000'でやってみる。うむ、158と出た。これが被害の数のようだ。これくらいなら何とかなる。日本語名のファイル、ディレクトリだけが被害を受けるのでWindowsそのものの動きには影響はなさそうだ。最初はWindowsの再インストールまで覚悟したが、それはしなくても大丈夫なようだ。良かった。

 実際の修復にとりかかる。自分のドキュメントはバックアップが不完全ながらあったので、それを見ながら、Ubuntu上で元へ戻せたが、困ったのは、Windows自体にある大量の日本語ファイルであった。Windowsのテーマファイルがごっそり000に変わっている(スポーツテーマなど)。少し直し始めたけれど、どうせ使わないテーマを元にもどす必要もない。結局、自分のファイルだけの回復作業でやめることにする。

 それでも30個近いファイル・ディレクトリの修復をさせられた。やれやれ、えらいところで時間をとられてしまった。デスクトップで発見の端緒となった000になったアイコンは、ソリティア.lnkだった。ははは。

 余り腹が立たないのは、何故だろう。まあ、Linuxびいきということもある。これが現実にファイルそのものを消していたらこんな笑い話ではすまないが、この程度の被害と言うことと、問題解決に当たっての、このオープンなところが何とも清々しい。かなり致命的な問題なのだが、みな感情的にならず寄ってたかってその修復に力を合わせている。これがオープンソースの良いところだ。それでもFAT32でWindowsを作り、そこへあとからUbuntu Linuxをインストールする人は要注意である。

| | コメント (1) | トラックバック (0)

2009年6月23日 (火)

BeagleBoardにUbuntu9.04をインストールする

日経Linuxの記事があてにならない(6/21/09)
 今月(7月号)の日経Linuxは、電源プラグに差すだけで動くLinuxサーバーや、BeagleBoardの新版(RevC)の紹介という組み込み系の特集である。なかでも最近リリースされたばかりのARM用のUbuntu 9.04 LinuxをBeagleBoardにインストールする記事は、当研究所がこれからやろうとしていたこととぴったり一致する。Thumb_200_cover_200907

 BeagleBoardは余技にすると言ったばかりなのだが、タイミングが良すぎた。これは買ってくるしかない。それに、この前のAngstromのインストールでは、knoppixで誤魔化したけれど、そろそろPCにもLinuxを入れておきたい。各種の最新Ubuntuディストリビューションの入ったDVDも付録についているというので、早速、購入してきた。

 通読すると、BeagleBoardへのUbuntu9.04のインストールは、SDカードのフォーマットから、最後の日本語フォントのインストールまで事細かに解説してある。とても簡単に見えた。BeagleBoardの当面の目標は日本語化だったが、Angstromの日本語化はそう簡単ではない(動かしたのはデモ版)。これならすぐ日本語が見られそうだと気楽に作業を始めた。

 ところが、これが一筋縄では行かなかった。雑誌の記事の通りやっても動かないのである。あとでわかったことだが、この雑誌の記事にはミスが多いのだそうだ。普通は、印刷された、しかも大手の出版社の活字情報は、Webの情報より信頼度が高いと思うのが常識なのだが、これが違ったのである。

 結果としては、インストールは成功し、BeagleBoardのブラウザーで日本語を表示できるところまで進んだ。この雑誌の記事の通りにやって動かないで困っている人がまだ沢山いると思うので、とりあえず経過だけでも紹介しておくことにする。

 まず、はまったのが、パーティションを切る、GPartedというソフトのインストールである。apt-get installを入れても一瞬のうちにエラーで帰ってくる。こちらは最近のLinux情勢にうとい。とくにDebian関係は全く経験がない。始め、apt-get updateをしないで、ない、ないと騒いでいた。

 これはGPartedでなく、gpartedで探したら一発で見つかる。やれやれUNIX関係は、大文字、小文字に厳密なので、こんなことではまる。コマンドは正確に記述して欲しい。

(誤) sudo apt-get install GParted    -----> (正) sudo apt-get install gparted

 しかもページを沢山使って説明したGPartedのやっていることは、単に、SDカードの残りの部分をext3で定義し、ここと頭の部分をそれぞれフォーマットするだけのためだった。これくらいなら、何故、fdiskとmkfsでやってしまわない。記事を良く読まなかった自分が悪いことを棚に上げて無駄な作業手順をやらされて腹の虫が納まらない。

 いよいよ付録DVDからrootfsイメージの展開である。記事の通りtarコマンドを入れる。おやあ、このコマンドのオペランドの順がおかしいなあ、最近は順序が変わったのかしら。入力する。やっぱりシンタックスがおかしいと、はねられる。

(誤)
$ tar /media/cdrom/article/toku3/ xvzpf armel-rootfs-lxde-200905161138.tar -C /mnt/
  (傍線 筆者)

(正)
$sudo tar xvzpf   /media/cdrom/article/toku3/armel-rootfs-lxde-200905161138.tar -C /mnt/

 何と、tarコマンドのオプションが入出力引数の中間に入っているまま印刷記事になっている。こういうコマンド行は校正の時には真っ先に、入念にしなければならないところである。どうしてこんな間違いが起きるのだろう。理解に苦しむ。しかもこのtarの前には、sudoがない。

 まあ、この程度なら少しUNIXを知っている人ならすぐわかる間違いだが、次の不具合はもう少し深刻である。正しく入れなおしたtarが全く展開できていない。エラーメッセージを見てわかった。SDカードのルートディレクトリは、root以外の書き込みを許可していない。雑誌の記述では、この先のファイルの作成ではroot権限になれと書いてあるが、tarはsudoで動かしている。

 ファイルの生成は微妙で、誰が作ったかでパーミッションが変るので、こういう作業はユーザーはrootでやるのが間違いがない。いくら管理者権限があってもrootでないと失敗するときがあるのだ。しかし困った。何かの手違いで新しくいれた現在のPCのUbuntuではrootのパスワードが設定されてしまい、現在rootになれない(これはその後、sudo su - で、# passwd によってrootのパスワードの設定が出来ることがわかった。 Ubuntuでは最初、rootが設定されていない)。

 仕方がないので、SDカードのルートディレクトリをchmod 777 /(SDカード)で、パーミッションを強引に変えて(これはsudoでも出来る)、tarを入力する。正規には、ここでrootになってインストールしなければならない。

 何とか順調にtarボールが展開され始めた。おや、最後の方で少しエラーが出た。うーむ、rootではないからな。いくつかのディレクトリ生成やリンクが失敗に終わっている。だめもとで出来上がったカーネルを立ち上げてみる。いや大丈夫なようだ、順調にブートされていく。いや、やっぱりだめだ。途中で止まってしまった。no initial consoleのメッセージで止まっている。確かtarの展開のときのエラーはディバイス関係のディレクトリでのエラーだった。このあたりでひっかかっているのだろう。

 やれやれ、アマチュアのWebの記事を参考に入れたAngstromは一発で動いたが、雑誌の記事を見て、しかもミスを回避しながらのインストールは失敗に終わった。恐らく沢山の人がこの記事の通りやって動かない動かないと悩んでいることだろう。A6221987

 もういちどrootからやってみよう。それに雑誌のrootfsイメージは信用がならないので、正規のサイトから落としたほうが良いかもしれない。

BeagleBoardでやっと日本語が出る(6/22/09)
 翌日、仕事から帰って、もういちどSDカードをフォーマットし直し、正式にrootになってtarで展開する。とりあえずは雑誌のDVDから展開する。うむ、全くエラーもなく、きれいにrootfsはインストールされた。omap3のカーネルイメージも順調に展開された。

 新しく入れたUbuntuのターミナルでcuコマンド(いや、なつかしい。接続終了が、~.という変なコマンド)でシリアル端末を立ち上げる。おやあ、最初のブートローダーがリセットしてしまう。どうした。あ、USBのハブの電源を入れていなかった。入れ直す。よしよし、Linuxのブートが始まった。画面を切り替える。

 おお、PCのUbuntuと全く同じログイン画面が出た。しかしログインでまたはまる。rootでは入れない。これは雑誌にちゃんと書いてあった。BeagleBoardのUbuntuはユーザー名 ubuntu パスワード ubuntuで入るのだ。

 Angstromと同じようなGUI画面があらわれる。ロケールが日本語になっているので字化けしている。日本語フォントが入っていないからだ。これは自分でいれなければならない。最後の難関、日本語化キットのインストールである。BeagleBoardがネットワークにつながっていないと出来ない。幸い、Net関係は一発で通ったようだ。インストールコマンドの入力だ。何い、こんなコマンドを入れるのか。

(誤)
$ sudo -y apt-get install language-support-fonts-ja

(正)
$ sudo  apt-get install language-support-fonts-ja

 とんでもないところに -y が入っている。これ違うよね。念のため、その通り入れてみる。もちろんシンタックスエラーではねられる。-yをとりのぞいて入力。順調にパッケージがインストールされた。Debianは初めてだが、このapt-getは実に便利である。昔々RedHat Linuxを入れて、rpmに感激したことを思い出す。

 ウェブブラウザーを探す。おや、Conkerorという簡易なブラウザーしかない。こいつキーボードからURLを入れさせる。コマンドガイドを頼りに日本語サイトを入れる。出た出た。おおう、きれいな日本語フォントだ。A6231991

 いやあたいしたものだ。たかだか8センチ四方のボードでここまで動くのである。ボードのCPUチップに触ってみる。結構熱くなっているが、やけどしそうなほどの熱さではない。せいぜい数ワットというところだ。地球に優しい。

 画面の動きは、一昔前のノート PC、そうちょうど今ターミナルに使おうとしているPentium133Mhz時代のLet'sNoteの画面の動きをもう少し遅くした感じだ。ウインドウを激しく動かすと軌跡が残る。まあ、これが目的ではない。これだけ動けば十分だ。こちらは今のところNASあたりを予定している。

 それにしても、今度の雑誌の誤植には驚いた。信頼性について活字メディアを一段高い位置に置いて考えていた自分がもう古いのかもしれない。Web情報ならいくらでも訂正が効くが、活字はそういうわけにはいかない。だから校正には念には念を入れ、読者もそれを信じていた。そういう自覚が今は薄れているのだろうな。

| | コメント (9) | トラックバック (0)

2009年6月16日 (火)

レガシーなRS232Cインタフェースにはまる

 STM32のRTC(リアルタイマークロック)が動き始めた。次のプロジェクトの目標はSDカードアクセスで、行く行くはこのSTM32で、液晶フォトフレームのようなものを作ってみようと考えている。その前に環境を整備しておこうとして思わぬところで時間を費ってしまった。一週間たっぷりはまりこんで一喜一憂していた。まあこれが趣味の醍醐味だと負け惜しみを言っている(単に耄碌(もうろく)しただけかも)。

printfがやっと動いた(6/08/09)
 当面の懸案は片付いたのだが、具体的な次の作業が見つけられない。そんなこともあって細々とした手直しや、周辺の環境整備をして気分が乗るのを待っている。1年以上前にAVRの実装処女作として作った温度ロガーを久しぶりに動かしてみた。電池はまだ十分あって温度が表示されたが、コマンドを殆ど忘れていることがわかる。あわててコマンドの案内メッセージを出すためにAVRStudioを立ち上げてAVRプログラムの修正。良かった。やり方を忘れていなかった。かと思えばBeagleBoardのために買ったワイヤレスのキーボードを試してみたりする。どうも落ち着きがない。

 当研究所のキーボードは15年以上前に買ったDECのPCについていたものである。中古でも当時30万近くしたPCだったのでキーボードのつくりが良い。こいつの使い勝手、キータッチを上回るキーボードにそれ以来お目にかかったことがない(安物ばかり使っていたこともあるが)。ブラウン管モニター同様愛用していて今も何の不具合もないが、さすがに古くなってきた。今度のワイヤレスはその代替としても考えており、少し高めの製品を選んだためか打ちやすい。

 ところでBeagleBoardのブートローダーや、STM32のファームライターはシリアルを要求する。PC一台では開発の効率が悪いので、戸棚の奥に眠っていた大昔のLet'sNoteを引っ張り出した。Pentium133MhzのWindows95時代のものである。ターミナルだけなら十分だ。立ち上げてみて、色々思い出した。こいつはLinuxと、DOS(V7)まで3つのOSが動くようにしてあった。海外のサイトの情報をもとに、liloを細工してPartitionTableを書き換えるという荒技をやって、DOSとWindowsを両立させている。懐かしい。Letsnote

 情けないことにLinuxのコマンドを殆ど忘れているのでWindowsのハイパーターミナルでシリアルをテストする。問題なく動いた。これでPCの画面を切り替えなくてもBeagleBoardを動かすことが出来る。

 STM32の方は、ファームライブラリをV1(V2は殆ど同じ)からV3に上げないといけない。STマイクロのmigration guideを少しまともに読んでお勉強する。CMSISなどという大層なコンセプトがついているので何かと思ったら、Cortex Microcomputer Software Interface Standardの略で、ARMのCortex-Mファミリーの中だけの話だ。

 構造的に大きく変わったわけではなさそうだ。直接レジスターを叩くときのライブラリ(core_cm3.h関連)と、構造体を介して動かすソフトのためのライブラリを別に用意したのと、表記上の変更・統一(Atmelと同じようなuint32_tとか、volatileでなく__IO__とか)などが主な変更だ。要するにCortex-Mシリーズの統一したライブラリを目指したもので(ベンダー側のメンテナンスコスト削減)、ユーザーにはたいしたメリットはない。まあ、GNU用のスタートアップルーチンが用意されたのが安心と言えば安心である。

 一気にV3の新しいプロジェクトを立ち上げる気力がなかったので、前からやろうと思っていたprintfの実装をすることにした。Eclipseで#include <stdio.h>が未定義エラーになっているのも以前から気になっている。それでいて標準ライブラリは、sprintfが問題なく使えている。良くわからない。

 オリジナルのデモソースは、printfだったが、動かなかったので、sprintfに替えた経緯がある。理屈から言えばこのあいだのsyscalls.cのスタブルーチンの_write( )にUARTの出力関数を実装すれば動くはずだ。「ねむい」さんのsyscallsのソースもそうなっていた。早速このソースを参考にコーディングしてみる。

 こいつがまた思い通り動かない。出力はされるのだがタイミングがおかしい。色々調べているうち、昔のことを思い出した。かなり昔、UNIXを少しいじっていた頃、標準ストリーム出力が言うことをきかなかったことを思い出す。確か、ストリームは、バッファーリングしているのでデータを残さないで全部を吐き出させるためには何かテクニックがあったはずだ。

 ウェブに慌てて教えを請う。やっぱりそうだった。えー、¥n(ニューライン)がバッファーの区切りなの?それじゃあ、デモソースにある時刻を表示するステートメントの最後が¥r(リターン)では、いつまでたっても表示されない。デモソースのオリジナルは、printfの文法を無視した実装になっている。ちょうど逆だ。

 どうも、オリジナルのデモソースのprintfは標準のpirntfで動いていない。その証拠に\n\rが行頭にあり、これでは全部のステートメントが一回づつ遅れる。それに時刻表示が\rで終わっている。これでは1秒毎に表示されず、バッファーが満杯になって始めて全部の秒表示が行われ、最終的に最後の秒表示が出るだけだ。今のソフトがまさしくこうして動いており、何分かに一回、時刻が更新されている。

 UARTに出すメッセージの行換え文字\rをすべて\nにして行末に移しコンパイルし直す。これで正しくメッセージが表示された。おや、時刻表示が\nによって行を換えて斜めに表示されてしまう。これはまずい。

「ねむい」さんから貰ったsyscallsのソースを確かめて見ると、_write( )で、\nがあると\rを追加している。そうか、これがそれを防ぐ仕掛けか。しかし、時間表示が延々と行を換えて出てくるのは時刻表示らしくない。

 そこで考え付いたのが、\nを\rに、\rを\nにひっくり返す方法だ。これで、\n\rとやれば、従来どおり行を換えて行頭から出力され、\nだけだと、行頭に来るが、行換えをせず重ね書きをして時刻表示らしくなる。恐らく標準ライブラリには、これらを定義する関数か、環境変数があるのだろうが、とりあえずの対策である。

簡易RS232Cの制作ではまる(6/13/09)
 今さらレガシーなRS232Cでもないのだが、COMポートの使用頻度が高くなったきたので、chaNさんの簡易RS232Cインターフェースを作ることにした。USB-UARTがあるから必要ないように思えるが、USBの仮想COMポートは、頻繁にファームを書き直し、リセットしては動かすマイコン相手には、極めて使い勝手が悪い。

 USBの仮想UARTは、セッションのときだけ存在するまさしく仮想的なもので、どちらかのアプリケーションが終われば無効になる。マイコンのように常にリセットするような相手では、PC側の端末ソフトはその都度、立ち上げなおさなければいけないし、フラッシュローダーも仮想COMポートが生きているように見えても実際にはマイコンだけでなく仮想COMポートもリセットしてから(コネクタの抜き差し)でないとつながらない。

 ARMのフラッシュローダーを使うようになってUARTを使う機会が増えた。BeagleBoardもブートローダーはシリアル経由だ。ChaNさんのAVRspもシリアルであり、シリアル、UARTの使用頻度は高い。幸い我が家の自作PCはレガシーなCOMポートがついている。いざとなったら16550を使った拡張COMポートインターフェースだってある(古いものなら何でもある。あ、あれはISAバスだったか)。

 ハードのCOMポートなら端末プログラムを立ち上げておきさえすれば、マイコン側がどういう状態であろうと常に動き出す。フラッシュローダーも端末プログラムを止めればそのまま動く。手始めにSTM32のTTL-UARTをRS232CインターフェースにするChaNさんの簡易RS232CをDSUBソケットに作ることにした。Rs232c1

 これはインバータICを使った至極簡単な回路である。これで+9V,-9VのRS232CラインがTTLになってしまう魔法のような回路だ。規格に合っていない邪悪な方法だそうだが、他のいくつかのサイトでも動作が確認されておりアマチュアが使う分には折り紙つきだ。ブレッドボードに組み、動きを確認する。作るのに1分もかからない。最初はPCからの送信がうまくいかなかったが、端末のフロー制御をしていないという例のオチに気が付いてジャンパーを飛ばして解決し、ブレッドボードでは何の問題なく稼動した。3.3VのVccなのに5Vの入力パルスが来るのが少し気になるが、これは実装のときに100KΩの抵抗を増やせば良いだろう。

 今度は基板を小さく切り取ってDSUBの変換基板に実装する。ところがブレッドボードでは苦もなく動いたのに、こいつが言うことを聞かないのである。TTLからの送信はできるのだが、PCからの送信が出来ない。フロー制御はコネクタで処置済みである。オシロまで持ち出した。結果、PCからの送信、マイコンにとって受信側が、送信データを拾って発振を起こしている。配線が近くなったから?まさか。

 それともインバータの手持ちがなかったので74HCU04というアンバッファータイプを使ったのが原因なのだろうか。Vccを3.3Vにしたので、RS232Cの電圧が高すぎ、ICをこわしてしまったのだろうか(100KΩを200KΩにして3Vまで下げた)。ICを取り替えてみたいが、こういうときに限ってICを半田付けしてしまっている。やれやれ。

 休みに家族と都心に出たついでに秋葉に寄り千石で74HC04を仕入れ、ついでに秋月で、本式のRS232Cのラインドライバー(ADM3202ARN 2ヶ ¥300)を用心のため買う。例の表面実装部品とりはずしの低温半田でインバーターICを取替え(これは確かに楽だ)、組み込みなおす。しかし当然、HC04でも動かない。頭を抱える。ブレッドボードでは問題ないのに。Rs232c

 思い込みとは恐ろしい。結局、RS232Cを動かすのに3日もかかってしまった。オチは、ここに書くのも恥ずかしい、インバーターの入力ピンと出力ピンの取り違いである。ブレッドボードでは横並びにインバータを使い、実装では配線を短くするため、反対側の回路を使った。ピンナンバー順に入出力が並んでいると頭から思い込んで、片側の回路に入出力を逆につけて動かない、動かない、発振していると悩んでいたのである。

 データシートは見たが、思い込んでいるときは、こういうものである。ふんふん、下から入力、出力、入力、出力ね、とはなから自分で納得し図をろくに見ていない。昔、鉄道の単線で、全速力の列車の正面衝突という大事故の原因が、区間にひとつしかないタブレットという交換器の機械が空かない(実際にもう汽車が走っている)のは故障と頭から決め付けて、鍵をはずしてもう一方の列車に渡してしまった駅長さんの話を思い出した。

 動いたときは、本当に安心した。情けないという自責の気持ちより、これが動かずに終わったらこの先の気持ちの整理をどうしようかと恐れていたのだが、それをしないですんだという安堵感の方が強かった。くだらないことにくよくよする自分が情けなくてまたさらに落ち込むという鬱のスパイラルに陥るときがある。まあ、こんなことで一喜一憂しているのだから本当に安い娯楽だ。

やっぱり本式のラインドライバーは違う。フラッシュローダーが動く(6/14/09)
 手を動かしていると、こういう気持ちの納まらない時の気分転換になる。安全のために買ってあったRS232Cのラインドライバーを実験してみた。DIPではなくあえてSOICのADM3202ARNにしたのは、変換基板に必要部品も乗せてしまおうと言う魂胆である。Adm3202

 ICのおまけに、チップコンデンサーが付いている(0.1μF、5×2)。これが、今まで実装したことのある20x12ではなく、もう一段小さい16x08(横1.6ミリ、縦0.8ミリ)だ。これをつけろというらしい。うーむ、変換基板の端子に普通のリード線のコンデンサーをつけるつもりをしていたが、挑戦状を突きつけられた感じだ。これは受けるしかないだろう。

 写真を見ていただければ良いが、これは面白かった。良い勉強になった、半田ごてをもう少し細いこて先にすればもっと楽だったかもしれない。被害はチップコン1個(ピンセットで強く挟んだ弾みに机から飛びはね行方不明になった)。まあ、このへんが手配線の限界だろう。Adm3202_3

 ブレッドボードにDSUBコネクタと一緒に配線してテストする。うむ、配線違いもなく問題なく動く。オシロで波形を見る。きれいに+6V,-6VにわかれたRS232Cの信号が出ている。STマイクロのフラッシュローダーはどうだ。こいつは気難しくて簡易RS232Cでは動かなかったのだ。おおお、何の問題もなく認識した。やっぱり本式は違う。買っておいて良かった。

| | コメント (0) | トラックバック (0)

2009年6月 8日 (月)

STM32基板のRTCを動かす

 それにしてもデバッグは難しい。わかってしまえば、何でこんなことに今まで気づかなかったのだろうというお馬鹿な間違いなのだが、気がつくまでの道のりは決して短くない。まあこの謎解きが面白くて電子工作をやっているようなものだが、今度のSTM32のRTC(リアルタイマークロック)プログラムも結構手こずった。「デバッグは外へ、外へ」などと偉そうなことを常日頃言っているくせに、頭に血が昇るとつい我を忘れてしまう。

軽い気持ちで手をつけたがまるで動かない(6/2/09)
 このところ1年前の雑誌の付録基板、STM32F103(Cortex-M3) の開発に熱中し、先週、高速化したUSB仮想UARTのモニタープログラムを完成させて意気が上がっている。ウェブでもこの石を使ったCPUボードを時々見かけるようになった。価格もそう高くない(2インチ160x128のカラー液晶付きの評価ボードが¥9000で手に入る)。クロック72Mhzの32ビットプロセッサーだ。ARMコアの中では普及版だそうだが、アマチュアが遊ぶには十分すぎるスペックである。

 RTCはUARTモニターの開発のときから次の目標に決めてある。せっかくバッテリーバックアップ回路を追加したのだ。電池と32.767khzのクリスタルの顔を立ててやらねばならない。RTCはファイルシステムには欲しい機能だし(書き込みの記録)、これが動くと俄然マイコンがプロっぽくなる。幸いSTマイクロの提供するライブラリには、RTCのライブラリを使ったデモソースが収録されている。これを使えば簡単に出来るはずだ。Stm32vbat

 早速Eclipseの新規プロジェクトを作り、そこへソースコード一式を放り込む。このソースはIARなどの開発環境用なので、仮想UARTモニター同様、GNUで必要な、Makefileや、リンカースクリプト、スタートアップルーチンを入れて調整する。Makfileを換えるだけでうまく行くはずだ。必要なライブラリを取捨選択し、ビルドする。殆ど問題なくバイナリーが出来た。

 わくわくしながら、フラッシュローダーにかける。おやあ、赤ランプがついて送れない。ええー、hexファイルがないだと? ほんとだ。ファイルはあるけれど中身は0バイト。これは一体どうしたことだ。elfファイルは60KB以上あるのに。コンパイラーもリンカーもエラーは出ていない。こうなると何が悪いのか見当がつかない。

 マップファイルは出来ていたので、良くわからないままこれを調べる。あれ、関数のエントリーがみな同じ値だ。これはおかしい。でも、エラーは起きていない。念のため、必要なライブラリの数をMakefileで確かめる。一つ少ない。あれえ、stm32f10x_vecter.cが抜けている。デモソースのreadmeには、これを入れろとは書いていない。

 何と言うことだ。こいつがないからに違いない。とにかくこれを含めてビルド。おお、ちゃんとしたhexファイルが出来た。readmeを信じてえらい目にあった(このあと各開発環境のプロジェクトフォルダーにはこのモジュールが入っているのを発見した。GNUのときは注意しないといけない)。それにしても、ビルドやリンクのときのNO ERRORは安心できないことを学ぶ。

 お膝元のメーカーのデモソースである。バイナリーが出来たので簡単に動くかと思ったが、これが全く動かない。おかしい原因はおおよそ見当がついている。UARTへの出力関数printfが恐らく暴走の原因だ。これを、これまで使っていたsprintfに置き換え、受信関数も自前のものにして再度、実行。

 おお、やっとメッセージが出た。しかし、RTC not configured...のメッセージを出したまま、それっきりになる。ロジックを追うと、RTCのセットアップが終わるのをループで待っていて、ここがreadyになっていないようだ。やれやれ、ハードか。念のため電圧を測る。3.24V。この程度なら問題ないはずだ。オシロで周波数を確認する。立派に32.767khzが出ている。大丈夫だとは思うが、要因を減らしてみよう。

 バッテリーバックアップをやめてVccにつなぎなおす。うわあ、RTC configuredのメッセージが出て先へ進んだ。何だ、何だ。電池が原因か。何か部品が足らないのか。

 ハードの問題は別として、これでうまく行ったと思ったら、そうは問屋が卸さなかった。時刻の設定をする受信関数が、がんとしてデータを読まない。受信関数は自前だ。自信がないので、プログラムの頭でテストステートメントを挿入してみた。いや、ちゃんと動く。しかし、時刻設定の入力では、受信データのフラグがあがらない。

 それにしても、UARTぐらいの機能で、このソースの複雑さは何だ。読みにくいことおびただしい、と悪態をつきながらデバッグする。また最適化が原因かと思ってループに、NOP_Processなどを入れるが変わらない。UARTなら、このあいだのGNUサンプルソースにもあった。こちらは至極簡単なソースだ。こいつを持ってきて動かすが、これも駄目。万策がつきる。

原因はUARTではなかった。あっけない幕切れ(6/5/09)
 UART受信が出来ない。本質と関係のないところでつまずいている。RTC不調も電池でない可能性が強い。電源を入れたままリセットをすると、RTCの初期化が途中で止まる。

 UARTの方は、その後ステータスレジスターを問題のところで出力させ不正なビットが立っていないことを確認した。どうもUARTがハングの原因ではなさそうだ。LEDとUART出力を処理の始めから、少しづつ挿入し、ハングアップするステートメントを探していった。

 その結果、RTCの割込みをenableするところでハングすることがわかる。RTC割込みがおかしい。試しに割込みルーチンにLEDを点灯するステートメントを入れるが、点かない。そうだこれに違いない。

 デモソースのバグは考えられないので、これは明らかに、Dfuのためにずらしたプログラムのエントリーアドレスが、ベクターテーブルに反映されていないことを物語る。しかし、ソースの何処を探しても、テーブルのアドレスを設定するところはない。ベクターテーブルは、リンカーの最初のプログラムのスタートアドレスから相対的に展開しているからだ(これが大きな勘違い)。そうすると、リンカースクリプトか、スタートアップルーチンか。しかしここは良く分からないところで手が出せない。

 思い余って、最近お世話になっている「ねむい」さんが、RTCを動かしたと言うので、質問しようかとページを開いたら、ソースを公開されている。質問する前に調べてみようとありがたくソースを頂く。(会社ではダウンロードできなかった)

 おお、このソースは情報の宝庫だ。ユーザープログラムで割込みを止めるステートメントもある。で、ベクターテーブルを設定するところは、どこだ。見つかった。あ、あ、あ、なーんだ。明示的に設定するのだ。

void NVIC_Configuration(void)
{ NVIC_InitTypeDef NVIC_InitStructure;
  /* Set the Vector Table base address at 0x08003000    for Dfu  */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000); 

 早速、このステートメントを追加し、コンパイルしなおす。苦もなく動き始めた。全く問題ない。1秒ごとにLEDが点滅し、UARTに時刻が表示される。RTCの出来上がりである。これで、この週始めから悩んでいた問題がすべて解決した。いやあ、知らないと言うことは恐ろしい。NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); のステートメントでもあれば気がついていたかも知れないが、それにしても「ねむい」さんに感謝である。Stm_rtc

 しかし、何故、割込みが原因だということに気がつかなかったのだろう。UARTの不具合と頭から思い込み、こればかりを追求していた。RTC割り込みは1秒である。ちょうど時刻設定の入力と重なる頃だ。一瞬入力が出来たときもあり、少し冷静に考えれば、このとき不具合がUARTでないことにもっと早く気がつくべきだった。

 電池が入っているときに動かないのは、時刻設定をしないで単に時刻表示に行くからで電池が原因でハングアップしていたわけではない。しかも、付録の雑誌の7月号には、このベクターのオフセットをしないとデモなどは動かないよ、とわざわざ解説がステートメント付きで載っていて、これを読んでいたはずだ。この前の仮想UARTのhw_config.cにもちゃんとベクターのシフトがコーディングされている。今になって考えるとヒントはそこらじゅうにころがっていたのだ。お恥ずかしい限りである。

| | コメント (10) | トラックバック (0)

2009年6月 5日 (金)

Beagle Boardを動かしてみる

 話は少し前後するが、このあいだ手に入れたBeagle Boardの動作試験の報告である。ウェブ上には既に沢山の人の動作報告があがっているので、今さらの感もあるが、自分の備忘録を兼ねてまとめておく。いや、こいつはすごいマシーンだ。

Linuxの組み込みバージョンAngstromの立ち上がりまで(5/29/09)
 STM32の開発が一段落したので、懸案のBeagleBoardを触っている。足りなかった部品、UARTケーブルは、このあいだ既に作ってあり、ROMモニターが動くところまではテスト済みである。Beagle

 次のステップは、ここにLinuxやAndroidなどのOSをインストールすることである。例によって先人の経験をありがたく参考にさせてもらうことにする。お手本にするサイトは、既にここに決めてある。このサイトは前から評判になって目をつけていたところで、ここではLinuxの組み込みバージョン、Angstrom(オングストローム)のデモ版を動かすところまで丁寧に教えてくれる。本当に良い時代になったものだ。

 Beaglebootこのサイトの著者はちょうど私と同じソフト系の人で知識の層が似ており理解が早い。恐らく私より遥かに若いのだろう。UARTのフロー制御を「なし」にしないと動かないので苦労したというところで笑った。昔シリアルが全盛のときは、フロー制御をしない「フリーランニング」という結線があり、これは、シリアルのCTSとRTS、DSRとDTRをコネクターの中で結んでしまう。

 こうすると、片側がフロー制御を要求する機器であっても問題なくつながる(自分が要求したものが返るので)。もちろん本当のフロー制御はできない。上品な言い方ではないが「垂れ流し」とも言っていた。そうか、シリアルはもう誰も使っていないので、こういうことは忘れられているのだろう。年をとったことを実感する。

 それはとにかくこのOSのインストールにあたっての問題は、UNIX(Linux)マシンが手元にないことである。Linuxは10年ほど前、今の電子工作同様熱中し、家中のPCや会社のPCにインストールしまくっていたが、今はすっかり手元にない。

 へそ曲がり、天邪鬼な性格なので、みんなが騒ぐようになるとかえって熱が醒めてしまう。Linuxも企業が使うようになってシステムが巨大化し、何か開拓者精神のようなものが失われたような感じがして興味が薄れたこともある。

 BeagleのためにLinuxをインストールするのも何なので、前から残してあったKnoppixのCDでLinuxを立ち上げてみた。ところが、このKnoppixのCDが古く、途中でどこかのサイトにリソースを取りに行く途中で止まってしまう。日付を見たら4年も前のCDだ。

 これじゃあ、いくら何でも古すぎる。久しぶりにLinux関連のキーワードでサイトを探した。最新版のKnoppix(6.1)を落とし(600Mだけれど数分。いや便利になった)、CDに焼いて立ち上げてみた。

 いやあ、立ち上がりの早いの何の。あっという間にLinuxが動き出した。ほんと浦島太郎の気分である。こんなに早いのなら、これを実用としても十分使える。

 SDカードのフォーマットが少しややこしく(fdiskを間違えて、fdisk /dev/sdc1とやって大はまり。 昔もよくやった)、UNIXのコマンドがなかなか思い出せず苦労したが、長い名前のファイル名の入力も、Xの上の端末なので、コピー&ペーストで間違いなくできて、システムを入れたSDカードが完成した。この時点で夜中の3時。ここまで来たら、最後までやるしかない。BeagleBoardにビデオケーブルをつけ(ケーブルの方が重くてケーブルを動かすとボードがふらふらする)、通電する。Angstromterm

 おお、カーネルロードが始まった。流れるようにメッセージが続く。うむ、順調のようだ。よーし、Angstromのロゴがキャラクタ画面に出た。Loginプロンプトでユーザー名を聞かれて弱った。始め設定かと思って新しいユーザー名、パスワードを入れるが反応しない。夜が白み始めて頭がもうろうとしているので、よくわからない。やけっぱちでrootと入れたら動いた。

 ばかな話である。Linuxの初期設定のあたりをすっかり忘れている。最初はrootしかいないのだ。Xの方はどうだ。残念。画面はこのモードをサポートしないという表示でEnlightmentは動いていない。まあ、動いたことだけでもよしとしよう。部屋を片付けて店じまいする。

 次の日。グラフィック環境が動かない原因がわかった。まだ環境変数を設定していなかった。Angstromlogin グラフィックボードへの設定を、環境変数に設定すると、見事にLOGIN画面が出た。思わずキーボードを叩いてしまって、苦笑いする。USBにまだキーボードがつながっていない。USB-LANとセルフパワーのHUBをまだ買っていない。まあ、LOGIN画面まででたので大丈夫だろう。

 キーボードと、USB-LANアダプター、HUBをアマゾンに発注した。最近はPC用品を通販で買うことが多くなった。値段が安いのである。価格.comなどの安売りランキングを見て、秋葉原に行っても必ずしも同じ値段で買える訳ではない。しかし、アマゾンなどは、安売り通販ショップに伍して、負けていない。秋葉でうろうろするより安いことが多い。

あっけなくウェブブラウザーまで動いて拍子抜け(5/31/09)
 アマゾンからUSB関連の品物(エレコムワイヤレスキーボードTK-FDP001WH、コレガUSB-LAN  FEther USB-TXC)が届いた。早速BeagleBoardにつないでみた。HUBはまだ到着しないが、今使っているセルフパワーのHUB(エレコムU2H-TAP3420SWH)をこちらにつなぐ。こいつはUSB-UARTコネクターの抜き差しをスイッチで出来るように買ったものである。USBマウスは、ウェブでは不調と言われたEeePCにオマケについていたもの(Arvel MS35MBL)。

 ブートする。シリアルポート(COM1)に順調にメッセージが流れ、Angstromのロゴが出て無事に立ち上がったようだ。画面を切り替える。ソフトキーボードのログイン画面が出た。さあ、キーボードが入るか。おおお、ちゃんとパスワード入力がキーボードからできる。Enlightmentの画面に替った。マウスは?これも問題ない。

 なんだなんだ。何の問題もなく認識するではないか。ブートメッセージを見ていくと、キーボードの型番までしっかり出ている。昔のLinuxとは大違いだ。海外の情報を頼りに新しいI/Oディバイスを認識させるのが、インストールのときの大仕事だった。

 次は一番問題のLANだ。うまくいったので調子に乗って、動いたままUSB-LANを接続する。活線挿抜というやつだ。ほほう、何か動き始めたぞ。いかん。コンソールには eth0が設定されたが、downしているというメッセージが出た。ifconfig eth0とすると、IPアドレスが定義されていない。やれやれこれは自分でやれと言うことか。

 これが、ちょっと前までさんざん使っていたコマンドがもう思い出せない。gatewayはどこだ。pingを入れたがやっぱり外へでていかないぞ、とやっているうち、ifconfig eth0を入れてみたら、さっき定義したIPアドレスが変わっている。あれ、どうしたの。そうかDHCPが動いたのか。物は試しと、Elightmentのウェブブラウザーを立ち上げて見る。

 何と、何と、ネットがつながっている。Mogillaの初期画面が出た!いやあきれたものだ。何もしないで、全部つながってしまった。日本語フォントが入っていないので字化けしているが間違いない。余りにも簡単にイーサネットが動いてしまってあっけにとられるばかりだ。Beagleweb

 これは一体何なのだ。一区切りがついて考えた。BeagleBoardは明らかに今までの組み込みコンピューターとは違う。要するに、小さなボードで電子工作っぽいけれど、もう、ここまで来ると、これは電子工作ではない。ここはLinuxと変わらない。世界が全く違う。

 ハードに素人が立ち入る隙がもうないのだ。それにソフトウエアの規模が大きすぎる。ARM7あたりまでは、まだソースを追いかける気力があるが、このレベルでは無理だ。別の趣味に近い。

 これはこれで昔、Linuxにはまっていたから、がた老「AVR」研究所としては研究の意味はあるが、8ビットの石を工夫して機械にしているときの、わくわくする気持ちがない。
嬉しいことに、このあいだのSDカードのLPCMプレーヤーは、周りの複数の人から発注を受けて量産を考えなければいけなくなった。はじめてのプリント基板制作に挑戦しようかとも考えているが、電池ホルダーが難物だ。これの自作はちょっと大変だが、物を作る喜びは、こちらの方が大きい。

 BeagleBoardは、ケースを考えたり、日本語フォントのインストール、それとウェブサーバーとしての能力をテストする課題などが残っているが、これはもう電子工作とは別の次元の話だ。まあ、がた老AVR研究所としては、BeagleBoardは余技としておこう。本業はあくまでもAVRクラスだ(最近はARMばっかりだけど)。

| | コメント (0) | トラックバック (0)

2009年6月 1日 (月)

ダブルバッファーでUSB仮想UARTの内部速度が2Mbps

しゃれた実装を考えたが挫折(5/28/09)
 SysTickタイマーで1ms単位の経過時間が測れるようになったので、勇躍、STM32基板のUSB仮想UARTの高速化にとりかかった。これまでにわかっていることは、UARTの速度が遅いときは問題ないが、早くなってくるとエンドポイントの送信終了の割込みがユーザープログラムがデータを移している最中に入り、このときのデータサイズが実際のデータと不整合が生じてデータが欠落する。

 これはSTマイクロが提供するSTM32F(Cortex-M3)用のVCPデモプログラムに最初からあった問題で、STマイクロのフォーラムで去年話題になり議論されていた。少なくとも私の知る限りまだ解決していないはずである。SysTickを使って改修されたコードがアップされたが、その後本人が動かないとして取り下げている。この解決を当研究所がやろうというのである。もしうまく行けば鼻が高い。

 方式はダブルバッファー方式である。前のDACのデコードと同じような考え方だ。ひとつのバッファーをユーザーの送信関数の書き込み用とし、ここに送信データを入れていく。送信関数ではエンドポイントに直接書き込まない。ここで書き込むと、書き込み終了の割り込みがどこで起きるかわからないからである。もうひとつのバッファーは、割込みルーチンが既に書き込み処理をしたデータが入っている。

 書き込み終了の割込みがかかり、割込みルーチンに制御が渡ったときに、バッファーをスイッチして、今度は送信関数が書き溜めていたデータをエンドポイントに書き込む。さきほど送り終わったバッファーが今度は送信関数が新たに書き込むバッファーとなる。これで、データ書き込みと送り出しの衝突を避けることができる。

 最初、コードを少なくするため、2組必要なバッファー配列とカウンターをポインター変数にし、そのアドレスをスイッチして動くようなスマートな方式でコードを組んだ。
バッファーに送信バイトを送り込むとして、

 * ( バッファーアドレス +  * カウンター++ )=  送信バイト;

みたいなプロっぽいコードである。バッファーアドレスとカウンターポインターを取り替えるだけで、main.cの送信関数USB_Putc()はダブルバッファーであることを知らないで済む。いやコーディング技術も格段に進歩したものだ、と、得意になって完成させた。ロジックはそう難しいものではない。気をつけないといけないところは、バッファーを切り替えるときに、ユーザープログラムの実行と重ならないように、フラグを立てて守るということである。今度は、割込みルーチンが見えているので、ユーザー側は、そのフラグを見て待てばよい。

 と、これが全くうんともすんとも言わないのである。どうもさっきのステートメントのところで暴走している。表記に間違いはないはずだ。何度もウェブなどで確かめる。うーむ、何か勘違いがあるのだろうか。プログラムはまさしく考えたようには動かない。書いたように動くだけだ。いずれにしても、ポインターを使ったコーディングは一歩間違えば、とんでもないところにデータを書き込み、簡単に暴走してしまう。

 色々いじったが好転しない。悩んだ挙句、この方法をとりあえずあきらめ、普通の配列を使い、愚直に2組のバッファーを別々に操作するルーチンに切り替えた。さあ、これでどうだ。これなら暴走しようがない。もう問題ないはずだ。

 ありゃりゃあ、これでも動かない。ええー、どこが悪いんだ? シングルバッファーに戻すと何事もなく動く。わからない。このあたりでGDBが使えれば良いのだが、今のままでは、USBを使っているので初期化の段階で、HardFaultに落ちてしまいメインループに来ない。環境を大きく換えないと使えない。別のUARTで変数を出してデバッグする手もあるが、どちらも手間がかかる。

ダブルバッファーが動いた!しかしこれで良いのか(5/29/09)Ws000000
 開発が暗礁に乗り上げている。マラソンや登山と同じだ。この苦しみが歓喜の材料なのだが、その最中はそれどころではない。大げさに言えば人生が暗い。今まで生きてきたことすべてが意味のない時間だったような気分になる。

 BeagleBoardのために久しぶりにモニターを取り替え、1920x1080のワイドディスプレイになって開発環境は一変し(エディターと端末が同時に見られる)、快適になったのだが、気分は優れない。救いは、このあいだの第三のファーム書き込み手法ROMのフラッシュローダーが思いのほか使い勝手が良く、プログラムの修正、ビルド、ファーム書き込みのサイクルが飛躍的に早くなったことである。AVRなみの開発環境である。Eclipseは編集とビルドだけにしか使っていないが、これはこれで便利だ。

 それはともかく、ダブルバッファーが動かない。基本的なところを少しづつ確認していくしかない。何回目かのコードレビューの最中に、ふっと気がついた。送信関数は律義にバッファーにデータを溜め込み、一杯になれば、割込みルーチンがバッEclipeファーを切り替えるのを待っている。では誰がUSBのエンドポイントに書き込むのだ。あ、あー、ここだ。エンドポイントに書き込む処理は、エンドポイントに書いた後の割込みルーチンにしかない。ポインターの暴走でもなんでもない。元から動かない。

 何と言うお馬鹿なコードだ。これでは永遠に送れない。しかし、どうすれば良いのだろう。頭の中が混乱する。何か根本的な間違いがあるのかもしれないが、ロジック的には一度mainの初期化のところでエンドポイントにデータを書き込む呼び水のようなダミー処理をすれば良いのではないか。そうすれば次々に割り込みが連続し、うまくいくのではないか。

 やってみた。やっほー、動いたぞ。ダブルバッファーの仮想UARTモニターが前と同じように動き始めた。転送速度を測る。ややや、2Mbpsだ。素晴らしく早い。1KB送るのに数msしかかかっていない。そりゃそうだ。バッファーに1バイトづつ送るだけで60kbps近くあったのだから、その64倍だったら3Mbps近くあっても、おかしくない。

 もちろんこの速度は、単に内部でUSBドライバーが受け取った時の速さで、実際にホスト(PC)との仮想UARTでの転送速度ではない。しかし少なくとも内部では安定的にメガビットのオーダーでデータが送れたことになる。

 肝心のデータ欠落をチェックするために、同じ文字でなく、"0123456789"の文字列を送ってみる。うむ、全く欠落はない。きれいに数列が画面上に並ぶ。1字の落ちもない。いやあ、至福の瞬間である。今までの暗い気持ちが吹き飛び、天下をとった気分になる(相当中毒が進んでいる)。

 しかし、ロジックとしては不満がある。今の状態は、データがなくてもエンドポイントに立て続けに書き込む処理が動いているはずだ。今は単なるモニタープログラムなので関係ないが、別のSmpvcd仕事をするときはCPUリソースを無駄に使っていることになり効率が悪い。

 というので、エンドポイントの割込みルーチンにデータがなければ処理をやめるようにし(割込みが止まる)、送信関数には、バッファーが何もないときのデータ送信では、ダミーのエンドポイント書き込みを入れるようにしたが、こいつはまた全く動かない。

やっと満足できるコードになった(5/31/09)
 速度が2MbpsまでになったUSB仮想UARTだが不満が残っている。呼び水方式で、USBのエンドポイントにデータを送るところまでは良かったが、これでは送信していないときも延々とUSBドライバーは0データを送り続ける。

 送信データがないときはこの繰り返しを止め、データが来たときに再開するロジックを色々考えて試してみるが、ことごとく失敗する。奇怪なことに、メインルーチンの初期化でダミーの書き込みをすると上手く行くのに、送信関数の中でやると先に行かない。

 この間の差は時間だけだ。余りやりたくなかったがタイマーを入れて調整することにした。しかし全く変わりがない。何か変だ。このタイマー(元々の雑誌のソースに入っていたもの)は

   Delay( int i) { while(i)  i--; }

という簡単なコードだが、iをいくら増やしても変わりがない。コンパイラーの最適化を疑ったが、i--は立派な処理だ。無効になるわけがない。それにこの関数は、前から使っていたはずだ。

 しかし、やっぱりおかしい。念のため、コマンドを新設してこいつの待ち時間をSysTickの時間で測ってみた。うひゃー、全部0で帰ってくる。何と言うことだ。コンパイラーがこのステップを取ってしまっているに違いない。

 AVRでやったように、ループにasm volatile("NOP");を入れる(これはアセンブラーコードでなくマクロだそうだ。従ってARMでも共通)。ちゃんと待ち時間遅れが作れた。やっぱりコンパイラーの仕業だ。 雑誌で動いていたのは開発環境IARとGNUの違いだろう。それにしても、i-- がどうして無駄なコードなのだ。理解に苦しむが文句を言っても始まらない。

 ところが、待ち時間を作ってもうまく行くときと行かないときがある。時間待ちはあくまでも対症療法だ。やはり基本から確実な方法を探すしかない。もういちどソースコードをひとつひとつ追いかけて手順を考えることにした。Beale

 BeagleBoardのセットアップ(次記事で紹介)で少し日をあけたのが良かったのだろう。良い方法を思いついた。これまで送信関数の方ばかりに注目して、何とかしようとあれこれ考えていた。しかし、割込みルーチン側で動作モードを設定していけばうまく行くことに気がついた。そうなのだ。送信関数は、いつどこで割込みを受けるかわからないのでデータカウントが変わる可能性がある。バッファーを制御するスイッチにもうひとつ「データなし」というステイタスを追加してプログラムを組み直した。祈る気持ちでテストする。やった。前と変わりなくデータが送信できた。

 CPUのオーバーヘッドが明らかに減っている。その証拠に先のループで待つウェイトルーチンの時間が早くなったのだ。すごい。はっきりと差がわかる。時間にして3%くらい早くなっている。やっとまともなコードになったと思う。

 ソースコードの公開は迷った。単に大量送信の時間が表示されるだけの、このままでは実用性0(ゼロ)のモニタープログラムである。まあ、これをベースに色々アプリケーションを考えれば役に立たないわけでもない。がた老「AVR」研究所の記念すべき、初の「ARM」プログラムソースでもある。

 人のソースを流用させてもらっているが、殆どのソースは雑誌からなので問題ないだろう。STマイクロのデモプログラムも、ソースリストに「責任取らないからね」という文言しかないので問題ないと判断した。Makefile、リンカースクリプトとスタートアップルーチンはこちらのお世話になった。この場を借りて御礼申し上げたい。

 ソースファイル一式(ライブラリ、リンカースクリプト、Makfile)をここにおきます。Eclipseのプロジェクトファイルですが、Eclipseがなくても動きます。また、実行させるだけなら、STM_VCPDフォルダーの中のstm_vcpd.hexをDfuか、フラッシュローダーで書き込めば動きます。

「STMVCPD_archive.lzh」をダウンロード

 コンパイルの簡単な手順は以下の通り。

・コンパイラー(CodeSourcery G++)をここからダウンロードする。(OSはEABI、Sourcery G++ Lite 2009q1-161を選ぶ。 5/31/09現在)
・解凍したフォルダの下のSTM_VCPDフォルダーにカレントディレクトリを置き、DOS窓でコンパイル(make all)する。 FWLibや、USBLibのディレクトリの位置は変えないこと。換える場合は、Makefileを修正する。

・また、gccの標準ライブラリとヘッダーファイルは、gccの入っているbinフォルダーと同列のarm-none-eabiフォルダーの中のlib\thumb2下のライブラリと、include下のヘッダーを使っている。正確にはMakefileを参照。

・解凍ファイルの中のFWLibや、USBLibはV1.0で、現在のV3と混在させると動かない可能性がある。
・出来上がったhexファイルをDfuか、フラッシュローダーでファームに書き込む。
・STM32の電源を入れ、PC側の端末プログラムでUSBのVCPに接続し、何かキーを入力すると、WelComeメッセージが出る。

| | コメント (12) | トラックバック (1)

« 2009年5月 | トップページ | 2009年7月 »