「PIC AVR 工作室」サイトの日記的なブログです。
サイトに挙げなかった他愛ないことを日記的に書き残してます。
PIC AVR 工作室 ブログ



昨日の続き。
http://brown.ap.teacup.com/nekosan0/1222.html

ようやく思ったように動いてくれた…。
WINAVRでインラインアセンブラ使って、ある程度正確な
遅延時間を作る処理のこと。


なぜ遅延時間が不正確なのか。
シミュレータのディスアセリストを眺めながら1ステップ
1ステップ追っていってみたら、16ビット変数(uint16_t型)
をアセンブラに渡すところで上位下位の8ビットが逆に渡ってた。
そりゃ無茶苦茶ですがな。

直してみてからあらためてシミュレーション。


微妙に遅延時間が長い…

遅延時間が伸びてる最大の理由は、シミュレータ画面上で
追ってみたら判明。1マイクロ秒単位の引数を、関数の先頭で
10マイクロ秒単位に丸める処理(単に10で割るという整数除算)
で300クロックほど要していることが原因みたい10マイクロ秒
単位の精度が欲しいのに、300クロック=30マイクロ秒
(@10Mhz)の誤差はでかすぎ。

仕様変更することにして、引数を10マイクロ秒単位で指定
することに。
それでも関数の引数(定数)内で10で割る処理を明記して
おけば、コードの可読性自体は悪化しないだろう、と。
定数式はコンパイル時に最適化されて引数は1/10単位の値で
展開されていることは確認済み。

これなら300クロックほどの遅延が無くなり、最低限で済む
のでとりあえずok。


いい感じになってきたので、きちんと一通り全部のロジック
をシミュレータ通して確認してみる。

…部分的におかしい。なんだこりゃ?


あらためてディスアセのリストを1ステップずつ追ってみると、
引数を1/10させてた時と違って、時間稼ぎ処理のサブルーチン
(今回インラインアセンブラ使った部分)が意図しない
インライン展開されちゃってる。

呼び出し箇所のすべてでインライン展開されちゃってるなぁ…。
まぁ、コードサイズ的にはそれでも800バイト程度程度だから
充分小さいんだけど、問題はその一つ一つ展開されたロジック
が変な状態ってこと。

具体的には、引数がきちんと渡されているところと、まともに
渡されてないところがあって、渡されていないところは
引数ゼロで処理しちゃって、ループを一気に抜けちゃう。


うーん。何だコリャ?
同じ関数を複数個所にインライン展開してるだけなんだけど、
複数個所ゆえにレジスタ割り当ての管理で支障をきたして
いるのかな?だったらインライン展開してくれるなよぅ…。
コンパイラ君…。

ロジック自体には間違えがなさそうなので、かくなる上は
コンパイルオプションの最適化引数を弄ってみる。

Os → O1に変更してみたら、サブルーチンがきちんとサブ
ルーチンとして独立して生成され、想定どおりの動きになった。
ヨシヨシ。
一方、O0もO2もO3もOsも全部だめ。一部は実行コードサイズが
馬鹿でかく(3KB超え)なっちゃうし、一部は上述のとおり
不完全なインライン展開で引数が渡ってくれない…。


とりあえずコンパイルオプションをO1にしたところで動いた
ので、これでよしとしてしまおうと思うんだけど、
こういう綱渡りって、コンパイラのバージョンアップが
致命傷になったりするから嫌いなんだよねぇ…。
(だからこの手のタイミングクリティカルなプログラムは
 いつもアセンブラで組んじゃうんだよな)

あとはアレかな。インラインアセンブルじゃなくて、
アセンブリ言語で書いたサブルーチンをC言語サブルーチン
として繋ぐってやつ。
http://avrwiki.jpn.ph/wiki.cgi?page=avrgcc%A4%C7%A5%A2%A5%BB%A5%F3%A5%D6%A5%E9%A4%F2%BB%C8%A4%A6
avrwikiでも解説されてるこれ。

コードの可読性って意味ではこっちの方がスマートな
気もするんだけど、これだと必ず関数のカタチにしないと
いけない(必ずサブルーチンコールのカタチとなり
オーバーヘッドが生じる)っていう点と、makeファイル
弄らないといけないっていう面倒くささがあるんだよな。


なんにしても、今回書いたコード。まだCとアセンブラの
引数周りについて少し心配なところがあるといえばあるん
だよな。100%理解できたのか?と言われたら、Noって
レベルだからなぁ。所詮付け焼刃なのだ。


まぁ今回は「想定どおりのhexファイル」ができたって
ことで、あとは実機に流し込んでリモコンが動作するか
どうかが確認出来たら凍結ってことにしよう…


winavrって、関数をインライン展開させないための
プリプロセッサってあったりするのかな?それがあれば
コンパイルオプション弄る必要が無いんだけどな…
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Inline.html
これか?いや、これの逆だな。



コメント ( 0 )
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする