_Pasha 0 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба убраны debug symbols из всех *.a; По этому поводу E.W. на avrfreaks писал типа "а что мешает самостоятельно их пострипать?" :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 21 января, 2010 Опубликовано 21 января, 2010 · Жалоба Размеры проектов - 1836->1854 (загрузчик) и 6042->5816 (приложение, мега8, С++, виртуальные функции). Работоспособность не проверял.Проверил. Код работает. Сравнил листинги (правда для другого проекта). Основное отличие - обращение к eeprom. В 20090313 процедура чтения|записи блока принимала в качестве параметра указатель на функцию чтения|записи байта и косвенно вызывала эту функцию. Теперь функция чтения/записи байта встроена в чтение/запись блока, благодаря чему экономится место как на загрузке указателя так и на перетасовке регистров при косвенном вызове. В 20100110 вся процедура чтения/записи блока (со встроенным обращением) меньше, чем обертка вызова функции чтения/записи байта в 20090313. Кроме этого в 20090313 независимо от -msave-prologue запись/чтение блока вызывала процедуры сохранения/восстановления регистров, которые в 20100110 не понадобились. Результат - уменьшение кода на 148 байт. В остальном код на этом конкретном проекте идентичный до байта. Вывод - теперь можно смело использовать eeprom_read_block(). В 20090313 эффективнее получалось вручную читать побайтно в цикле. Остался недостаток оптимизации при работе с байтовыми аргументами функций: При вызове функции, объявленной с аргументом типа "байт" в регистры заносится 2 байта (старший = 0), внутри функции копия аргумента тоже хранится как двухбайтовая переменная, хотя используется только младший байт: void hd44780::write_data(uint8_t byte) 162: ff 92 push r15 164: 0f 93 push r16 166: 1f 93 push r17 <----------------------------------- 168: 8c 01 movw r16, r24 <----------------------------------- 16a: f6 2e mov r15, r22 { write_tetrade(byte & 0xF0); 16c: 60 7f andi r22, 0xF0; 240 16e: ec df rcall .-40 ; 0x148 <_ZN7hd4478013write_tetradeEh> write_tetrade(byte << 4); 170: f2 94 swap r15 172: 80 ef ldi r24, 0xF0; 240 174: f8 22 and r15, r24 176: c8 01 movw r24, r16 <----------------------------------- 178: 6f 2d mov r22, r15 17a: e6 df rcall .-52 ; 0x148 <_ZN7hd4478013write_tetradeEh> 17c: 8d e3 ldi r24, 0x3D; 61 17e: 8a 95 dec r24 180: f1 f7 brne .-4 ; 0x17e <_ZN7hd4478010write_dataEh+0x1c> _delay_us(50); ON(LCD_RS); 182: c1 9a sbi 0x18, 1; 24 } 184: 1f 91 pop r17 <----------------------------------- 186: 0f 91 pop r16 188: ff 90 pop r15 18a: 08 95 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vova75 0 27 января, 2010 Опубликовано 27 января, 2010 · Жалоба Ошибку в прологе/эпилоге при использовании ISR(xxx_vect, ISR_NOBLOCK) так и не исправили :( Проект для меги1280 на С++ в 14КБ собрался на 150 байт меньше, это хорошо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 4 февраля, 2010 Опубликовано 4 февраля, 2010 · Жалоба Однако... То-то я чуйкой какой-то ("шестое чувство в пятой точке") играюсь разными версиями, а рабочие компиляции в 20071221 делаю :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 8 февраля, 2010 Опубликовано 8 февраля, 2010 · Жалоба Code: #include <avr/io.h> volatile uint8_t v; int main(void) { while (1) { v; v; v; #if BUG uint8_t* p = (uint8_t*) &v; PORTC = *p; #endif } } avr-gcc 3.4.6 (WinAVR-20060421): Code: .text .global main .type main, @function main: ldi r28,lo8(__stack - 0) ldi r29,hi8(__stack - 0) out __SP_H__,r29 out __SP_L__,r28 lds r25,v .L2: lds r24,v lds r24,v lds r24,v out 40-0x20,r25 rjmp .L2 (yes, first lds is placed out of loop) avr-gcc 4.1.2 (WinAVR-20070525) - the same except no stack pointer initialisation avr-gcc 4.2.2 (WinAVR=20071221) - the same except no stack pointer initialisation avr-gcc 4.3.2 (WinAVR-20081205) and later - as WinAVR-20100110 А чего тут криминального? Чтений из volatile ровно столько, сколько надо. А от чтения по указателю на простой (не volatile) тип - ничего, кроме знаачения не гарантируется. А откуда оно его взяло - целиком на усмотрение оптимизатора. Вообще, всё что не volatile, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 8 февраля, 2010 Опубликовано 8 февраля, 2010 · Жалоба А чего тут криминального? Тут всё нормально. Вы посмотрите что из этого делают версии WinAVR-2008, 2009 и та 2010, которая в теме и обсуждается. Там из v при -DBUG=1 делется одно чтение. Вот это "as WinAVR-20100110" .global main .type main, @function main: .L2: lds r24,v out 53-32,r24 rjmp .L2 У Klen-сборок 4.4.0 и 4.5.0 и у WinAVR по 20071221 включительно (т.е. по 4.2.x включительно) всё нормально. Т.е. - похоже, что ошибка в 4.3.x Вообще, всё что не volatile, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо.И, если не зависит друг от друга, то переставлено местами (в том числе и с обращениями к volatile), и вообще выброшено. А то я этого не знаю :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 8 февраля, 2010 Опубликовано 8 февраля, 2010 · Жалоба Однако... Однако, дубль два. Имеем: double res; //.............. return (int16_t) (lround(res) - 273); Скомпилировано с опцией -mint8 Получаем: +000007BC: 01C8 MOVW R24,R16 +000007BD: 01B7 MOVW R22,R14 +000007BE: D12D RCALL PC+0x012E // lround(res) R23:R22:r25:r24 = 0x01870000 +000007BF: 019C MOVW R18,R24 // осторожно, грабли! +000007C0: 5121 SUBI R18,0x11 // - 273 +000007C1: 4031 SBCI R19,0x01 +000007C2: 01C9 MOVW R24,R18 Вместо того чтобы правильный результат в старшей половине, отдает ноль. Без опции -mint8 - все нормально. Просьба советы никогда не применять указанную опцию не давать! :) А вначале был оч.рад, когда используя stdint.h получал утоптанные выражения целого типа. Недолго музыка играла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 12 февраля, 2010 Опубликовано 12 февраля, 2010 · Жалоба Однако, дубль два. :( Боян оказываеццо, с 2004 года так и не удосужились подрихтовать. Еще прикол. Кто нибудь знает, как избавиться от неправильного назначения регистровых пар? Например, имеем указатель на структуру, и поля в ней интенсивно используются. Сабж так любит регистры XH:XL, что поручает именно Х эту непосильную работу. В итоге, послав все к чертям, я прибил эти регистры register volatile uint8_t xL asm("r26"); register volatile uint8_t xH asm("r27"); Компилер немедленно взялся за ум и функция изрядно похудела, т.к. пошли в ход инструкции LDD/STD :cranky: Неужели эту фигню никогда не причешут? А у KGP как с этим дела? (Нету времени попробовать...) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 17 февраля, 2010 Опубликовано 17 февраля, 2010 · Жалоба :1111493779: Ау, я что, в палате №6? Не спим! Нашел серьезную багу. Предположим, имеется глобальная переменная или extern uint8_t period; Попытка сделать задаром арифметическую операцию по модулю 100, например так period += 33; if(period > 100) period -= 100; Приводит к созданию неожиданного кода, наподобие lds r24,period subi r24,0xdf // period += 33 cpi r24,0x64 brlo label subi r24,0x43 // !!! а должно быть 0x64 label: Оптимизация -Os Это катастрофа. У оптимизатора появилась ложная зависимость, и он посчитал что надо вычесть не 100, а 100-33 = 67 Сколько таких случаев надо отсматривать в листинге - ХЗ :smile3046: Мне повезло, что вносилась доработка в уже готовое софто. Проблема имеет workaround, як кажуть кляті англійці Для того, чтобы код выполнялся правильно, надо period объявить volatile Такие дела. Видимо, придется возвращаться в WinAVR-20071221 :cranky: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
misyachniy 0 17 февраля, 2010 Опубликовано 17 февраля, 2010 · Жалоба Друг спросил как разместить данные во флеш поопределенному адресу. Сделал как по ссылке. http://8515.avrfreaks.net/index.php?name=P...ic&p=589365 WinAVR-20100110. Судя по листингу программа обращается к данным как задано const uint8_t part_number __attribute__ ((section (".part_number")))='A'; i = pgm_read_byte(&part_number); 2ee: e0 ef ldi r30, 0xF0; 240 2f0: ff e3 ldi r31, 0x3F; 63 2f2: e4 91 lpm r30, Z+ Но ни в HEX ни в bin файле нету данных. Обычное объявление переменных в памяти программ работает. Совместить два аттрибута у меня не получилось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 17 февраля, 2010 Опубликовано 17 февраля, 2010 · Жалоба Но ни в HEX ни в bin файле нету данных.попробйте обозвать секцию .text.partnumber или .progmem.partnumber Я указываю секцию в скрипте линкера, --section-start не пользовался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NullPointer 0 17 февраля, 2010 Опубликовано 17 февраля, 2010 · Жалоба Нашел серьезную багу.Воссоздать не получается. Используется два регистра, оттуда и такой подход с константами: lds r25,period mov r24,r25 subi r24,lo8(-(33)) sts period,r24 cpi r24,lo8(101) brlo .L3 subi r25,lo8(-(-67)) sts period,r25 .L3 Дайте проект, в котором у вас такая ошибка возникает, ибо пока не понятно (доприбивались вы регистры, хехе :laughing:). -- Сделал как по ссылке.Тоже сделал. Данные все на месте. Разница в оптимизации? Показывайте Makefile. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 17 февраля, 2010 Опубликовано 17 февраля, 2010 · Жалоба Попытка сделать задаром арифметическую операцию по модулю 100, например так ... Оптимизация -Os Это катастрофа. У оптимизатора появилась ложная зависимость, и он посчитал что надо вычесть не 100, а 100-33 = 67 Мне не удалось полeчить такую бяку. Код странноватый (оптимизатор явно перемудрил) но корректный. Более того - он не отличается от кода 20071221 #include <avr/io.h> extern uint8_t period; void foo() { period += 33; if(period > 100) period -= 100; } uint8_t moo(uint8_t i) { i += 33; if(i > 100) i -= 100; return i; } -Os .text .global foo .type foo, @function foo: lds r25,period mov r24,r25 subi r24,lo8(-(33)) sts period,r24 cpi r24,lo8(101) brlo .L3 subi r25,lo8(-(-67)) ; 67 вычитается из _исходного_ значения (+33-100) <=> (-67) sts period,r25 .L3: ret .global moo .type moo, @function moo: subi r24,lo8(-(33)) cpi r24,lo8(101) brlo .L5 subi r24,lo8(-(-100)) .L5: ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZiB 0 18 февраля, 2010 Опубликовано 18 февраля, 2010 · Жалоба аналогично, не удалось воссоздать ошибку. проверил на готовом проекте код уменьшился, сравнил - лучше оптимизация в условиях. правда у меня во всех проектах оптимизция равна 2. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
misyachniy 0 18 февраля, 2010 Опубликовано 18 февраля, 2010 · Жалоба попробйте обозвать секцию .text.partnumber или .progmem.partnumber Я указываю секцию в скрипте линкера, --section-start не пользовался. Переобъявил, секция попала сразу за таблицей векторов. Как в скрипте линкера без --section-start настраивать я не умею. код const uint8_t part_number __attribute__ ((section (".progmem.part_number")))='A'; const unsigned long serial_number __attribute__ ((section (".progmem.serial_number"))) = 0x12345678; маке LDFLAGS += -Wl,--section-start=.progmem.part_number=$(PART_NUMBER_ADDRESS) LDFLAGS += -Wl,--section-start=.progmem.serial_number=$(SERIAL_NUMBER_ADDRESS) HEX :100050000C9458 0041 78563412 456E7465722063D2 LST 00000054 <part_number>: 54: 41 A i = pgm_read_byte(&part_number); 2f4: e4 e5 ldi r30, 0x54; 84 2f6: f0 e0 ldi r31, 0x00; 0 2f8: e4 91 lpm r30, Z+ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться