« LEDマトリックスで遊ぶ | トップページ | Mega128で漢字フォント表示 »

2008年9月 3日 (水)

スタック領域とSRAM変数

遂に真犯人をつきとめた(6/2/08)
 これまで、がた老研究所を悩ましてきたトラブルの原因が外部の支援でほぼ特定でき、とても嬉しい気持ちでこの記事を書いている。 LEDマトリックスでUARTバッファーを小さくしたら一気にトラブルが解消したため、これまでの色々なトラブルも含めてまとめてAVRWikiに「WINAVRの外部変数の不具合?」というタイトルで投稿したらすぐ反応があった。最初のレスポンスは少し違っだが、さすが経験者揃いのメンバーである。私が見落としていた問題点をすぐ明らかにしてくれた。いやいや仲間と言うのは持つべきものである。本当にありがたい。

 そうなのだ。限られたSRAMスペースにスタック領域がとられていることをすっかり見落としていた。このあいだは定義したバッファーサイズと実際のSRAMサイズが合わないことを不審には思ったけれど、それ以上の追求はしなかった。冷静に考えていれば、今度のTiny2313などSRAMはわずか128バイト、80バイトものUARTバッファーをとれば、残りは40 数バイトしかなく、ちょっと沢山pushをしてレジスタを待避させているプログラムなどであっというまに届いてしまう。それに早く気づくべきだった。

 大型機育ちなので、メモリバイオレーションには敏感ではない。大型機だと、あっというまに異常終了してプログラムそのものが通らないしかけが出来ているのでプログラマーは余り心配しないですむ(起きてから考える。ただし自分のプログラムのなかで自らのエリアをつぶすとわからない)。これまでTiny26やTiny2313(SRAMが128バイト) で起きて、Tiny861(512バイト)で起きなかったこと、I2Cインタフェースが72 バイトの送受信バッファーを半分にしてトラブルが解消したこと、データの破壊がUARTなどの割込みプログラムのあとで起きること、すべてがこのことを裏付ける。

 このブログでこれまでコンパイラーのバグだと言っていたのは、ほぼすべてが、このレジスタ値の待避などのスタックデータがSRAM変数域に被ったことが原因だったと思われる。WinAVRコンパイラーのみなさん、リンカーのみなさん、疑ってごめんなさい。

 AVRWikiでのやりとりでは、メモリマップの取り方をついでに質問をしたら、これも直ちに教えてもらった。 AVRstudioで出力されるlinkmapは実体のアドレスマップではないが、ELFファイルをavr-nmコマンドにかけると、実際のメモリーアロケーションが得られることがわかった。 これでビクビクしながらメモリを定義するのでなく事前に確認して予防ができる。寿命がきたとされたTiny26はまだ動く可能性が高くなってきた(LCD基板は2313に換えてしまったので確認できない)。

 LEDマトリックスは順調だ。わずか128バイトだけどEEPROMを利用して、自分の名前の漢字フォントをLED上で作り登録した。16ヶ登録できる。8×8のエリサフォントでも結構視認性が高い。携帯のムービーで動画を記録する。 こういうと叱られるが、みんながまあ愚にもつかないLEDマトリックスではまる理由がわかる気がしてきた。

 何度も書くように、始めは何の反応もしないLEDや、IC、抵抗などの部品が集められ半田付けされ、チップにプログラムが書かれると、生き生きと点灯して意味あるメッセージを送り出す。それが単なる点滅でも楽しいのに、自分の名前がLED面の上を流れるのを見ていると何故か嬉しくてたまらない。まあ、これは作ったものにしか分からないかもしれないが。

 ただ、Tiny2313はフォントのエディターまで作ったら、フラッシュがもう満杯になった。残念だけれど、861かMega168に移行せざるを得ない。今日は仕事の帰り、調子に乗ってLEDマトリックスをさらに2つ買い足してしまった。これで8×32の本格的な電光掲示板になる。

3色でLEDマトリックスが動いた(6/6/08)A6061329
 勢いで、というより、秋月の商品棚に2色のLEDマトリックスが2つしか残っていなかったのであせって買い込んだようなものなのだが(案の定その後は欠品)、よく考えてみたらまだ単色でしか動いていない。せっかく赤と緑のLEDがついているのだから、赤だけでなく緑もつけてみたい。同時に光らせるとオレンジか黄色の計3色でドットが表示できる。基板にはもう1色用のシフトレジスタのスペースもつけアートワークも出来ている。

 マトリックスを追加する前にその配線をすることにした。予想通り追加の配線は厳しい。UEW線での基板上の交差はしないで、基板の表にジャンパー線を回すという決まりを作っていたのだが、これを守ることが出来ず、いくつかの交差を許してしまった。まあ、UEW線の絶縁性は高そうで、ウェブにはこれを接着剤でかためて配線している例もあるのでそう心配はしていない。

 2色となると配線だけでなくプログラミングも難しい。ダイナミック表示をどうするかが問題だ。HC595はラッチがついているので、相当な長いデータをシフトレジスタに送り込んでも表示切替には気を使わなくてすむのはありがたい。しかし、2313はもう数十バイトしかフラッシュが残されていないので、プログラムがなかなかうまく組み込めない。

 今まであった4ヶのバッファーの2つづつを赤と緑のフォントエリアにして、それを同時にスキャンする方法によって2313で3色表示のスクロールが可能になった。と、簡単に書いたけれど、これを思いついて実際に動くようになるまではやはり2日ほどかかった。

 まあ、これが楽しいのだ。プログラムはまさしく考えたようには動かず、書いたようにしか動かない。最初、色コードのようなことを考えたが、各ドット単位に色を変えるところまで考えると断然この方法のほうがわかりやすい。ただ、シフトレジスタへのデータ送り込みと、各列へのダイナミックな動き、さらにそれ全体をリングバッファーのように折り返す動きを考えながら2色発光させるロジックはちょっとしたパズルである。それだけに思い通りに動いたときの満足感は、人のソースで動いたときのものとは比べ物にならない。

 ウェブには予想通り沢山、実験記があげられていてソースも掲載されているようだが、今度はなるべくこれを見ないようにしている。SDカードから文字フォントを読み込んで、長いテキストが電光掲示できるようになってからソースを見比べてどちらが優雅か比較してみようと思っている。
 前記事にuploadしたプログラムはこの3色を表示するTiny2313の最新のプログラムです。ソースをご覧になればわかるように、UARTのコマンドのいくつかはフラッシュメモリ不足でコメントアウトされています。

|

« LEDマトリックスで遊ぶ | トップページ | Mega128で漢字フォント表示 »

AVR」カテゴリの記事

コメント

コメントを書く



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


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



トラックバック


この記事へのトラックバック一覧です: スタック領域とSRAM変数:

« LEDマトリックスで遊ぶ | トップページ | Mega128で漢字フォント表示 »