2010年9月27日月曜日

avr-gdbをインストールした、、

avr-gdbをインストールしました。 ターゲットマシンはFC13 x86_64

1) ftp://ftp.ring.gr.jp/pub/GNU/gdb/ から gdb-7.2.tar.bz2 をダウンロード
2) mkdir gdb-7.2_AVR
3) cd gdb-7.2_AVR
4) ../gdb-7.2/configure --prefix=/usr/local/avr-gcc4/ --target=avr
5) 途中で error: no termcap library found でおちる
6) ftp://ftp.ring.gr.jp/pub/GNU/termcap/ から termcap-1.3.1.tar.gz をダウンロード、インストール
7) make , make install

**情報追加
4) ../gdb-7.2/configure --prefix=/usr/local/avr-gcc4/ --target=avr --disable-nls

--disable-nlsを追加してコンパイルし直し、、

2010年9月26日日曜日

ひさしぶりに秋月に行ってきました

組み込み勉強会(別途この内容は書きます)のついでに、八潮の秋月に行ってきました。以前行ったときはもっとジャンクな物があって面白かったけれど、昨日は"普通の"秋月だったのがちょっと残念。FT2232のボードが欲しかっただけなのに、なんか気がついたらいろいろな物がかごに入っていて、お会計してびっくり。とりあえずこのボードが手に入ったのでJTAGkey cloneが作れる。またしばらく遊べそうです。

2010年7月2日金曜日

下で、kitaxさんからコメントをいただいている通り、じつはこれ、リンカ最適化の"-O"オプションで制御されます。
前回の結果はMakefileのこのオプションがコメントアウトされていて、"-O0"な状態でコンパイルされていたわけです。
で、これを"-Os"でやり直してみると、、

ver 3.4.6 では、

138 PORTB = 0x55;
139 84: 85 e5 ldi r24, 0x55 ; 85
140 86: 88 bb out 0x18, r24 ; 24

ver 4.4.3 でも、

120 64: 25 e5 ldi r18, 0x55 ; 85
:
152 PORTB = 0x55;
153 7c: 28 bb out 0x18, r18 ; 24

と、ちゃんと outを使った内容にコンパイルされます。コードサイズはそれぞれ、
ver 3.4.6

1 /usr/local/avr-gcc3/bin/avr-size led.elf
2 text data bss dec hex filename
3 154 0 0 154 9a led.elf

ver 4.4.3

1 /usr/local/avr-gcc4/bin/avr-size led.elf
2 text data bss dec hex filename
3 148 0 0 148 94 led.elf

と、ぎゅっと小さくなっています。 おそまつさま、、
割り込みを使わないこのプログラム、実はさらにコードサイズを小さくする秘策が、、

2010年6月20日日曜日

avr-gcc4の吐き出すコードって、、

avr-gcc ver.3 (3.4.6) と ver.4 (4.4.3) の吐くコードがどのくらい違うのか調べてみたくなって、簡単なプログラムを書いて実際にコンパイルしてみた。 プログラム自体はたわいもないもので、attiny2313のPORTBに繋がっているLED8個を1つおきに交互に点滅させるというもの。 で、実際のプログラムはこんな感じ。

1 /* led.c, test program for LED on and off */
2
3 #include <avr/io.h>
4

5 int main(void)
6 {
7 unsigned int i;
8
9 DDRB = 0xff;
10 DDRD = 0x00;
11 PORTD = 0xff;
12
13 for(;;){
14 PORTB = 0x00;
15 PORTB = 0xaa;
16 for( i=0; i&lt;30000; i++){
17 asm volatile ("nop");
18 }
19
20 unsigned int j=30000;
21 PORTB = 0x00;
22 PORTB = 0x55;
23 do{
24 asm volatile ("nop");
25 }while(j--);
26 }
27 }


最初は for() と do-while でどのくらい吐き出すコードが違うのか調べたかったのだが、こちらは期待どおりというか、大した違いは無かった。片方は順番に変数がインクリメントされていくし、片方はディクリメントされていく。 ところが、面白かったのは、何気に使っている PORTB = 0x55; がどんな風に変換されているのか調べてみたら、使っている avr-gcc のバージョンによって吐かれるコードが結構違うことに気がついた。 使ったavr-gccのバージョンは上に書いた通り。 実際に吐かれたコードは、

ver 3.4.6 は、

PORTB = 0x55;
a8: 85 e5 ldi r24, 0x55 ; 85
aa: 80 93 38 00 sts 0x0038, r24

レジスタ24に0xaaをロードしてSRAMの0x0038番地にr24を出力。AVRはmemory maped IOなので PORTBもメモリマップ上にいる。

ver 4.4.3 だと、これが↓こうなる。

PORTB = 0x55;
c2: 88 e3 ldi r24, 0x38 ; 56
c4: 90 e0 ldi r25, 0x00 ; 0
c6: 25 e5 ldi r18, 0x55 ; 85
c8: fc 01 movw r30, r24
ca: 20 83 st Z, r18


ver.3 では 6バイトで書けたものが ver.4では 10バイトも必要になっている。で、最終結果にもそれがちゃんと(?)反映されていて、それぞれ

ver.3.4.6
avr-size led.elf
text data bss dec hex filename
198 0 0 198 c6 led.elf


ver.4.4.3
avr-size led.elf
text data bss dec hex filename
238 0 0 238 ee led.elf


ちなみに、アセンブラで書くならきっとこう書くはず。

ldi r18, 0x55
out PORTB, r18

4バイトか、、、 何かのコンパイルオプションでこの状況は解決されるのだろうか?

2010年5月3日月曜日

gcc4.4.3 for avr-gcc インストール

** gcc-4.4.3 (avr-gcc) インストールメモ **

atmega32u4とat90usb1286を使いたいので、これらのデバイスに対応しているgcc4.4.3をインストールした。
gcc4以降、gmpとmpfrがgccコンパイル時に必要となっているのでそれらも同時にインストールした。


gmp
gmp-4.2.4
./configure


mpfr
mpfr-2.4.2
./configure --with-gmp-lib=/usr/local/lib --build=i686
configオプションに--with-gmp-libを追加。このオプションがないとgmpが見付からずにconfig時にエラーで落ちる。


binutils
binutils-2.20
../binutils-2.20/configure --target=avr --prefix=/usr/local/avr-gcc4


gcc
gcc-core-4.4.3
../gcc-4.4.3/configure --target=avr --prefix=/usr/local/avr-gcc4 \
--enable-languages=c --with-dwarf2 --disable-nls \
--with-mpfr-include=/usr/local/include --with-mpfr-lib=/usr/local/lib
configオプションに--with-mpfr-includeと--with-mpfr-libを追加。このオプションがないとmpfrが見付からずに
config時にエラーで落ちる。


avr-libc
avr-libc-1.6.2
../avr-libc-1.6.2/configure --build=i686-pc-linux-gnu --host=avr --prefix=/usr/local/avr-gcc4
avr-libc-1.6.8を試したが、どうしてもコンパイルが通らず断念。


atmega32u4もat90usb1286もソースをコンパイルが出来ることを確認した。

++ Myself ++

普通(?)のサラリーマン -- 生活のすきま時間にキーボードとはんだごてを持ち替えてプログラミングと電子工作してます