mikroPascal vs. C na AVRy

Jan 30, 2007 11 Replies

Witajcie.



Wziąłem prosty program i skompilowałem go dwóch środowiskach programistycznych celem porównania wielkości kodu wynikowego.


  1. Mikropascal
  2. AVR Studio + GCC

Zadaniem programu testowego było utworzenie migacza z diody LED.



W C:



#include <avr/io.h>



#include <util/delay.h>



#define F_CPU 4000000 #define CYCLES_PER_US ((F_CPU+500000)/1000000)



#define LED_ON sbi(DDRD,PD0);sbi(PORTD,PD0) #define LED_OFF sbi(DDRD,PD0);cbi(PORTD,PD0)



int main (void) { for (;;) { LED_ON; _delay_ms(1000); LED_OFF; _delay_ms(1000); } return (0); }


  1. Pascal:

program miagacz;



procedure wait; begin Delay_ms(300); end; begin DDRD:=$FF; while true do begin PORTD:=$FF; // włącz wait; PORTD:=$00; // wyłącz wait; end; end.


Wynik był następujący (porównanie wielkości pliku .hex):



C: 9697 bajtów + 13 bajtów plik *.eep



mikroPascal : 300 bajtów



Jak zminiejszyć "objętość" programu w C ?



Chciałem wybrać C jako narzędzie do oprogramowania chipów ale składnia i prostota mikroPascala zdecydowanie przemawia za nim.



Pozdrawiam L.


Włącz opcję -Os w GCC.

pozdrawiam Krzysztof Kajstura

napisz w³asny delay.h+delay.c

Mi wysz³o takie co¶: #include <avr/io.h>

#include "delay.h"

#define LED1_ON {PORTD |= 0x01; } // PD0 #define LED1_OFF {PORTD &= ~(0x01); } // PD0

/*

------------------------------------------------------------- G³ówna procedura

-------------------------------------------------------------

*/ int main(void) { DDRD |= 1 << 0; // PD0- output for (;;) { LED1_ON; delay1s8(1); LED1_OFF; delay1s8(1); } } 194 bajty mi wysz³o, a jak u¿y³em standardowej biblioteki delay: 206 bajty, I przy ró¿nych optymalizacjach: 0 - 1114b 1 - 552b 2 - 230b 3 - 242b s - 206b Oczywi¶cie w drugim przypadku z <ulil/delay.h> ,a z piewrszym nie chce mi siê :) .... A zreszt± co mi tam :D : 0 - 376b 1 - 194b 2 - 218b 3 - 230b s - 194b

Wszystkie testy na AVR-GCC 3.4.6

Strasznie kiepskie to GCC :) Ja w IARze wycisn±³em z w³asn± bibliotek± delay.h zaledwie 122 bajty kodu. Wywalaj±c z biblioteki delay.h mno¿enie móg³bym urwaæ jeszcze pare bajtów :)

Nie chce mi siê pisaæ tak wygl±da moja delay.c: void delay100us8(uint8_t t) { while (t>0) { delayus8(100);

--t; } }

void delay1ms8(uint8_t t) { while (t>0) { delay100us8(10);

--t; } }

void delay100ms8(uint8_t t) { while (t>0) { delay1ms8(100); t--; } }

void delay1s8(uint8_t t) { while (t>0) { delay100ms8(10); t--; } }

Tak jak widzisz wywo³uje hierarchicznie :) ,a nie od rêki :)

Legato napisał(a):

A dlaczego dla porównania nie napisałeś takiego samego migacza w asemblerze? Kod wynikowy będzie liczył pewnie kilkadziesiąt bajtów, kod źródłowy nie będzie raczej dłuższy ani bardziej skomplikowany niż w języku C. Porównuj lepiej długość kodu binarnego (po konwersji hex2bin) a nie pliku hex.

Wracając do tematu: sam kod wynikowy "właściwy" funkcji migającej w C ma kilkanaście bajtów, dodatkowo funkcja opóźniająca nieco dodaje. Reszta to biblioteka standardowa (głównie start programu w C). Można oczywiście pewnymi sztuczkami wyeliminować te dodatki, ale tylko w tym konkretnym przypadku.

Twoją funkcję sprawdziłem kompilując kod dla procesora ATmega128 kompilatorem avr-gcc 4.1.1 (WinAVR 20070122). No to po kolei:

1) używasz chyba starego kompilatora gcc, w nowej wersji nie ma już makr sbi ani cbi - zastąpiłem odpowiednimi sekwencjami |= i &=~ 2) wynikowy plik binarny ma 228 bajtów (w Makefile'u nie dołączam bibliotek do printf'ów ani matematycznej - może to u Ciebie jest problemem?) 3) pierwsze 140 bajtów kodu wynikowego to wektory przerwań, tu można oszczędzić najwięcej nie korzystając ze standardowych plików startowych (opcja -nostartfiles) ale wtedy najczęściej musiałbyś zapewnić także własne funkcje: zerującą sekcję danych .bss (__do_clear_bss) i przepisującą sekcję .data (__do_copy_data) a wcześniej ustawić wskaźnik stosu i wyzerować r1 4) oczywiście dla mniejszych procesorów będzie mniej wektorów przerwań - program skompilowany dla np. ATtiny22 (wykorzystujący PORTB i DDRB bo nie ma portu D w tym procu) ma tylko 88 bajtów binariów 5) możesz zainicjować raz a dobrze rejestr DDR a potem tylko migać pinem portu - binaria schodzą do 86 bajtów 6) na koniec rozwiązanie totalne czyli wywalenie standardowego startupu (patrz pkt. 3) i niekorzystanie z biblioteki standardowej (opcja

-nostdlib) daje wynikowy plik binarny długości 28 bajtów.

Czy taka optymalizacja ma sens? Oczywiście nie ale to już inna sprawa.

Finalny kod źródłowy w C dający 28-bajtowy binarny plik wynikowy (do linkera dorzucone opcje -nostartfiles i -nostdlib):

#define F_CPU 4000000

#include <avr/io.h>

#include <util/delay.h>

#define LED_ON PORTB |= (1 << PB0) #define LED_OFF PORTB &= ~(1 << PB0)

int main (void) { DDRB |= (1<<PB0); for (;;) { LED_ON; _delay_ms (1000); LED_OFF; _delay_ms (1000); } return 0; }

Adam Dybkowski snipped-for-privacy@45wp.pl napisa³ w news:epot2n$kak$ snipped-for-privacy@nemesis.news.tpi.pl...

[...]
[...]

Nie, panie Adamie! "Finalny kod ¼ród³owy" ma zawsze dok³adnie tyle samo bitów, tj. tyle, ile potrzeba do zdefiniowania ¶ci¶le to¿samej maszyny Turinga [mo¿e byæ w dowolnie innej formie ¶ci¶le to¿samego "rachunku/jêzyka"].

Tego typu "pojêcia" jak "finalny kod ¼ród³owy" to informatyczka dla bardzo ma³ych ch³opców, istniej±ce tylko po to, by ci mogli siê ¶cigaæ w tym, który "ma wiêkszego"... [p. ni¿ej: <<zwyk³em je zostawiaæ dla m³odzie¿y, która lubi studiowaæ raporty typu best buy>>]

To jest b³±d ZASADNICZY, jako¶ciowy, dotycz±cy fa³szywego sposobu pseudomy¶lenia opartego o _znajomo¶æ_ uruchamiania black-box'ów. To b³±d analogiczny do sposobu 'my¶lenia' (czyt. kojarzenia) "naj- lepszego d¿okeja" vs "biologa-koniologa". Jeden i drugi mog± twierdziæ, ¿e na koniach to "znaj± siê najlepiej ze wszystkich", ale... który ma racjê ? Zauwa¿ pan, i¿ ten drugi w ogóle mo¿e nie umieæ je¼d¼iæ na koniu.

Proponujê ma³e æwiczenie (mentalne): proszê po³o¿yæ na stole przed sob± banana, po czym zastanowiæ siê (g³êboko) jakie dzia³ania podejmie wobec owego przedmiotu: a) ma³pa, b) dziecko, c) bananomatyk (czyt. informatyk stosowany), d) biolog. (z podzia³em na dzia³ania widzialne - które s± absolutnie nieistotne (je¶li ???) - i niewidzialne tzn. _mentalne_). Wystarczy zauwa¿yæ, i¿ dok³adnie ostatnim celem (motywem dzia³ania) osob- nika typu d) bêdzie chêæ rywalizacji w zaspokajaniu intencjonalno¶ci osob- ników rodzaju a), b) czy c). [Chyba ¿e d) jest d) tylko z zewn±trz/"na oko", bo w ¶rodku bywa zwyk³ym a).] A je¶li spróbowaæ 'uzmys³owiæ' osobnikowm typu abc) motywacje d), to zaw- sze i nieustaj±co otrzymamy efekt: "A o czym w ogóle ten cymba³ bredzi jak pot³uczony???"

Powy¿sze jest równowa¿ne stwierdzeniu, i¿ ¿adnego d¿okeja (choæby najle- pszego w d¿okejstwie) ¿aden koñ _jako_taki_ w ogóle nie interesuje, i sum- ma summarum, "d¿okej" zna siê na koniach równie "dobrze", co moja pani np. na elektryczno¶ci (bo zna obs³ugê kontaktów, ¿elazka itd.).

A'propos polecam... o¶li most:

<< Raz nawet uda³o mi siê wyj¶æ na jasnowidza. Sprowadzono mnie do konaj±cego systemu rozproszonego fakturowania, a ja nie tylko odmówi³em oglêdzin stanowisk pracy, ale nawet nie raczy³em za- pytaæ o wersjê u¿ywanej bazy danych (mia³em po temu dobry powód: wiêk- szo¶æ produktów uchodz±cych za bazy danych w ¶rodowisku pecetów jest mi doskonale obca). >> [ z
formatting link
] i dalej: <<Szef firmy, który asystowa³ mi przez ca³y czas (bo te¿ siê mia³ za infor-matyka), nie móg³ wyj¶æ z podziwu, ¿e ja to tak wszystko robiê "na sucho", niczego nie ogl±dam na ekranie. On to w³a¶nie doszed³ do przekonania, ¿e jestem jasnowidzem. Pe³en podziwu chcia³ mnie zaanga- ¿owaæ do nadzoru nad rozbudow± systemu, bo firma ro¶nie. Zapyta³em, czego siê spodziewa po rozbudowanym systemie. Zacz±³ wyliczaæ, czego to on nie zamierza kupiæ: i serwer transakcji, i drukarki laserowe, i 117 wersjê sieci, i kilometry szklanego drutu (bo kumpel tanio sprze- daje). Przerwa³em mu, bo mnie te rzeczy dosyæ nudz± i zwyk³em je zo- stawiaæ dla m³odzie¿y, która lubi studiowaæ raporty typu best buy. [...] Teraz to ja wprowadzam potencjalnych kontrahentów na o¶li most. Z najpoczciwsz± min±, na jak± mnie staæ, patrzê takiemu g³êboko w oczka i pytam: no, a jak ju¿ zrobimy panu ten system-marzenie, jak rusz± dyski, rozjarz± siê monitory, zamigoc± diody na przy³±- czach, po klawiaturach zaklekoc± wytrenowane palce operatorek i ze szczelin super drukarek zaczn± bezszelestnie wysuwaæ siê super- dokumenty, to po czym pan szanowny pozna, ¿e system jest dla pañ- skiej firmy przydatny, ¿e siê to wszystko panu op³aca? Kontraktów co prawda nadal nie dostajê, ale jak s³odko jest patrzeæ na te opadaj±ce szczêki, niemal dos³ownie s³yszeæ pisk ma³o u¿ywa- nych opon mózgowych po nag³ym wci¶niêciu hamulca zw±tpienia: jak to, to oprócz tego piêknego widoku doskonale dzia³aj±cego uk³adu najnowocze¶niejszych urz±dzeñ, ma siê to jeszcze op³acaæ? To sy- stem informatyczny nie jest tak jak obraz Che³moñskiego czy innego Fa³ata: kupuje siê, bo drogi i wiesza na ¶cianie, ¿eby mnie podzi- wiano, ¿em tyle szmalu wyda³? To siê ma jeszcze op³acaæ? Przecie¿ nowoczesno¶æ jest bezcenna! A ju¶ci! Czy aby przypadkiem nie bez- warto¶ciowa? [...] >>

JeT.

U¿ytkownik "Jerzy Turynski" snipped-for-privacy@polaboax.com napisa³ w wiadomo¶ci

Wielkie ciach!

£a³, niez³y kawa³ek beletrystyki, tylko co to wnosi do tematu?

JJJK

Adam Dybkowski napisał(a):

Wiem, wiem ale nie napisałem dlatego, że niestety nie znam assemblera :(

Zdecydowaną poprawę wniosło ustawienie opcji -Os zaproponowanej przez kol. Krzysztof Kajstura oraz wyeliminowaniu zbędnych bibliotek.

Masz rację. Mam avr-gcc-3.4.1 Zabieram się do aktualizacji :)

Powiem tak, skompilowałem to "standardowo" jak leci w AVRStudio bez zastosowania wszelakich "optymizerów" kodu. Stąd wyszło jak wyszło. Do następnych kompilacji zastosuję się do porad Twoich jak i innych kolegów.

Dzięki Tobie i innym za fajną lekcję :)

Dopiero startuję z pisaniem w C na AVRy więc Twoje uwagi są dla mnie cenne. Jak by co to pozwolę sobie zamącić Wam w tym temacie głowę.

Pozdrawiam L.

Adam Dybkowski napisał(a):

Nie udało mi się dogonić mistrza. Wpisując Twoje parametry udało mi się osiągnąć postęp który jest dość znaczny :)

349 bajtowy plik hex i 116 bajtowy bin

Gdybyś był uprzejmy przeglądnąć plik makefile byłbym Ci wdzięczny. Oto on:

############################################################################### # Makefile for the project Migacz ###############################################################################

## General Flags PROJECT = Migacz MCU = atmega8 TARGET = Migacz.elf CC = avr-gcc.exe

## Options common to compile, link and assembly rules COMMON = -mmcu=$(MCU)

## Compile options common for all C compilation units. CFLAGS = $(COMMON) CFLAGS += -Wall -gdwarf-2 -nostartfiles -nostdlib -DF_CPU=4000000UL

-Os -fsigned-char CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

## Assembly specific flags ASMFLAGS = $(COMMON) ASMFLAGS += $(CFLAGS) ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

## Linker flags LDFLAGS = $(COMMON) LDFLAGS +=

## Intel Hex file production flags HEX_FLASH_FLAGS = -R .eeprom

HEX_EEPROM_FLAGS = -j .eeprom HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings

## Library Directories LIBDIRS = -L"F:\avr\winavr\avr\include\avr"

## Objects that must be built in order to link OBJECTS = migacz.o

## Objects explicitly added by the user LINKONLYOBJECTS =

## Build all: $(TARGET) Migacz.hex Migacz.eep size

## Compile migacz.o: ../migacz.c $(CC) $(INCLUDES) $(CFLAGS) -c $<

##Link $(TARGET): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET) avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@

%.eep: $(TARGET) -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0

%.lss: $(TARGET) avr-objdump -h -S $< > $@

size: ${TARGET} @echo @avr-size -C --mcu=${MCU} ${TARGET}

## Clean target .PHONY: clean clean: -rm -rf $(OBJECTS) Migacz.elf dep/* Migacz.hex Migacz.eep

## Other dependencies

-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)

Pozdrawiam L.

In the darkest hour on Wed, 31 Jan 2007 07:28:09 +0100, Janusz <janusz snipped-for-privacy@poczta.onet.pl> screamed:

Absolutnie nic. To taka informatyka przez duże U.

Jerzy Turynski napisał(a):

:-o Ale o so chozi?

Pod pojęciem "finalny kod źródłowy" przytoczyłem poprawioną wersję kodu źródłowego załączonego przykładu programu w języku C, uwzględniającą ograniczenia wymuszane przez nowszą wersję kompilatora avr-gcc takie jak brak makr cbi i sbi. Poza tym w języku C często na kilka sposobów można zapisać sekwencję dającą ten sam binarny kod wynikowy - więc mój "finalny kod źródłowy" to tylko przykład poprawienia programu migającego diodą na jeden z wielu możliwych sposobów.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required