ATTiny13 - avr-gcc Merhaba Dünya 100 bayttan fazla kullanıyor?


9

ATTiny13 için bir program yazmaya çalışıyorum. Benim sorunum, büyük boyut kısıtlamaları olması. İlk Hello World programımı yaparken, sadece bir ışık açmak ve kapatmak 100 baytlık program alanı gerektirdi! Bu boyutu küçültmek için avr-gcc'ye verebileceğim herhangi bir seçenek var mı? Ayrıca, crt0'da neler var? AVR meclisine çok hevesli değilim, bu yüzden fazla anlamıyorum ..

Bu proje için meclise gitmek istemiyorum ..


Küçük bir yan not olarak, bazı insanlar buna "Blinky" programı diyorlardı.
Johan

1
@Johan iyi "blinkenlights" büyü nasıl emin değildi
Earlz

Yanıtlar:


9

crt0, uC için başlangıç ​​rutinidir. Rutinler, kayıtların kurulumunu ve ayrıca verilerin başlatılmasını gerçekleştirir.

100 bayt kesinti vektör tablosunu içeriyor mu? ATtiny13 hakkında emin değilim ama ATtiny25 / 45 / 85'in 15 kesinti vektörü var. Bu 30 bayt alır.

gcc'nin crt0'ınızda bağlantı seçeneği vardır. AVR crt0.S dosyasını alıp değiştirebilirsiniz. Çok uzun değil, bu yüzden zor olmamalı.


Crt0 kaynağını bulamıyorum, ancak crt1'de bir kesme vektör tablosu gibi görünen bir şey var. Belki de budur
Earlz

Ben de benim sistemde bulamıyorum :( Ben kaynak olacağını tüm araçları derlenmiş bu yüzden orada olacağını düşündüm. Eğer "crt0.S atmel" için google Eğer başlangıç, crt0 ve gcc hakkında birkaç Atmel app notları Belki de bu dokümanlarda bazı ipuçları var
jluciani

@jlu İkisi arasındaki farkı anlamaya çalışıyorum ancak Stack Overflow'da henüz iyi bir şey elde etmedim: stackoverflow.com/questions/2709998/…
Earlz

2
avr-libc'nin her AVR yongası türü için farklı bir CRT'si vardır ve standart avr-libc dağıtımları yalnızca dosyanın .o sürümünü içerir. ATtiny13 için olan [avr-libc-path] /avr-3/lib/crttn13.o
todbot

@tobotbot hmm. Ah, evet evet var/avr-libc-1.6.7/avr/lib/avr2/attiny13/crttn13.S
Earlz

19

Nelerin üretildiğini görmek için avr-objdump -d .elf kullanabilirsiniz:

Biraz analiz edelim:

[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 bayt kesinti vektör tablosu (karşılık gelen kesintileri asla etkinleştirmeyeceğiniz konusunda ısrar edip söz verdiyseniz girişlerin en azından bir kısmı atlanabilir).

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'yi temizler (bunun gerçekten gerekli olduğundan emin değilim), 0x9f (RAMEND) 'i SPL'ye (yığın işaretçisi) yazar ve ana atlar. Son rjmp biraz gereksizdir. (asla anadan dönmeyeceğine söz verebilirsin)

00000020 <__bad_interrupt>:
  20:   ef cf           rjmp    .-34        ; 0x0 <__vectors>

Bu kesintiler için C'de bir tane yazılmamış olandan varsayılan kesme prosedürü (__vectors için olanla aynı kurallar)

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>

Ana işleminiz. Sıkı.

0000002a <_exit>:
  2a:   f8 94           cli

0000002c <__stop_program>:
  2c:   ff cf           rjmp    .-2         ; 0x2c <__stop_program>

Bu ikisi çok kullanışlı değil. _exit muhtemelen C standardı için gereklidir ve __stop_program olması gerektiği gibi çalışması için gereklidir.


16

Son başvurunuz nedir? Bir ATtiny13'ün 1kB flaşı vardır ve C ile çok şey yapabilirsiniz. Crt0, avr-libc C çalışma zamanıdır. Yığın işleme gibi şeyler içerir, böylece bağımsız değişkenlere ve döndürülen değerlere sahip işlevleri kullanabilirsiniz.

Gömülü C kurulumu için 100 bayt çok kötü değil ve sabit boyutu. Program mantığı satırlarını ikiye katlamak mutlaka 200 bayt yapmaz. Hangi optimizasyon seviyesinde derliyorsunuz? "-Os" da olmalısın. Ve bunu nasıl derliyorsunuz? Avr-libc sitesinden sunulan demo projelerde yer alan Makefiles oldukça iyi ve kapsamlı.

Aşağıdaki basit LED açma / kapama programı, avr-gcc 4.3.3 üzerinde "-Os" bulunan bir ATtiny13'te 62 bayt alır. CrossPack-AVR'den:

#include <avr / io.h>
#include <avr / delay.h>

int main (geçersiz)
{
    DDRB | = _BV (PB3);
    yaparken (1) { 
        PORTB | = _BV (PB3);
        _delay_ms (200);
        PORTB & = _BV (PB3);
        _delay_ms (200);
    }
}

_Delay_ms () çağrılarını kaldırmak 46 bayt yapar.

ATtiny13'teki daha büyük bir örnek Smart LED prototiplerim . Bu kod, 3 kanallı bir PWM yazılımı, bir HSV-RGB renk dönüşümü, bir durum makinesi içerir ve iki düğmeyi okur. Özellikle iyi yazılmamış ve 864 baytta geliyor. Avr-gcc 3.x altında daha da küçüktü. (bazı nedenlerden dolayı avr-gcc 4 neredeyse tüm programların birkaç bayt büyümesini sağlamıştır)


avr-gcc -std=c99 -Wall -Os -mmcu=attiny13 -o hello.out helloworld.c(kendi oluşturduğum) dosyamdaki ilgili satırdır. ve kullandığım LED'i çevirmek dışında neredeyse aynı kodu kullanıyorum PORTB &= ~(1 << LED);ve böyle
Earlz

Ve evet, boyut sabittir, ancak tek yapması gereken bir yığın çerçeve oluşturmaksa 46 bayt bile biraz ağır görünüyor
Earlz

2

Alanınız kısıtlıysa, IAR'ın Gömülü çalışma tezgahını deneyin - ücretsiz 'kickstart' sürümünün 4K kelime kodu boyut sınırı vardır, ATTiny için çok fazla ve muhtemelen gcc'den daha iyi optimizasyon


1
Optimizasyon karşılaştırmaları yüksek çekişmeli bir konudur. Oraya gitmezdim.
tyblu

1
@tyblu Katılıyorum, ancak IAR örneğin avr-gcc'den daha küçük ikili dosyalar ürettiği biliniyor. Mikeselectricstuff'a da katılıyorum.
Morten Jensen

1

Bunun gibi cihazlar genellikle birleştirici içinde programlanır, bu da daha küçük yürütülebilir dosyalar sağlar. Çaba göstermeye ve kullanmayı öğrenmeye değer.


1
Kabul ediyorum, ancak IMHO'nun amacı montajdaki tüm cihazları programlamak değil (bunun sıklıkla yapıldığını ve bunu da yaptım) ama C derleyicisinin arkanızdan ne yaptığını çözmek ve doğrulamak. Ayrıca, derleyiciyi ikinci kez tahmin edebileceğiniz ve küçük çalıştırılabilir boyut elde etmek için C'de yazdığınız kodu optimize edebileceğiniz anlamına gelir.
jpc
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.