RTV forum PL | NewsGroups PL

Jak zredukować rozmiar kodu w C na AVR w porównaniu do mikroPascal?

mikroPascal vs. C na AVRy

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Jak zredukować rozmiar kodu w C na AVR w porównaniu do mikroPascal?

Legato
Guest

Tue Jan 30, 2007 3:11 pm   



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 (;Wink
{
LED_ON;
_delay_ms(1000);
LED_OFF;
_delay_ms(1000);
}
return (0);
}

2. 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.

Krzysztof Kajstura
Guest

Tue Jan 30, 2007 3:21 pm   



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

Włącz opcję -Os w GCC.

pozdrawiam
Krzysztof Kajstura
--
www.kristech.eu
Development Boards and Tools

Saper/nolin11
Guest

Tue Jan 30, 2007 8:14 pm   



Legato wrote:
Quote:
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

napisz własny delay.h+delay.c

Quote:

#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 (;Wink
{
LED_ON;
_delay_ms(1000);
LED_OFF;
_delay_ms(1000);
}
return (0);
}


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 (;Wink {
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ę Smile ....
A zresztą co mi tam Very Happy :
0 - 376b
1 - 194b
2 - 218b
3 - 230b
s - 194b

Wszystkie testy na AVR-GCC 3.4.6


--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700

Saper/nolin11
Guest

Tue Jan 30, 2007 9:10 pm   



Piotr Chmiel wrote:
Quote:
On Tue, 30 Jan 2007, Saper/nolin11 wrote:

}
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ę Smile ....
A zresztą co mi tam Very Happy :
0 - 376b
1 - 194b
2 - 218b
3 - 230b
s - 194b

Wszystkie testy na AVR-GCC 3.4.6

Strasznie kiepskie to GCC Smile
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 Smile

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 Smile ,a nie od ręki :)

--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700

Adam Dybkowski
Guest

Wed Jan 31, 2007 2:54 am   



Legato napisał(a):

Quote:
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.
[...]


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

mikroPascal : 300 bajtów

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 (;Wink
{
LED_ON;
_delay_ms (1000);
LED_OFF;
_delay_ms (1000);
}
return 0;
}


--
Adam Dybkowski
http://www.amwaw.edu.pl/~adybkows/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

Jerzy Turynski
Guest

Wed Jan 31, 2007 6:29 am   



Adam Dybkowski <adybkows12@45wp.pl>
napisał w news:epot2n$kak$1@nemesis.news.tpi.pl...

Quote:
Legato napisał(a):

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.
[...]

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

mikroPascal : 300 bajtów

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.
[...]
Finalny kod źródłowy w C dający 28-bajtowy binarny plik wynikowy (do
linkera dorzucone opcje -nostartfiles i -nostdlib):
[...]


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 http://tinyurl.com/o6ycg ]
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? [...] >>

Quote:
--
Adam Dybkowski

JeT.

Janusz
Guest

Wed Jan 31, 2007 7:28 am   



Użytkownik "Jerzy Turynski" <jaetear@polaboax.com> napisał w wiadomości

Wielkie ciach!

Quote:
JeT.

Łał, niezły kawałek beletrystyki, tylko co to wnosi do tematu?

JJJK

Legato
Guest

Wed Jan 31, 2007 8:01 am   



Adam Dybkowski napisał(a):
Quote:
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.

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

Quote:
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.

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

Quote:
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 &=~

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


Quote:
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?)

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.

Legato
Guest

Wed Jan 31, 2007 9:22 am   



Adam Dybkowski napisał(a):

Quote:
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?)

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.

Artur M. Piwko
Guest

Wed Jan 31, 2007 12:47 pm   



In the darkest hour on Wed, 31 Jan 2007 07:28:09 +0100,
Janusz <janusz_karas@poczta.onet.pl> screamed:
Quote:
JeT.

Łał, niezły kawałek beletrystyki, tylko co to wnosi do tematu?


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

--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:237B ]
[ 11:47:28 user up 11238 days, 23:42, 1 user, load average: 0.06, 0.06, 0.06 ]

And on the seventh day, God wrote documentation (in Ark of the Covenant).

Adam Dybkowski
Guest

Wed Jan 31, 2007 6:37 pm   



Jerzy Turynski napisał(a):

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

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"].
[...]
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? [...]

Surprised 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.

--
Adam Dybkowski
http://www.amwaw.edu.pl/~adybkows/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

elektroda NewsGroups Forum Index - Elektronika Polska - Jak zredukować rozmiar kodu w C na AVR w porównaniu do mikroPascal?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map