ATTiny13 — avr-gcc Hello Worldは100バイト以上を使用しますか?


9

ATTiny13用のプログラムを書こうとしています。私の問題は、巨大なサイズの制約があることです。さて、私の最初のHello Worldプログラムを作成するとき、ライトをオン/オフするだけで100バイトのプログラムスペースが必要でした。このサイズを縮小するためにavr-gccに提供できるオプションはありますか?また、crt0には何がありますか?私はAVRアセンブリにあまり熱心ではないので、あまり理解していません。

このプロジェクトのアセンブリに立ち寄る必要はありません。


ちなみに、一部の人々はそれを「ブリンキー」プログラムと呼んでいます。
ヨハン

1
@ヨハン、まあ "blinkenlights"の綴りがわからなかった
Earlz

回答:


9

crt0は、uCの起動ルーチンです。ルーチンは、レジスタのセットアップとデータの初期化を実行します。

100バイトには、割り込みベクターテーブルが含まれていますか?ATtiny13についてはわかりませんが、ATtiny25 / 45/85には15の割り込みベクトルがあります。これには最大30バイトかかります。

gccにはcrt0にリンクするオプションがあります。AVR crt0.Sファイルを取得して変更できます。それほど長くはないので、難しくありません。


crt0ソースが見つからないようですが、crt1には割り込みベクターテーブルのようです。たぶんそれ
アールズ2010

私のシステムでもそれを見つけることができません:(ソースからすべてのツールをコンパイルしたので、そこにあると思いました。「crt0.S atmel」をググったら、スタートアップ、crt0、gccに関するAtmel app-notesのカップルたぶんそれらのドキュメントにいくつかのヒントがあるかもしれません
jluciani 2010

@jlu私は2つの違いを把握しようとしているが、まだスタックオーバーフロー上の任意のものが良いもらっていない:stackoverflow.com/questions/2709998/...
Earlz

2
avr-libcにはAVRチップのタイプごとに異なるCRTがあり、標準のavr-libcディストリビューションにはファイルの.oバージョンのみが含まれています。ATtiny13用のものは[avr-libc-path] /avr-3/lib/crttn13.oにあります
todbot

@todbotうーん。ああ、そうだ、私はそれを持っている/avr-libc-1.6.7/avr/lib/avr2/attiny13/crttn13.S
アールズ

19

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が必要です。


16

最終的な用途は何ですか?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);などを反転することを除いて、ほぼ同じコードを使用しています
Earlz

ええ、サイズは一定ですが、スタックフレームをセットアップするだけの場合、46バイトでもかなり重いようです
Earlz

2

スペースが不足している場合は、IARの組み込みワークベンチを試してください-それらの無料の「キックスタート」バージョンには4Kワードのコードサイズ制限があるため、ATTinyには十分であり、おそらくgccよりも最適化されています


1
最適化の比較は、高い競合の主題です。私はそこに行きません。
tyblu

1
@tyblu私も同意しますが、IARは、たとえばavr-gccよりも小さいバイナリを生成することで知られています。
Morten Jensen

1

このようなデバイスはアセンブラでプログラムされることが多く、実行ファイルが小さくなります。努力し、それを使用することを学ぶ価値があります。


1
私は同意しますが、私見の目標は、デバイス全体をアセンブリでプログラムすることではありません(これは頻繁に行われていることを知っており、私もこれを行いました)。また、コンパイラを頻繁に推測し、Cで記述したコードを最適化して実行可能ファイルのサイズを小さくできることがよくあります。
jpc
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.