2007-02 << 2007-03 >> 2007-04

2007-03-11 (日)

*AVRライタ

avrspxを今回作ったライタに対応させる.最低限の機能はテストできた.

プログラムの読み出しが1バイトずつしか出来ないので,Verifyが遅い.まとめて転送できるようにしたいけど,2313側のメモリがもう全く空いていない.あと,転送速度の設定も出来るようにしたいのだけど…….どうしてくれようか.せめてあと数十バイトあれば….

C言語上で出来る最適化は殆ど手詰まりなので,あとはアセンブラで書き直せば少し削れそう.

やっぱり,2KバイトのプログラムでUSBを使ったAVRライタは実用じゃないという結論?せっかく,HIDの扱いを思い出したから,ポインティングデバイスでも作ってみようか.MicrosoftのHIDの情報が整理されていて分かりやすい.

gccって,C言語のラベルはコンパイルした時点で「.L5:」みたいな無意味な名前にされてしまうんですね.ちょっと不便.コンパイルオプションで指定できないのかな.

*avr-gccメモ

なんか,gccがすごく気に食わないコードを生成するのですが,コンパイルオプションが悪いのかなぁ….

到達不可能な場所から呼ばれている関数が残ることがある

到達不可能なコードは最適化時に消してくれますが,そこから呼ばれている関数が残ってしまうことがあります.関数にstaticが付いていても,安心できません.

scrc,scrs命令を意識

AVRには,特定のビットを見て一命令スキップする便利な命令があります.avr-gccはif文の中身が一命令で済み,条件を左右するのが1ビットのみな場合,scrs命令を使ってくれるようです.

a が 0 か 1 の場合は a!=0 として判定するよりも, a&1 で判定しましょう.

整数リテラルをintとして扱う

255以下の整数はunsigned charとして扱って欲しいところ.具体的には,aがchar型だったとして「a&0x22」とかを計算すると,andi命令は副作用があるので,aを別レジスタにコピーする.そのときに,16ビットに拡張してから0x22とのandiを取ろうとすることがあるようです.

    if (a&0x22) {
        // ...
    }

    uint8_t tmp=0x22;
    if (a&tmp) {
        // ...
    }

上のより下の方がコードサイズが小さくなることがある.

リテラルをキャストしても無効っぽいので,「inline static uint8_t byte(uint8_t t) {return t;}」という関数を作ってしまう手もある.C言語の整数のサフィックスになんでchar型に相当するものが無いんでしょうか.

シフトには気をつける

AVRには任意ビットのシフト命令がありません.シフトで変なコードが生成されやすいです.

8ビットシフトは,バイトごとの移動でやってくれますが,算術シフトだと,符号のための分岐命令が出てきたりします.

「||」はなるべく避ける

「||」の左右の式の間の最適化は殆どされないようです.評価順序がどうでも良い場合は,「|」で繋ぎましょう.

スタックを使っていなくてもスタックポインタを初期化する

これはどうしようも無いかも…….コンパイル後に手で消しましょう.というか,C言語でスタックを使わないプログラムとか書いてはいけません.

2007-02 << 2007-03 >> 2007-04