ATTiny13用のプログラムを書こうとしています。私の問題は、巨大なサイズの制約があることです。さて、私の最初のHello Worldプログラムを作成するとき、ライトをオン/オフするだけで100バイトのプログラムスペースが必要でした。このサイズを縮小するためにavr-gccに提供できるオプションはありますか?また、crt0には何がありますか?私はAVRアセンブリにあまり熱心ではないので、あまり理解していません。
このプロジェクトのアセンブリに立ち寄る必要はありません。
ATTiny13用のプログラムを書こうとしています。私の問題は、巨大なサイズの制約があることです。さて、私の最初のHello Worldプログラムを作成するとき、ライトをオン/オフするだけで100バイトのプログラムスペースが必要でした。このサイズを縮小するためにavr-gccに提供できるオプションはありますか?また、crt0には何がありますか?私はAVRアセンブリにあまり熱心ではないので、あまり理解していません。
このプロジェクトのアセンブリに立ち寄る必要はありません。
回答:
crt0は、uCの起動ルーチンです。ルーチンは、レジスタのセットアップとデータの初期化を実行します。
100バイトには、割り込みベクターテーブルが含まれていますか?ATtiny13についてはわかりませんが、ATtiny25 / 45/85には15の割り込みベクトルがあります。これには最大30バイトかかります。
gccにはcrt0にリンクするオプションがあります。AVR crt0.Sファイルを取得して変更できます。それほど長くはないので、難しくありません。
/avr-libc-1.6.7/avr/lib/avr2/attiny13/crttn13.S
avr-objdump -d .elfを使用して、何が生成されているかを確認できます。
少し分析してみましょう。
[jpc@jpc ~] avr-objdump -d avr.elf | sed -e 's/^/ /' | pbcopy
avr.elf: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
0: 09 c0 rjmp .+18 ; 0x14 <__ctors_end>
2: 0e c0 rjmp .+28 ; 0x20 <__bad_interrupt>
4: 0d c0 rjmp .+26 ; 0x20 <__bad_interrupt>
6: 0c c0 rjmp .+24 ; 0x20 <__bad_interrupt>
8: 0b c0 rjmp .+22 ; 0x20 <__bad_interrupt>
a: 0a c0 rjmp .+20 ; 0x20 <__bad_interrupt>
c: 09 c0 rjmp .+18 ; 0x20 <__bad_interrupt>
e: 08 c0 rjmp .+16 ; 0x20 <__bad_interrupt>
10: 07 c0 rjmp .+14 ; 0x20 <__bad_interrupt>
12: 06 c0 rjmp .+12 ; 0x20 <__bad_interrupt>
20バイトの割り込みベクトルテーブル(対応する割り込みを有効にしないことを主張して約束した場合、少なくとも一部のエントリは省略できます)。
00000014 <__ctors_end>:
14: 11 24 eor r1, r1
16: 1f be out 0x3f, r1 ; 63
18: cf e9 ldi r28, 0x9F ; 159
1a: cd bf out 0x3d, r28 ; 61
1c: 02 d0 rcall .+4 ; 0x22 <main>
1e: 05 c0 rjmp .+10 ; 0x2a <_exit>
SREGをクリアし(これが本当に必要かどうかはわかりません)、0x9f(RAMEND)をSPL(スタックポインター)に書き込み、メインにジャンプします。最後のrjmpは一種の冗長です。(メインから戻らないことを約束できます)
00000020 <__bad_interrupt>:
20: ef cf rjmp .-34 ; 0x0 <__vectors>
Cで上書きされていない割り込みのデフォルトの割り込み手順(__vectorsと同じルール)
00000022 <main>:
22: bb 9a sbi 0x17, 3 ; 23
24: c3 9a sbi 0x18, 3 ; 24
26: c3 98 cbi 0x18, 3 ; 24
28: fd cf rjmp .-6 ; 0x24 <main+0x2>
あなたのメインプロシージャ。タイト。
0000002a <_exit>:
2a: f8 94 cli
0000002c <__stop_program>:
2c: ff cf rjmp .-2 ; 0x2c <__stop_program>
この2つはあまり役に立ちません。_exitはおそらくC標準で要求されており、正常に機能するには__stop_programが必要です。
最終的な用途は何ですか?ATtiny13は1kBのフラッシュメ has リを持ち、Cでそれで多くをすることができます。crt0はavr-libc C実行時間です。スタック処理などが含まれているため、引数と戻り値を持つ関数を使用できます。
組み込みCセットアップの100バイトはそれほど悪くなく、一定のサイズです。プログラムロジックの行を2倍にしても、必ずしも200バイトになるわけではありません。コンパイルする最適化レベルを教えてください。あなたは「-Os」にいるはずです。そして、これをどのようにコンパイルしていますか?avr-libcサイトから入手できるデモプロジェクトのMakefileは非常に優れており、包括的です。
以下の簡単なLEDオン/オフプログラムは、ATV13で62バイトを取り、avr-gcc 4.3.3で「-O」を使用します。CrossPack-AVRから:
#include <avr / io.h> #include <avr / delay.h> int main(void) { DDRB | = _BV(PB3); while(1){ PORTB | = _BV(PB3); _delay_ms(200); PORTB&=〜_BV(PB3); _delay_ms(200); } }
_delay_ms()呼び出しを削除すると、46バイトになります。
ATtiny13のより大きな例は私のスマートLEDプロトタイプです。このコードには、3チャネルソフトウェアPWM、HSVからRGBへの色変換、ステートマシンが含まれ、2つのボタンを読み取ります。特に上手く書かれておらず、864バイトです。avr-gcc 3.xではさらに小さくなりました。(何らかの理由でavr-gcc 4はほとんどすべてのプログラムを数バイト増加させました)
avr-gcc -std=c99 -Wall -Os -mmcu=attiny13 -o hello.out helloworld.c
私のメイクファイル(自己作成)の関連する行です。そして、私が使用するLED PORTB &= ~(1 << LED);
などを反転することを除いて、ほぼ同じコードを使用しています
スペースが不足している場合は、IARの組み込みワークベンチを試してください-それらの無料の「キックスタート」バージョンには4Kワードのコードサイズ制限があるため、ATTinyには十分であり、おそらくgccよりも最適化されています