реклама на сайте
подробности

 
 
> avr-gcc и IAR, сравнение, но не холивар
zhevak
сообщение Feb 21 2011, 11:11
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



(Предыстория. Можно пропустить.)
Я чуть боле двух лет как перебрался на Линукс. Оставил в покое Венду и Вендовые компиляторы. Все хорошо, полет более чем нормальный. Не сочтите за рекламу! Сижу в Ubuntu (и Debian). Просто после Венды мне показалось, что Ubuntu легче освоить, чем другие Линуксы типа Gentoo и Slackware. Тем более столько народа в ней сидит. И тем более, что средства для разработки программ для AVR уже лежат готовые в репозиториях. В общем, живу и в ус не дую.

Но меня давно подмывало произвести ревизию бинарного кода, который компилится avr-gcc, и сравнить его с IAR-овским кодом. Но все как-то не получалось сделать. То проект был не большой (типа "хелловорлд" в исполнении светодиодов), и поэтому полноценного сравнения не могло получиться. То проект наоборот был большой, и не хватало времени на его портацию в другую среду. А то проект коммерческий -- типа нельзя публиковать. В общем, все как-то не стыковалось с моими чаяниями.

И вот, внезапно выпало счастье заняться небольшим "не засекреченным" проектом. Я его начинал создавать на Mega48. Но в какой-то момент, по мере его роста не хватило флеши, пришлось перебираться на Mega8. Бывает. Не проблема! Переписал. Все легко поднялось и заработало. И на второе счастье у меня оказались свободными выходные (уже прошедшие). Чем я и воспользовался.

Откопал старый винт с установленной Вендой и IAR-ом, подцепил к компу.. и на до же! Оказывается я все еще помню, как в Венде тыкать мышкой! Короче, перенес проект под IAR, скомпилировал и поразился.


(А вот теперь по делу.)
Понятно, что поскольку компиляторы разные, они и должны создавать разный по объему код. Если размер кода (бинарник) чуть-чуть превышает 4КБ, то, как вы думаете, какая разница будет в объеме сгенерированных компиляторами кодов?

Я ожидал получить разницу в размере кода ну 100, ну 200 байт. А получил аж 1200 байт. Солидный кусок! Так сильно gcc меня еще не опускал. Обидно, да-а?

Конечно, на мое впечатление еще оказал воздействие тот факт, что если бы я изначально писал под IAR-ом, то мне бы не пришлось по ходу менять проц. Но ведь сам выбрал Линух и gcc!

Но это все эмоции. Мне же интересно было разобраться с состоянием дел вообще. Сначала я засел за оптимизацию. Начал перебирать различные комбинации ключей в надежде как можно более сильно сократить код и под gcc, и под IAR-ом. Да. Мне это удалось сделать. Код немного ужался и там, и там, но все равно разница в килобайт с хвостиком сохранилась: один компайлер генерит код размером в 2596 байт, другой -- 3772 байта. Я оцениваю размер кода по hex-файлу, который непосредственно заливается во флешь. Т.е. здесь вообще без дураков, которых можно обмануть не посчитав, допустим, размер таблицы векторов. Или опустив размер вспомогательных (ну или как их правильно-то назвать?) функций, который компилятор сам может создавать, увидев повторяющиеся участки кода.


(Вопрос.)
Коллеги, не впадая в безумие священных войн, вы можете помочь установить истину в работе компиляторов -- почему они дают такой существенно разный результат? Возможно что-то я не правильно делаю. (А это обязательно так!) Но мне, да и многим из вас, хотелось бы знать -- в каком отношении по объему друг к другу эти компиляторы "готовят" код.

Полный код проекта я могу предоставить. Единственная просьба -- по возможно соблюдать одинаковость исходных кодов в обоих версиях (для gcc и для IAR).

Ну, например, в gcc я есть команда для запрета прерываний cli(), и в IAR-е она тоже есть -- __disable_inerrupt(). Это все легко соблюсти. Сложнее соблюсти, допустим, программные задержки. В библиотеке gcc есть функции _delay_us() и _delay_ms(), а в IAR-е таковых нет. Но по жизни очень часто бывает так, что эти в программе без задержек никак. Поэтому я допускаю, что в исходниках для IAR-а, будут использованы приемы типа
Код
#define FCLK (11059200)
#define delay_ms(n)  __delay_cycles((FCLK / 1000) * (n));
#define delay_us(n)  __delay_cycles((FCLK / 1000000) * (n));


Есть еще одно замечание. Исходный текст написан не очень правильно с точки зрения профи. Пока его улучшать не надо! Я поясню. Дело в том, что этот проект не коммерческий, и этот девайс не предполагается кому-то продавать. Кроме того, передо мной стаояла задача: достаточно тупо слепить устройство и установить его в работу, не доводя его до витринного блеска. Поэтому, например, вместо того, чтобы работать с функциями строк из флеша (avr/pgmspace.h), я их тупо прописываю в printf() и не парюсь, что при этом в Оперативе создается их копия. Просто пока не до этого!

В общем, давайте _пока_ не будем трогать исходники. Ибо я хочу посмотреть на возможности компиляторов для среднестатистического быдлокодера, который пишет проги вот на таком вот уровне. А когда мы совместными усилиями получим какие-то цифры, для сравнения компиляторов, вот тогда уже можно будет отрываться и пытаться уникальными для конкретного компилятора приемами уменьшить объем кода.

Не думайте, что я пытаюсь вашими руками написать свой проект! Проект уже работает и приносит определенную пользу. Дальнейшее улучшение проекта пойдет не по направлению уменьшения кода или вылизыванию в нем ошибок, а по направлению увеличения функциональности (насыщенности). Но даже и это пока не нужно. У меня другая задача -- разобраться с компиляторами.


Надеюсь, вы понимаете меня, и топик не съедет в бессмысленный срач.

Пожалуйста, задавайте ваши вопросы.
Прикрепленные файлы
Прикрепленный файл  monitor_iar.zip ( 19 килобайт ) Кол-во скачиваний: 31
Прикрепленный файл  monitor_gcc.zip ( 9.96 килобайт ) Кол-во скачиваний: 48
 


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
4 страниц V  < 1 2 3 4 >  
Start new topic
Ответов (15 - 29)
zhevak
сообщение Feb 21 2011, 14:05
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(neiver @ Feb 21 2011, 18:27) *
Решение для avr-gcc - не вызывать из обработчиков прерываний функции из других единиц трансляции или использовать inline функции.

да. Хороша мысль. Но не сейчас, а для второй фазы, когда нужно будет оптимизировать код и писать рекомендации для пользователей gcc.

Цитата
Второй пожиратель ресурсов это как уже все догадались функция sprintf. В IAR проекте у вас используется минимальная урезанная версия, в gcc - полная с поддержкой float и чтения параметров из памяти программ.

Точно! И об этом я тоже как-то не додумался, не дошел! В IAR-е тип функций printf (и scanf) задается в Опциях проекта (General Options / Library Options) из выпадающих списков, а вот в опций для gnu-линковщика я не удосужился поискать. Былпа такая светлая мысль, поискать, но утонула среди других вопросов.
(В IAR-e у меня стоял Printf Formatter = Small)

Сейчас попробую нащупать подобную опцию в avr-ld...
Отбой! Пока я писал этот пост, уже опередили http://electronix.ru/forum/index.php?showt...st&p=888593

Откомпилировал с
Да, действительно скидывает 372 байта. Объем кода по avr-size -- 3400 байт (text), в бинарнике под заливку во флешь 0x0DBA байт (= 3514).
У IAR-а бинарник под заливку -- 0x0A32 байт (= 2610)

Все еще много лишних байт (почти 900) надо чем-то объяснять blink.gif


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 21 2011, 14:14
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



При использовании близких по функциональности версий стандартной библиотеки "normal DLIB" в IAR и -lprintf_min в avr-gcc (обе без поддержки float и еще какой-то фигни) размер кода почти сравнялся: IAR - 3614, avr-gcc - 3708 байт. Изначально в проекте IAR-а использовалясь жутко урезанная "CLIB" версия рантайма. В avr-gcc настолько порезанной несоответствующей стандартам, но тем не менее компактной библиотеки нет.
Так вот. А если функции вызываемые из прерываний сделать встраиваемыми, то будет, видимо, паритет.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 21 2011, 14:40
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



в ответ на http://electronix.ru/forum/index.php?showt...st&p=888594
Ну вот, посчитал количество команд (считал через $ grep -iw sts *.lst | wc -l и ее модификации для других мнемоник)

Код
command   gcc   IAR
-------   ---   ----
LDS       87    23
STS       86    25
LD        16    24
ST        26    33

05.gif и?


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 21 2011, 14:45
Сообщение #19


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zhevak @ Feb 21 2011, 17:40) *
05.gif и?

На 250 байт разницу объяснили. wacko.gif Блин, я ожидал поболее.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 21 2011, 15:18
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Как Вы считали? У меня другие цифры.

(87 + 86) * 4 + (16 + 26) * 2 = 776 байт
(23 + 25) * 4 + (24 + 33) * 2 = 306 байт

разница 470 байт.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 21 2011, 15:30
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Думаю, что не на 250 байт, поменьше. Не всегда Lds можно выгодно заменить на Ld/Ldd - адрес-то нужно предварительно загрузить в регистры.
Для 4-х и 2-х байтовых переменных и для структур выгоднее (только по размеру кода, но не по скорости) Ld/Ldd/St/Std использовать. Для однобайтовых - Lds/Sts.
А вообще, IAR более оптимально использует косвенную адресацию со смещением. AVR-GCC приходится явно намекать какую адресацию использовать, например работая с переменной через указатель.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 22 2011, 05:35
Сообщение #22


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zhevak @ Feb 21 2011, 18:18) *
Как Вы считали?

(87-23)+(86-25)=125 слов, имея ввиду только разницу между нормальными командами и этой, придурошной sm.gif

Цитата(neiver @ Feb 21 2011, 18:30) *
Думаю, что не на 250 байт, поменьше.
А вообще, IAR более оптимально использует косвенную адресацию со смещением. AVR-GCC приходится явно намекать какую адресацию использовать, например работая с переменной через указатель.

Ну, поменьше, это ж на глазок было. Гцц как ни намекай, он иногда в такую бяку сваливается sad.gif, жаждешь от него этих "со смещением", а их все нету. Это РТЛ деревья, видать, по мозгам сильно проехались. Не умеет он по-настоящему юзать три указателя. Еще Гцц не любит действия со старшим битом. Еще... да нафиг! Зато "на переднем крае" всегда.
Go to the top of the page
 
+Quote Post
klen
сообщение Feb 22 2011, 09:08
Сообщение #23


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



после танцев с бубном получил следующие размеры

''чистая культура" без использования библиотечных аля printf
text data bss dec hex filename
2714 30 43 2787 ae3 monitor-gcc.elf

максимум что я выжал не выкидывая авторские вызовый sprintf
text data bss dec hex filename
3240 114 43 3397 d45 monitor-gcc.elf

gcc версия 4.6.0 20110127 (experimental) (Klen's GCC package (KGP) for AVR/elf platform)
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 22 2011, 11:57
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Ну вроде как стало соизмеримо (если не сказать сравнялось в ноль!):
gcc: 2787(text) + 30(data) = 2817 байт флеши.
IAR: 2596(text) + 221(data) = 2817 байт флеши

Но что значит "без использования"?
Цитата(klen @ Feb 22 2011, 14:08) *
''чистая культура" без использования библиотечных аля printf


Вы вызовы просто закомментировали или сохранили функциональность, заменив их на strcpy() и itoa()?
В исходниках для IAR-а вызовы printf() не удалены и не заменены. Т.е. как бы условия состязания нарушены.

Вчера ночью попробовал postmessage(), которую вызывают оба прерывания, сделать inline -- ни какой реакции sad.gif, как было, так и осталось.

А пока резюме такое (извините, оно получилось несколько персонифицированным конкретно ко мне)
1. Функции printf и их модификации в тулчейне для avr имеют большие размеры, чем в IAR. Поэтому, если стоит вопрос компактности кода, их использования следует избегать.
2. Не забывать, что функции printf имеют несколько реализаций, выбор которых через ключи линковщика -Wl, -u, ...


Ну что, если других предложений нет, тогда переходим к фазе оптимизации два -- оптимизация кода.
Тут я вижу сразу две точки приложения:
1. Заменить вызовы printf() на strcpy(), strcat() и itoa()
2. Сделать по уму, заменить функции работы с оперативой на функции работы с констатами во флеш, т.е. вместо strcat() использовать strcat_P() и т.д.

Ну вот пожалуй это все, что я вижу, что можно сделать, чтобы легко выдавить из gcc. Давить наверняка можно еще, но это уже будет сродни национальным танцам народов севера с использованием ударных музыкальных инструментов.

По крайней мере для себя я понял, почему в первом приближении на gcc не достигается компактность кода присущая IAR, и что следует делать, что бы хоть как-то уменьшить размер кода.


ГОСПОДА, СПАСИБО ЗА КОЛЛАБОРАЦИЮ!

Через какое-то время я сообщу, что у меня получилось после реализации фазы два.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
klen
сообщение Feb 22 2011, 15:27
Сообщение #25


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



точно, чистая культура это вмесо printf заглушки. я это сделал чтоб посмотреть сколько собственного кода пллучится. второй вариант без нарушения функциональности
Go to the top of the page
 
+Quote Post
vitmeat
сообщение Feb 22 2011, 23:46
Сообщение #26





Группа: Участник
Сообщений: 13
Регистрация: 22-01-11
Пользователь №: 62 402



Попробуйте заменить стандартный gcc'ый printf на xprintf от elm-chan'a http://elm-chan.org/fsw/strf/xprintf.html
Эмм... В общем он теперь тоже сишный и большой, раньше был на асме и маленький, аж удивился rolleyes.gif . Но даже сейчас он меньше.
Заменил sprintf на xsprintf без потери функциональности

Из 4 тулчейнов: biggrin.gif

WinAVR -> ( тут еще включен -mint8 и --param inline-call-cost=0 )
Program: 3268 bytes (39.9% Full)
Data: 161 bytes (15.7% Full)

kgp_avr ->
Program: 3402 bytes (41.5% Full)
Data: 161 bytes (15.7% Full)

AVR_Toolchain -> ( тут еще включен -mint8 )
Program: 3366 bytes (41.1% Full)
Data: 161 bytes (15.7% Full)

mhvavrtools ->
Program: 3386 bytes (41.3% Full)
Data: 161 bytes (15.7% Full)

Для стандартной printf у меня получилось: biggrin.gif

WinAVR -> ( тут еще включен -mint8 и --param inline-call-cost=0 )
Program: 3514 bytes (42.9% Full)
Data: 157 bytes (15.3% Full)

kgp_avr ->
Program: 3578 bytes (43.7% Full)
Data: 157 bytes (15.3% Full)

AVR_Toolchain -> ( тут еще включен -mint8 )
Program: 3554 bytes (43.4% Full)
Data: 157 bytes (15.3% Full)

mhvavrtools ->
Program: 3566 bytes (43.5% Full)
Data: 157 bytes (15.3% Full)

WinAVR -> avr-gcc.exe (WinAVR 20100110) 4.3.3
kgp_avr -> avr-gcc.exe (Klen's GCC package (KGP) for AVR/elf platform) 4.6.0 20100725 (experimental)
AVR_Toolchain -> avr-gcc.exe (AVR_Toolchain_3.0_149) 4.4.3
mhvavrtools -> avr-gcc.exe (GCC) 4.5.1
wacko.gifcranky.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 23 2011, 11:44
Сообщение #27


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Наткнулся на интересную бяку. Для начала, убрал все "ньюансовые" флаги. Размер существенно не менялся. Компилер, тсз conventional 2010-0110 sm.gif
Придрался к стремно-длинным прологам/эпилогам в прерываниях. По опыту - это гавновопрос, сделал так (почти на автопилоте)
Код
static void postmessage_prim(msg_t msg);
void postmessage(msg_t msg)
{
postmessage_prim(msg);
}

Соответственно, в прерываниях, поменял вызовы на статик-примитив. Логика железная - статик как на ладони, шохошь то и делай.
Так он, собако, абсолютно это игнорирует и прологи те же. cranky.gif Вот жеж нанизм блин! И самое загадостное, что у мну это много раз так разруливалось. Он что, фамилию спрашиват?

UPD причину нашел, надо было указать __attribute__((pure))
С дефолтовым минимальным принтфом 3788 байт.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 26 2011, 17:02
Сообщение #28


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(_Pasha @ Feb 23 2011, 14:44) *
С дефолтовым минимальным принтфом 3788 байт.

аналогично, но у меня поменьше вышло 3424
вообще без правки исходников, лишь переписал Makefile.
CODE
avr-gcc (AVR_Toolchain_3.0_149) 4.4.3
Copyright © 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Building project: bin/monitor-gcctest/monitor-gcc.elf

avr-gcc -mmcu=atmega8 -MMD -MP -MF ./bin/monitor-gcctest/monitor-gcc.dep -gdwarf-2 -DF_CPU=4608000UL -Os -pedantic -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -fno-split-wide-types --combine -fwhole-program -ffunction-sections
-fdata-sections -Wl,--relax -ftree-loop-ivcanon -mcall-prologues -fno-tree-scev-cprop -finline-small-functions -fearly-inlining
--param inline-call-cost=2 -finline-limit=65535 -mshort-calls -fno-unit-at-a-time -Wsign-compare -Wa,-adhlns=./bin/monitor-gcctest/monitor-gcc.lst
-std=c99 -I. hal.c app.c lcd4.c main.c --output bin/monitor-gcctest/monitor-gcc.elf -Wl,-Map=./bin/monitor-gcctest/monitor-gcc.map,--cref
-Wl,--gc-section -Wl,-u,vfprintf -lprintf_min

Creating load file for Flash: bin/monitor-gcctest/monitor-gcc.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature bin/monitor-gcctest/monitor-gcc.elf bin/monitor-gcctest/monitor-gcc.hex

Creating load file for EEPROM: bin/monitor-gcctest/monitor-gcc.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex bin/monitor-gcctest/monitor-gcc.elf bin/monitor-gcctest/monitor-gcc.eep || exit 0

Creating Extended Listing: bin/monitor-gcctest/monitor-gcc.lss
avr-objdump -h -S bin/monitor-gcctest/monitor-gcc.elf > bin/monitor-gcctest/monitor-gcc.lss

Creating Symbol Table: bin/monitor-gcctest/monitor-gcc.sym
avr-nm -n bin/monitor-gcctest/monitor-gcc.elf > bin/monitor-gcctest/monitor-gcc.sym

Size after:
AVR Memory Usage
----------------
Device: atmega8

Program: 3424 bytes (41.8% Full)
(.text + .data + .bootloader)

Data: 157 bytes (15.3% Full)
(.data + .bss + .noinit)

Последний WinAVR выдал ещё на 4 байта меньше 3420.
avr-gcc (Klen's GCC package (KGP) for AVR/elf platform) 4.6.0 20100725 (experimental) выдал на 30 байт больше 3454

Сообщение отредактировал IgorKossak - Feb 27 2011, 09:45


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 26 2011, 21:14
Сообщение #29


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(demiurg_spb @ Feb 26 2011, 22:02) *
... выдал на 30 байт больше 3454

30 байт это 1%. Мне кажется это не существенно.

(что-то все еще никак не могу засесть за свою задачу и заменить printf на более "легкие" функции.)


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
zhevak
сообщение Mar 1 2011, 02:14
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Похоже что всё, приехали. Дальнейшая борьба за ужатие кода не приносит ощутимых результатов.

Я заменил вызовы sprintf() на strcpy_P(). Где -то это оказалось вообще безболезненно (изменения только в файле app.c):
Код
  case MODE_STOP:
//    strcpy(buf0, "    Spectron");
//    strcpy(buf1, " Click for start");
    strcpy_P(buf0, (PGM_P)pgm_read_word(&(str0)));
    strcpy_P(buf1, (PGM_P)pgm_read_word(&(str1)));
    break;


, а где-то сполшной туман (как потом, через полгода буду сам продираться через это код -- типа что этим кодом хотел сделать и почему нужно было так извращаться, почему нельзя было написать сразу ясно-понятно-чисто):
Код
  case MODE_0:
//    sprintf(buf0, "Channel 1:%6lu", uvchannel0);
    strcpy_P(buf0, (PGM_P)pgm_read_word(&(str4)));
    buf0[8] = '1';
    ltoa(uvchannel0, buf3, 10);
    len = strlen(buf3);
    strcpy((buf0 + (16 - len)), buf3);

    buf1[0] = 0x00;
    break;

Вот, при такой замене размер секции text даже увеличился с 3400 до 3456 байт, а размер секции data уменьшился со 114 до 86 байт.

Потом я вынес повторяющиеся участки в отдельную функцию:
Код
void preplcd(char *buf, char ach, long uv)
{
  char buf3[12];
  uint8_t len;

  strcpy_P(buf, (PGM_P)pgm_read_word(&(str4)));
  buf[8] = ach;
  ltoa(uv, buf3, 10);
  len = strlen(buf3);
  strcpy((buf + (16 - len)), buf3);
}

оставив на месте только ее вызов:
Код
//    sprintf(buf0, "Channel 1:%6lu", uvchannel0);
    preplcd(buf0, '1', uvchannel0);    

    buf1[0] = 0x00;
    break;

То размер секции text удалось еще ужать до 3420 байт.

Таким образом, размер бинарного кода для загрузки во флеш сейчас составляет 3506 байт.

Резюме всего исследования будет такое:

IAR по сравнению с gcc создает заметно более компактный код при минимальных усилиях со стороны программиста.

Увы и ах! Я так понимаю, дальнейшие изыскания не приводят к желаемому результату. К сожалению, вынужден признать, что в этот раз gcc "продул" IAR-у. Это вывод №1.

Вывод №2. Замена sprintf на серию функций не дала существенной экономии. На деле даже получился небольшой проигрыш. Но это скорее всего из-за того, что были так же взяты не чистые функции (strcpy), а функции работы с флеш-памятью (strcpy_P). Но так или иначе получается, что раз улучшения нет, то функции printf в libc не такие уж и "раздутые", как казалось ранее. Просто что-то еще улучшить в gcc или libc у их создателей уже не получается. Использовать же printf на практике вполне можно и даже нужно, ибо ясность исходного кода куда более важна, чем экономия 20 байт флеша.

Если у вас есть что добавить или опровергнуть, пожалуйста скажите, я же дальнейшие "исследования" в этом направлении прекращаю. Здесь ловить не чего.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 00:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01543 секунд с 7
ELECTRONIX ©2004-2016