しょうがないので、gcc-3.4.6 にデバイスを追加することにした。
準備)
前提として、binutils-2.18 を使うことにするので先にインストールしておく必要がある。
また、avr-libc-1.4.7 を使う。avr-libc でサポートされていないデバイスまで gcc に組み込むと 面倒なので、サポートされていることを確認しておく。
gcc へのデバイス追加)
gcc にデバイスを追加するには、gcc/config/avr の avr.c , avr.h t-avr の3つのファイルを編集する。基本的には他のデバイスのマネをすればよい。
avr.c :
○ avr_mcu_types にデバイスを追加する。デバイス名とデバイスの define は、avr-libc と一致させる必要がある。
ATtiny は、ARCHタイプ 2 にする。ATmega は普通 4 or 5 。8KB を超えるものは、5 を使う。
ちなみに、gcc-4.X では ARCHタイプ 25 が追加されている。このARCHタイプ は、新しいATtinyシリーズのように movw があるものに使用する。
ARCHタイプ3は、乗算命令がないが、8KBを超えるものに使用する。AT90USB162 はこれに該当。
8KB を超えると RCALL/RJMP命令が届かない場合が出てくる。同一ファイルにない関数呼び出しは、CALL命令を使用しなけばならないので、ARCH2 と ARCH3 , ARCH4 と ARCH5 の違いが必要。
AT90USB162 用に本当は、ARCH35が欲しいところだが、ないものは仕方がないので、ARCH3 にするわけだ。
avr.h :
○ LINK_SPEC にデバイスを追加する。-m avr1 〜 -m avr5 のどれかに追加し、さらに ATmega や AT90USB , AT90PWM などは、-Tdata =0x800100 のところにも追加する必要がある。
○ CRT_BINUTILS_SPECS に crtXXX.o の名前を追加する。適当に付けてはいけない。必ず avr-libc と同じ名前を付けること。
t-avr :
○ MULTILIB_MATCHES にデバイス名を追加する。
avr-libc-1.4.7の変更)
実は、at90usb162 , at90usb82 の定義が間違っている。乗算命令を持っていないので、avr5 ではなく avr3にしなくてはならない。
(当然だが)まず、avr5 → avr3 に変更した gcc をインストールしてから、次の変更をした avr-libc をビルドしなければならない。
○ at90usb162 と at90usb82 を avr/lib/avr5 から avr/lib/avr3 に移動した上で、avr/lib/avr5 , avr/lib/avr3 の Makefile.* および at90usb162 と at90usb82 の Makefile.* を書き換える必要がある。
○ さらに、configure.ac , configure も avr5 → avr3 の変更が必要。
この問題は、WinAVR-20070525 でも存在する。at90usb162 で期待どおりに動かない場合、乗算命令を使っている可能性がある。
生成した xxx.elf ファイルに対して、avr-objdump -d でアセンブルリストを作成し、mul を grep することでチェックすべし。
おまけ)
参考までにパッチを提示しておく。このパッチはあくまで参考。動作確認もできていないし、デバイスも適当に選択している。
○ gcc-3_4_6-avr-new-devs2.patch
○ avr-libc-1.4.7-usb162.patch
注)ディレクトリを移動したので patch のサイズが大きくなっている。パッチを当てた上で avr5 のもとの Makefile.* と比較すると変更点が分かる。
おまけ2)
WinAVR-20070525 で at90usb162 を正しく コンパイルするには、コンパイルのオプションを次のように変更する。ただし、リンクは、-mmcu=at90usb162 のまま変更しない。
-mmcu=at90usb162
↓
-mmcu=avr3 -D__AVR_AT90USB162__
乗算命令を使用しているライブラリを使わないことが前提なので注意。
なお、WinAVR プロジェクトには、このバグについて だいぶ前に報告されている。次のリリースでは修正されると思う。
追記:WinAVR と同じ gcc を作るには
WinAVR は、ソースを管理しているのではなく、パッチを管理している。CVS から取らなくても ブラウズしてちまちま取ってくれば OK 。ちなみに、00/10/11 は WinAVR 固有なので、Linux では必要ない。
おまけ: WinAVR (gcc-4.1.2) の at90usb82/162 を avr4/avr5 → avr3 に変更するパッチ。
○ 99-gcc-4.1.2-usb162.patch
おわりに
これで、WinAVR ベースの gcc-4.1.2 と 独自拡張の gcc-3.4.6 で USB910 TypeA (attiny861) , at90usb162 が動くようになった。
3.4.6 のほうを avr-gcc にしてメインに使うつもりだが、4.1.2 も avr-gcc4 で使えるようにしている。avr-libc-1.4.7/binutils-2.18 は共通でよいようだ。
普通は、4.1.2 の方がコードが小さくなるし、特に ATtiny で MOVW 命令を使ってくれるので高速なはずだ。でも、コードによってサイズが大きくなる場合がある。USB910 TypeB (ATtiny44) は、4.1.2 ではサイズがオーバしてビルドできない。というわけで両方のバージョンを使える環境が欲しかったのだ。
ちなみに、CVS から取ってきた WinAVR ベースの 4.2.2 はまだダメ。新しいチップに対応する必要があるなら、4.2.2へのパッチと上記を参考にして 4.1.2 に追加していくほうが良いと思う。
パッチを見ていると、ATtiny43U とか 知らないチップ名がいくつか見える。ひょっとしたら、新しい WinAVR が出る前に使いたくなるかも...