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

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> 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
_Pasha
сообщение Feb 21 2011, 11:32
Сообщение #2


;
******

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



Может быть, может быть...
Код выложите-то?
Go to the top of the page
 
+Quote Post
dimka76
сообщение Feb 21 2011, 11:44
Сообщение #3


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Для корректного сравнения компиляторов не надо пользоваться библиотечными функциями, а у вас есть printf и из-за него сравнение будет не корректным, т.к. будет зависить от степени корявости этих библиотек, а не от особенности компилятора.


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 21 2011, 11:44
Сообщение #4


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



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

За AVR не скажу, но в MSPGCC получал при оптимизации -Os разницу примерно 16к->19к, 25к->29к ну или около этого, в пользу IAR.
Специально ничего не оптимизировал, поскольку потолок флеша 60к пока достаточно высоко...


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 21 2011, 11:46
Сообщение #5


Знающий
****

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



Цитата(_Pasha @ Feb 21 2011, 16:32) *
Может быть, может быть...
Код выложите-то?

Да, конечно и с удовольсивием!
Если я приаттачу к своим постам заархивированные (.tar.bz2) файлы -- это нормально будет? Вендузятники смогут разарзивировать?


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


Местный
***

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



IAR и GCC оба хорошие компиляторы, у каждого свои сильные и слабые стороны. ИМХО примерно так:
Сильные стороны IAR:
- устранение общих подвыражений;
- тщательная заточка под целевую архитектуру:
- - оптимальное использование режимов адресации,
- - максимально полное использование набора комманд процессора.

Сильные стороны GCC (по сравнению с IAR):
- продуманное встраивание функций;
- оптимизация циклов;
- оптимизация обращений к памяти;
- часто обходится меньшим числом регистров.

Вобщем, по-разноу, для одного исходника IAR генерирует более компактный код, для другого GCC.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 21 2011, 12:02
Сообщение #7


Знающий
****

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



Исходники проектов выложил. Движок форума файлы .tar.bz2 не принял. Пришлось zip-овать.

Цитата(dimka76 @ Feb 21 2011, 16:44) *
Для корректного сравнения компиляторов не надо пользоваться библиотечными функциями, а у вас есть printf и из-за него сравнение будет не корректным, т.к. будет зависить от степени корявости этих библиотек, а не от особенности компилятора.

Ночью уж попробовал. Для простоты, не взирая на то, что проект станет нерабочим, закомментировал все printf-ы (они только в файле app.c ). Объем кода уменьшился, но колоссальная разница осталась. sad.gif Понятно, что printf() много съедает, и дешевле обойтись itoa() и строковыми функциями.

Цитата(neiver)
Вобщем, по-разноу, для одного исходника IAR генерирует более компактный код, для другого GCC.

Да-да, я вот и хочу установить хоть какую-нибудь документально подтвержденную зависимость. А то одни разговоры и слухи.

Версии компиляторов:
[console]
alex@zhevak:~$ avr-gcc --version
avr-gcc (GCC) 4.3.5
[/console]

IAR v.5.11B


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


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(zhevak @ Feb 21 2011, 14:46) *
Вендузятники смогут разарзивировать?

Смогут, 7zip в помощь!


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 21 2011, 12:56
Сообщение #9


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

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



Глянул Ваш Makefile - там можно сказать для хорошей оптимизации по объёму сделано далеко не всё.
Сейчас нет времени, но вечерком может попробую ваши исходники сбилдить по моим рецептам:-)
О результатах отпишусь.


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


Знающий
****

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



В проекте имеется файл hal.c (абстрагирование от аппаратного уровня), в котором определены функции обработчики двух прерываний -- от таймера и от UART-а.

CODE
// Прерываение случается каждую миллисекунду
ISR (USART_RXC_vect)
{
uint8_t data;
uint8_t status;

status = UCSRA;
data = UDR;
if ((status & (_BV(FE) | _BV(DOR) | _BV(PE))) == 0) // (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
{
// Байт принят без апаратных ошибок
_pack = data;
postmessage((msg_t) MSG_PACK); // Тоби пакет!
}
else
postmessage((msg_t) MSG_BADPACK); // Пакет принят с ошибкой
}


// Прерываение случается каждые 10 миллисекунд
ISR (TIMER2_COMP_vect)
{
static uint8_t _timer_200ms;
static uint8_t _key_prevstate;

uint8_t key_currstate;

// Таймер 200 мс
if (++_timer_200ms >= 20)
{
_timer_200ms = 0;
postmessage(MSG_TIMER200MS);
}

// Отработка таймеров
if (_timer_buzzer != 0)
if (--_timer_buzzer == 0)
BUZZER_OFF;

if (_timer_led0 != 0)
if (--_timer_led0 == 0)
LED0_OFF;

if (_timer_led1 != 0)
if (--_timer_led1 == 0)
LED1_OFF;

if (_timer_led2 != 0)
if (--_timer_led2 == 0)
LED2_OFF;

if (_timer_led3 != 0)
if (--_timer_led3 == 0)
LED3_OFF;

// проверка нажатия кнопки

if ((PINC & _BV(KEY)) == 0)
key_currstate = 1; // Кнопка нажата
else
key_currstate = 0; // Кнопка отпущена

if ((key_currstate == 1) && (_key_prevstate == 0))
postmessage(MSG_KEY);
_key_prevstate = key_currstate;
}



Вот как это сделал gcc:
CODE
00000130 <__vector_3>:
130: 1f 92 push r1
132: 0f 92 push r0
134: 0f b6 in r0, 0x3f; 63
136: 0f 92 push r0
138: 11 24 eor r1, r1
13a: 2f 93 push r18
13c: 3f 93 push r19
13e: 4f 93 push r20
140: 5f 93 push r21
142: 6f 93 push r22
144: 7f 93 push r23
146: 8f 93 push r24
148: 9f 93 push r25
14a: af 93 push r26
14c: bf 93 push r27
14e: ef 93 push r30
150: ff 93 push r31
152: 80 91 d3 00 lds r24, 0x00D3
156: 8f 5f subi r24, 0xFF; 255
158: 80 93 d3 00 sts 0x00D3, r24
15c: 84 31 cpi r24, 0x14; 20
15e: 20 f0 brcs .+8 ; 0x168 <__vector_3+0x38>
160: 10 92 d3 00 sts 0x00D3, r1
164: 84 e0 ldi r24, 0x04; 4
166: c8 df rcall .-112; 0xf8 <postmessage>
168: 80 91 e0 00 lds r24, 0x00E0
16c: 88 23 and r24, r24
16e: 51 f0 breq .+20 ; 0x184 <__vector_3+0x54>
170: 80 91 e0 00 lds r24, 0x00E0
174: 81 50 subi r24, 0x01; 1
176: 80 93 e0 00 sts 0x00E0, r24
17a: 80 91 e0 00 lds r24, 0x00E0
17e: 88 23 and r24, r24
180: 09 f4 brne .+2 ; 0x184 <__vector_3+0x54>
182: ad 98 cbi 0x15, 5; 21
184: 80 91 de 00 lds r24, 0x00DE
188: 88 23 and r24, r24
18a: 51 f0 breq .+20 ; 0x1a0 <__vector_3+0x70>
18c: 80 91 de 00 lds r24, 0x00DE
190: 81 50 subi r24, 0x01; 1
192: 80 93 de 00 sts 0x00DE, r24
196: 80 91 de 00 lds r24, 0x00DE
19a: 88 23 and r24, r24
19c: 09 f4 brne .+2 ; 0x1a0 <__vector_3+0x70>
19e: a8 98 cbi 0x15, 0; 21
1a0: 80 91 df 00 lds r24, 0x00DF
1a4: 88 23 and r24, r24
1a6: 51 f0 breq .+20 ; 0x1bc <__vector_3+0x8c>
1a8: 80 91 df 00 lds r24, 0x00DF
1ac: 81 50 subi r24, 0x01; 1
1ae: 80 93 df 00 sts 0x00DF, r24
1b2: 80 91 df 00 lds r24, 0x00DF
1b6: 88 23 and r24, r24
1b8: 09 f4 brne .+2 ; 0x1bc <__vector_3+0x8c>
1ba: a9 98 cbi 0x15, 1; 21
1bc: 80 91 e3 00 lds r24, 0x00E3
1c0: 88 23 and r24, r24
1c2: 51 f0 breq .+20 ; 0x1d8 <__vector_3+0xa8>
1c4: 80 91 e3 00 lds r24, 0x00E3
1c8: 81 50 subi r24, 0x01; 1
1ca: 80 93 e3 00 sts 0x00E3, r24
1ce: 80 91 e3 00 lds r24, 0x00E3
1d2: 88 23 and r24, r24
1d4: 09 f4 brne .+2 ; 0x1d8 <__vector_3+0xa8>
1d6: aa 98 cbi 0x15, 2; 21
1d8: 80 91 e1 00 lds r24, 0x00E1
1dc: 88 23 and r24, r24
1de: 51 f0 breq .+20 ; 0x1f4 <__vector_3+0xc4>
1e0: 80 91 e1 00 lds r24, 0x00E1
1e4: 81 50 subi r24, 0x01; 1
1e6: 80 93 e1 00 sts 0x00E1, r24
1ea: 80 91 e1 00 lds r24, 0x00E1
1ee: 88 23 and r24, r24
1f0: 09 f4 brne .+2 ; 0x1f4 <__vector_3+0xc4>
1f2: ab 98 cbi 0x15, 3; 21
1f4: 9c 9b sbis 0x13, 4; 19
1f6: 02 c0 rjmp .+4 ; 0x1fc <__vector_3+0xcc>
1f8: 80 e0 ldi r24, 0x00; 0
1fa: 07 c0 rjmp .+14 ; 0x20a <__vector_3+0xda>
1fc: 80 91 d2 00 lds r24, 0x00D2
200: 88 23 and r24, r24
202: 11 f4 brne .+4 ; 0x208 <__vector_3+0xd8>
204: 81 e0 ldi r24, 0x01; 1
206: 78 df rcall .-272; 0xf8 <postmessage>
208: 81 e0 ldi r24, 0x01; 1
20a: 80 93 d2 00 sts 0x00D2, r24
20e: ff 91 pop r31
210: ef 91 pop r30
212: bf 91 pop r27
214: af 91 pop r26
216: 9f 91 pop r25
218: 8f 91 pop r24
21a: 7f 91 pop r23
21c: 6f 91 pop r22
21e: 5f 91 pop r21
220: 4f 91 pop r20
222: 3f 91 pop r19
224: 2f 91 pop r18
226: 0f 90 pop r0
228: 0f be out 0x3f, r0; 63
22a: 0f 90 pop r0
22c: 1f 90 pop r1
22e: 18 95 reti

00000230 <__vector_11>:
230: 1f 92 push r1
232: 0f 92 push r0
234: 0f b6 in r0, 0x3f; 63
236: 0f 92 push r0
238: 11 24 eor r1, r1
23a: 2f 93 push r18
23c: 3f 93 push r19
23e: 4f 93 push r20
240: 5f 93 push r21
242: 6f 93 push r22
244: 7f 93 push r23
246: 8f 93 push r24
248: 9f 93 push r25
24a: af 93 push r26
24c: bf 93 push r27
24e: ef 93 push r30
250: ff 93 push r31
252: 8b b1 in r24, 0x0b; 11
254: 9c b1 in r25, 0x0c; 12
256: 8c 71 andi r24, 0x1C; 28
258: 21 f4 brne .+8 ; 0x262 <__vector_11+0x32>
25a: 90 93 e2 00 sts 0x00E2, r25
25e: 82 e0 ldi r24, 0x02; 2
260: 01 c0 rjmp .+2 ; 0x264 <__vector_11+0x34>
262: 83 e0 ldi r24, 0x03; 3
264: 49 df rcall .-366; 0xf8 <postmessage>
266: ff 91 pop r31
268: ef 91 pop r30
26a: bf 91 pop r27
26c: af 91 pop r26
26e: 9f 91 pop r25
270: 8f 91 pop r24
272: 7f 91 pop r23
274: 6f 91 pop r22
276: 5f 91 pop r21
278: 4f 91 pop r20
27a: 3f 91 pop r19
27c: 2f 91 pop r18
27e: 0f 90 pop r0
280: 0f be out 0x3f, r0; 63
282: 0f 90 pop r0
284: 1f 90 pop r1
286: 18 95 reti



А вот так отработал IAR:
CODE
26 __interrupt void _usart_rxc_isr(void)

\ _usart_rxc_isr:

27 {

\ 00000000 .... RCALL ?Subroutine0

\ ??CrossCallReturnLabel_0:

\ 00000002 B78F IN R24, 0x3F

28 uint8_t data;

29 uint8_t status;

30

31 status = UCSRA;

\ 00000004 B10B IN R16, 0x0B

32 data = UDR;

\ 00000006 B11C IN R17, 0x0C

33 if ((status & (_BV(FE) | _BV(DOR) | _BV(PE))) == 0) // (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)

\ 00000008 710C ANDI R16, 0x1C

\ 0000000A F421 BRNE ??_usart_rxc_isr_0

34 {

35 // Байт принят без апаратных ошибок

36 _pack = data;

\ 0000000C 9310.... STS _pack, R17

37 postmessage((msg_t) MSG_PACK); // Тоби пакет!

\ 00000010 E002 LDI R16, 2

\ 00000012 C001 RJMP ??_usart_rxc_isr_1

38 }

39 else

40 postmessage((msg_t) MSG_BADPACK); // Пакет принят с ошибкой

\ ??_usart_rxc_isr_0:

\ 00000014 E003 LDI R16, 3

\ ??_usart_rxc_isr_1:

\ 00000016 .... RCALL postmessage

41 }

\ 00000018 BF8F OUT 0x3F, R24

\ 0000001A .... RCALL ?Subroutine1

\ ??CrossCallReturnLabel_2:

\ 0000001C 9518 RETI

\ 0000001E REQUIRE _A_UCSRA

\ 0000001E REQUIRE _A_UDR



\ In segment CODE, align 2, keep-with-next

\ ?Subroutine1:

\ 00000000 9109 LD R16, Y+

\ 00000002 9119 LD R17, Y+

\ 00000004 9129 LD R18, Y+

\ 00000006 9139 LD R19, Y+

\ 00000008 9149 LD R20, Y+

\ 0000000A 9159 LD R21, Y+

\ 0000000C 9169 LD R22, Y+

\ 0000000E 9179 LD R23, Y+

\ 00000010 9009 LD R0, Y+

\ 00000012 9019 LD R1, Y+

\ 00000014 9029 LD R2, Y+

\ 00000016 9039 LD R3, Y+

\ 00000018 91E9 LD R30, Y+

\ 0000001A 91F9 LD R31, Y+

\ 0000001C 9189 LD R24, Y+

\ 0000001E 9508 RET



\ In segment CODE, align 2, keep-with-next

\ ?Subroutine0:

\ 00000000 938A ST -Y, R24

\ 00000002 93FA ST -Y, R31

\ 00000004 93EA ST -Y, R30

\ 00000006 923A ST -Y, R3

\ 00000008 922A ST -Y, R2

\ 0000000A 921A ST -Y, R1

\ 0000000C 920A ST -Y, R0

\ 0000000E 937A ST -Y, R23

\ 00000010 936A ST -Y, R22

\ 00000012 935A ST -Y, R21

\ 00000014 934A ST -Y, R20

\ 00000016 933A ST -Y, R19

\ 00000018 932A ST -Y, R18

\ 0000001A 931A ST -Y, R17

\ 0000001C 930A ST -Y, R16

\ 0000001E 9508 RET

42

43

44 // Прерываение случается каждые 10 миллисекунд

45 // ISR (TIMER2_COMP_vect)

46 #pragma vector = TIMER2_COMP_vect



\ In segment CODE, align 2, keep-with-next

47 __interrupt void _timer2_comp_isr(void)

\ _timer2_comp_isr:

48 {

\ 00000000 939A ST -Y, R25

\ 00000002 .... RCALL ?Subroutine0

\ ??CrossCallReturnLabel_1:

\ 00000004 B79F IN R25, 0x3F

49 static uint8_t _timer_200ms;

50 static uint8_t _key_prevstate;

51

52 uint8_t key_currstate;

53

54 // Таймер 200 мс

55 if (++_timer_200ms >= 20)

\ 00000006 .... LDI R30, LOW(_timer_led0)

\ 00000008 .... LDI R31, (_timer_led0) >> 8

\ 0000000A 8105 LDD R16, Z+5

\ 0000000C 9503 INC R16

\ 0000000E 8305 STD Z+5, R16

\ 00000010 3104 CPI R16, 20

\ 00000012 F020 BRCS ??_timer2_comp_isr_0

56 {

57 _timer_200ms = 0;

\ 00000014 E000 LDI R16, 0

\ 00000016 8305 STD Z+5, R16

58 postmessage(MSG_TIMER200MS);

\ 00000018 E004 LDI R16, 4

\ 0000001A .... RCALL postmessage

59 }

60

61 // Отработка таймеров

62 if (_timer_buzzer != 0)

\ ??_timer2_comp_isr_0:

\ 0000001C 9100.... LDS R16, (_timer_led0 + 4)

\ 00000020 2300 TST R16

\ 00000022 F039 BREQ ??_timer2_comp_isr_1

63 if (--_timer_buzzer == 0)

\ 00000024 9100.... LDS R16, (_timer_led0 + 4)

\ 00000028 950A DEC R16

\ 0000002A 9300.... STS (_timer_led0 + 4), R16

\ 0000002E F409 BRNE ??_timer2_comp_isr_1

64 BUZZER_OFF;

\ 00000030 98AD CBI 0x15, 0x05

65

66 if (_timer_led0 != 0)

\ ??_timer2_comp_isr_1:

\ 00000032 9100.... LDS R16, _timer_led0

\ 00000036 2300 TST R16

\ 00000038 F039 BREQ ??_timer2_comp_isr_2

67 if (--_timer_led0 == 0)

\ 0000003A 9100.... LDS R16, _timer_led0

\ 0000003E 950A DEC R16

\ 00000040 9300.... STS _timer_led0, R16

\ 00000044 F409 BRNE ??_timer2_comp_isr_2

68 LED0_OFF;

\ 00000046 98A8 CBI 0x15, 0x00

69

70 if (_timer_led1 != 0)

\ ??_timer2_comp_isr_2:

\ 00000048 9100.... LDS R16, (_timer_led0 + 1)

\ 0000004C 2300 TST R16

\ 0000004E F039 BREQ ??_timer2_comp_isr_3

71 if (--_timer_led1 == 0)

\ 00000050 9100.... LDS R16, (_timer_led0 + 1)

\ 00000054 950A DEC R16

\ 00000056 9300.... STS (_timer_led0 + 1), R16

\ 0000005A F409 BRNE ??_timer2_comp_isr_3

72 LED1_OFF;

\ 0000005C 98A9 CBI 0x15, 0x01

73

74 if (_timer_led2 != 0)

\ ??_timer2_comp_isr_3:

\ 0000005E 9100.... LDS R16, (_timer_led0 + 2)

\ 00000062 2300 TST R16

\ 00000064 F039 BREQ ??_timer2_comp_isr_4

75 if (--_timer_led2 == 0)

\ 00000066 9100.... LDS R16, (_timer_led0 + 2)

\ 0000006A 950A DEC R16

\ 0000006C 9300.... STS (_timer_led0 + 2), R16

\ 00000070 F409 BRNE ??_timer2_comp_isr_4

76 LED2_OFF;

\ 00000072 98AA CBI 0x15, 0x02

77

78 if (_timer_led3 != 0)

\ ??_timer2_comp_isr_4:

\ 00000074 9100.... LDS R16, (_timer_led0 + 3)

\ 00000078 2300 TST R16

\ 0000007A F039 BREQ ??_timer2_comp_isr_5

79 if (--_timer_led3 == 0)

\ 0000007C 9100.... LDS R16, (_timer_led0 + 3)

\ 00000080 950A DEC R16

\ 00000082 9300.... STS (_timer_led0 + 3), R16

\ 00000086 F409 BRNE ??_timer2_comp_isr_5

80 LED3_OFF;

\ 00000088 98AB CBI 0x15, 0x03

81

82 // проверка нажатия кнопки

83

84 if ((PINC & _BV(KEY)) == 0)

85 key_currstate = 1; // Кнопка нажата

\ ??_timer2_comp_isr_5:

\ 0000008A 999C SBIC 0x13, 0x04

\ 0000008C C002 RJMP ??_timer2_comp_isr_6

\ 0000008E E001 LDI R16, 1

\ 00000090 C001 RJMP ??_timer2_comp_isr_7

\ ??_timer2_comp_isr_6:

\ 00000092 E000 LDI R16, 0

\ ??_timer2_comp_isr_7:

\ 00000094 2F80 MOV R24, R16

86 else

87 key_currstate = 0; // Кнопка отпущена

88

89 if ((key_currstate == 1) && (_key_prevstate == 0))

\ 00000096 3001 CPI R16, 1

\ 00000098 F431 BRNE ??_timer2_comp_isr_8

\ 0000009A 9100.... LDS R16, (_timer_led0 + 6)

\ 0000009E 2300 TST R16

\ 000000A0 F411 BRNE ??_timer2_comp_isr_8

90 postmessage(MSG_KEY);

\ 000000A2 E001 LDI R16, 1

\ 000000A4 .... RCALL postmessage

91 _key_prevstate = key_currstate;

\ ??_timer2_comp_isr_8:

\ 000000A6 9380.... STS (_timer_led0 + 6), R24

92 }

\ 000000AA BF9F OUT 0x3F, R25

\ 000000AC .... RCALL ?Subroutine1

\ ??CrossCallReturnLabel_3:

\ 000000AE 9199 LD R25, Y+

\ 000000B0 9518 RETI

\ 000000B2 REQUIRE _A_PINC

\ 000000B2 REQUIRE _A_PORTC

93



Фейерическое растранжиривание памяти компилятором gcc видите?
Что-нибудь можно предпринять на уровне компилятора или для gcc это фатально?


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


Местный
***

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



Да, да. Это феерическое растранжирование памяти в обработчиках прерываний является следствием того, что в этих обработчиках вызываются функции из другой единици трансляции. Компилятор не знает какие регистры использует вызываемая функция и сохраняет в стеке все call-saved регистры на всякий случай. А у IAR это как раз сильная сторона - устранение общих подвыражений. Он выносит эти сохранения/восстановления регистров в отдельные функции. Решение для avr-gcc - не вызывать из обработчиков прерываний функции из других единиц трансляции(для IAR, кстати тоже полезно будет) или использовать inline функции.


Второй пожиратель ресурсов это как уже все догадались функция sprintf. В IAR проекте у вас используется минимальная урезанная версия, в gcc - полная с поддержкой float и чтения параметров из памяти программ.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 21 2011, 13:33
Сообщение #12


Знающий
****

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



Цитата(demiurg_spb @ Feb 21 2011, 17:56) *
Глянул Ваш Makefile - там можно сказать для хорошей оптимизации по объёму сделано далеко не всё.
Сейчас нет времени, но вечерком может попробую ваши исходники сбилдить по моим рецептам:-)
О результатах отпишусь.

Я не помню в каком состоянии оставил Makefile. Я уже отчаялся, добиться от gcc чего-либо значимого, и тупо, просто тупо, как китаес, перебирал варианты. Потом плюнул на все и пошел спать. А сегодня решил обратиться к помощи зала sm.gif Да, и это... Makefile это рабочая лошадка, т.е. он постоянно у меня в движении находится. Ну, т.е. это не готовый к употреблению файл. Исходнные тексты я более-иене причесал, а Makefile -- as is.

И тем не менее, спасибо за коллаборацию! Жду результатов.

Плюс-минус 10-20 байтов особой погоды не делают. Мне хотелось бы скинуть хотя бы 500 байт. Я уж не говорю о килобайте! Но обязательно, я еще раз подчеркиваю, -- сохранить этот быдлокод с его библиотечными вызовами монструозных функций типа printf. Мне хотелось бы в результате нашего совместного поиска выработать какие-то предложения (или правила), как надо и как не надо кодить в gcc. Что допустимо, а что не допустимо в нем по сравнению с IAR.


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


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата
20e: ff 91 pop r31
210: ef 91 pop r30
212: bf 91 pop r27
214: af 91 pop r26
216: 9f 91 pop r25
218: 8f 91 pop r24
21a: 7f 91 pop r23
21c: 6f 91 pop r22
21e: 5f 91 pop r21
220: 4f 91 pop r20
222: 3f 91 pop r19
224: 2f 91 pop r18
226: 0f 90 pop r0
228: 0f be out 0x3f, r0; 63
22a: 0f 90 pop r0
22c: 1f 90 pop r1
22e: 18 95 reti

Эта жесть!
Копайте в сторону инлайнов

Все ваши hal-функции должны быть static inline
(извините, ваши исходники не смотрел, меня за свои скоро расстреляют)

/Блин, а я-то 4-кратный push/pop в прерываниях считал диким оверхедом/

Цитата(zhevak @ Feb 21 2011, 16:13) *
Извините, не знаю как подвернуть эти листинги-простыни. Наверняка же можно как-то cut-нуть. Подскажите, плиз!

тег CODEBOX.
Поправьте вручную или слева вверху есть пулл-даун "Спец.элементы"


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
neiver
сообщение Feb 21 2011, 13:57
Сообщение #14


Местный
***

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



Параметры линкера:
-Wl,-u,vfprintf -lprintf_min
для avr-gcc сразу дают минус 372 байта.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 21 2011, 14:01
Сообщение #15


;
******

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



По приведенным фрагментам.
push/pop ld/st - что в лоб, что по лбу. А вот при сравнении модификации таймеров - гцц использует интенсивно LDS/STS а IAR чаще LDD/STD или LD/ST. Имхо, секрет фокуса как раз в том, что размер инструкции LDS/STS 2 слова и разница в размере от этого. Можно проверить - сравнив кол-во LDS/STS в листинге. Зуб даю, у иара их меньше в разы.
По поводу стиля исходников ничего не скажу, но понял одно - у меня давно нет проблем впихнуть невпихуемое и тянуться к иару из-за того, что многие подобные таймерам вопросы решаются совсем по-другому.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 17:45
Рейтинг@Mail.ru


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