|
bootloader в WinAVR, к вопросу оптимизации |
|
|
|
Jun 25 2011, 16:58
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Простая программка: Код ************************************************ ПРИМЕР МИГАНИЯ СВЕТОДИОДАМИ ************************************************ #include <avr/io.h>
int main(void) { PORTB |=_BV(PB2) | _BV(PB0); DDRB |= _BV(PB0); while (1) { if (bit_is_clear(PINB,PB2)) PORTB |= _BV(PB0); else PORTB &= ~_BV(PB0); } } Использовал различные уровни оптимизации (OPT = s в данном случае) Команда: "make.exe" all выдает следующий протокол: Код Creating load file for Flash: test.hex avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature test.elf test.hex
Creating load file for EEPROM: test.eep avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 --no-change-warnings -O ihex test.elf test.eep || exit 0
Creating Extended Listing: test.lss avr-objdump -h -S -z test.elf > test.lss
Creating Symbol Table: test.sym avr-nm -n test.elf > test.sym
Size after: AVR Memory Usage ---------------- Device: attiny2313
Program: 114 bytes (5.6% Full) (.text + .data + .bootloader)
Data: 0 bytes (0.0% Full) (.data + .bss + .noinit)
-------- end --------
> Process Exit Code: 0 > Time Taken: 00:02 Получается вот такой код: Код test.elf: file format elf32-avr
Sections: Idx Name Size VMA LMA File off Algn 0 .text 00000072 00000000 00000000 00000054 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .debug_aranges 00000020 00000000 00000000 000000c6 2**0 CONTENTS, READONLY, DEBUGGING 2 .debug_pubnames 0000001b 00000000 00000000 000000e6 2**0 CONTENTS, READONLY, DEBUGGING 3 .debug_info 00000076 00000000 00000000 00000101 2**0 CONTENTS, READONLY, DEBUGGING 4 .debug_abbrev 00000041 00000000 00000000 00000177 2**0 CONTENTS, READONLY, DEBUGGING 5 .debug_line 00000073 00000000 00000000 000001b8 2**0 CONTENTS, READONLY, DEBUGGING 6 .debug_frame 00000020 00000000 00000000 0000022c 2**2 CONTENTS, READONLY, DEBUGGING 7 .debug_str 00000079 00000000 00000000 0000024c 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text:
00000000 <__vectors>: 0: 12 c0 rjmp .+36; 0x26 <__ctors_end> 2: 2a c0 rjmp .+84; 0x58 <__bad_interrupt> 4: 29 c0 rjmp .+82; 0x58 <__bad_interrupt> 6: 28 c0 rjmp .+80; 0x58 <__bad_interrupt> 8: 27 c0 rjmp .+78; 0x58 <__bad_interrupt> a: 26 c0 rjmp .+76; 0x58 <__bad_interrupt> c: 25 c0 rjmp .+74; 0x58 <__bad_interrupt> e: 24 c0 rjmp .+72; 0x58 <__bad_interrupt> 10: 23 c0 rjmp .+70; 0x58 <__bad_interrupt> 12: 22 c0 rjmp .+68; 0x58 <__bad_interrupt> 14: 21 c0 rjmp .+66; 0x58 <__bad_interrupt> 16: 20 c0 rjmp .+64; 0x58 <__bad_interrupt> 18: 1f c0 rjmp .+62; 0x58 <__bad_interrupt> 1a: 1e c0 rjmp .+60; 0x58 <__bad_interrupt> 1c: 1d c0 rjmp .+58; 0x58 <__bad_interrupt> 1e: 1c c0 rjmp .+56; 0x58 <__bad_interrupt> 20: 1b c0 rjmp .+54; 0x58 <__bad_interrupt> 22: 1a c0 rjmp .+52; 0x58 <__bad_interrupt> 24: 19 c0 rjmp .+50; 0x58 <__bad_interrupt>
00000026 <__ctors_end>: 26: 11 24 eor r1, r1 28: 1f be out 0x3f, r1; 63 2a: cf ed ldi r28, 0xDF; 223 2c: cd bf out 0x3d, r28; 61
0000002e <__do_copy_data>: 2e: 10 e0 ldi r17, 0x00; 0 30: a0 e6 ldi r26, 0x60; 96 32: b0 e0 ldi r27, 0x00; 0 34: e2 e7 ldi r30, 0x72; 114 36: f0 e0 ldi r31, 0x00; 0 38: 02 c0 rjmp .+4 ; 0x3e <.do_copy_data_start>
0000003a <.do_copy_data_loop>: 3a: 05 90 lpm r0, Z+ 3c: 0d 92 st X+, r0
0000003e <.do_copy_data_start>: 3e: a0 36 cpi r26, 0x60; 96 40: b1 07 cpc r27, r17 42: d9 f7 brne .-10; 0x3a <.do_copy_data_loop>
00000044 <__do_clear_bss>: 44: 10 e0 ldi r17, 0x00; 0 46: a0 e6 ldi r26, 0x60; 96 48: b0 e0 ldi r27, 0x00; 0 4a: 01 c0 rjmp .+2 ; 0x4e <.do_clear_bss_start>
0000004c <.do_clear_bss_loop>: 4c: 1d 92 st X+, r1
0000004e <.do_clear_bss_start>: 4e: a0 36 cpi r26, 0x60; 96 50: b1 07 cpc r27, r17 52: e1 f7 brne .-8 ; 0x4c <.do_clear_bss_loop> 54: 02 d0 rcall .+4 ; 0x5a <main> 56: 0b c0 rjmp .+22; 0x6e <_exit>
00000058 <__bad_interrupt>: 58: d3 cf rjmp .-90; 0x0 <__vectors>
0000005a <main>: 5a: 88 b3 in r24, 0x18; 24 5c: 85 60 ori r24, 0x05; 5 5e: 88 bb out 0x18, r24; 24 60: b8 9a sbi 0x17, 0; 23 62: b2 99 sbic 0x16, 2; 22 64: 02 c0 rjmp .+4 ; 0x6a <main+0x10> 66: c0 9a sbi 0x18, 0; 24 68: fc cf rjmp .-8 ; 0x62 <main+0x8> 6a: c0 98 cbi 0x18, 0; 24 6c: fa cf rjmp .-12; 0x62 <main+0x8>
0000006e <_exit>: 6e: f8 94 cli
00000070 <__stop_program>: 70: ff cf rjmp .-2 ; 0x70 <__stop_program> Собственно полезный код занимает десяток байт , таблица векторов прерваний - это понятно, далее секция <__ctors_end>: первые две команды - обнуление SREG ! Для каких это целей ? Оставшийся код как я понимаю bootloader ? зачем он тут нужен ? Как исключить его из кода ?
Сообщение отредактировал MaxiMuz - Jun 25 2011, 17:02
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 20)
|
Jun 25 2011, 20:49
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (MaxiMuz @ Jun 25 2011, 22:38)  я подозревал это  ну а как это выключить ? Это можно, только ответьте сначала на два вопроса: 1) Вы находясь в здравом уме собираетесь работать с неициализированными переменными с произвольным значением? 2) Если нет, то не стоит-ли Вам подумать, что инициализация их по одной займет больше кода, нежели оптом? P.S. На форуме есть раздел для начинающих. И не стоит по каждому чиху создавать новую тему, тем более не подобающих разделах.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 26 2011, 06:48
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(zltigo @ Jun 25 2011, 23:49)  P.S. На форуме есть раздел для начинающих. И не стоит по каждому чиху создавать новую тему, тем более не подобающих разделах. Чем же этот раздел не подобает ? Других я не нашел А на вопрос вы не ответили !
|
|
|
|
|
Jun 26 2011, 08:38
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (MaxiMuz @ Jun 26 2011, 08:48)  Других я не нашел Не верю, просто обычная привычка гадить, где попало  , не читать ни документации на компилятор, ни пользоваться знаниями накопленными на форуме. QUOTE А на вопрос вы не ответили ! Моим условием ответа на вопрос был для начала ответ на два моих вопроса - тоже типа "не нашли"  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 27 2011, 16:40
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(MaxiMuz @ Jun 27 2011, 19:59)  Непонимаю смысл инициализации все области памяти , если я с ней не работаю В Вашем случае (примере) никакой инициализации и не производится: фактически производится проверка, что инициализация не нужна (точнее, что инициализировать нужно 0 слов памяти). Реальные программы, обычно, гораздо сложнее Вашего примера, и, обычно, без инициализации некоторых областей памяти не обойтись. Если что-то в стандартном startup'е Вас не устраивает, то можно его поправить...
|
|
|
|
|
Jun 30 2011, 05:45
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата Поэтому 128 байт - тоже обьем, и принцып тут ни причем Тогда надо учится писать на AVR-ассемблере, или брать контроллер подходящий по объему флеша к реализуемой задаче
|
|
|
|
|
Jul 5 2011, 00:22
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата В случае написании на Си и оптимизации по обьему (Оs), код , я думаю , тоже будет ужат нормально, а этих 128Б может как раз не хватить не понимаю я bootloader'ы в WinAVR, CV, ICC или еще какой-то байде, для бутсекций в 2kb. Если старая программа написана на asm'е да еще и соптимизирована, то на Си вы просто ни при каких обстоятельствах не сможете добиться такого функционала в том же объеме, не говоря уже о расширении оного. Функционал который со скрипом влезет в самую большую бут секцию (2kb) с макс оптимизацией на WinAVR, - на асм поместится в самую маленькую бутсекцию из 256 байт. Достигается это за счет оптимальных прологов/эпилогов функций и исключительно регистровых переменных. Реализция бутлоадера на Сях оправдана разве только "тайм ту маркетом" либо большим объемом флеш целевого МК. На С vs ASM, вы всегда потеряете или функциональность, или объем, или скорость, или всё сразу, какой бы ключик оптимизации не ставили. Цитата(Сергей Борщ @ Jun 30 2011, 08:50)  У вас такое бывало? Ибо ужать 2К программу на 128 байт обычно не составляет труда. Дальнейшая дискуссия неинтересна - вы спорите о вкусе устриц с теми, кто их ел. У меня вот что есть сказать, - бутсекция 1кб - поддержка: modbus по 485-му, загрузка с внешней eeprom'ки, CRC апп секции, шифрование в обе стороны... Портирование между МК байты приходится искать вставляя код в неиспользуемые ячейки таблицы векторов, проект собирается ровно в 1024байт ни одной свободной ячейки флеш (портировать с m8 напр на m16 - занятие не особо веселое, и найти там не то что 128, 8 байт без урезания функционала - большая проблема). Зато освобождается целый 1кб под апликейшин, для 8/16кб флешевых чипов - очень актуально. Бутлоадер - это такой тип программы, где простота найти 128 байт - означает недодать эти 128 байт (чаще больше) аппликейшину, а там они явно нужнее.
|
|
|
|
|
Jul 5 2011, 09:03
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (defunct @ Jul 5 2011, 03:22)  Функционал который со скрипом влезет в самую большую бут секцию (2kb) с макс оптимизацией на WinAVR, - на асм поместится в самую маленькую бутсекцию из 256 байт. Достигается это за счет оптимальных прологов/эпилогов функций и исключительно регистровых переменных. Как человек неоднократно писавший загрузчики размером от 128байт до 16килобайт, как на ASM, так и на С для самых разных контроллеров, не могу не сказать, что соотношение 256 и 2048 есть абсолютный бред. Для получения такого "результата" нужно писать даже не левой ногой, а протезом левой ноги и после многократной лоботомии. На прикладных программах в десятки килобайт, ситуация с ASM становится еще печальнее, если программа создается за конечное время. QUOTE какой бы ключик оптимизации не ставили. Голову на плечах иметь надо, а продуманные ключики оптимизации это дело абсолютно обязательное, но не они задают уровень качества полученного продукта. QUOTE (defunct @ Jul 5 2011, 03:22)  не понимаю я bootloader'ы в WinAVR, CV, ICC или еще какой-то байде, для бутсекций в 2kb. Совершенно достаточный размер для более,чем многофункционального загрузчика. Все, что больше 1K редко способно выдержать конкуренцию с C. Ниша ASM загрузчиков заканчивается на уровне 128...256, максимум 512 байт. Дальше в 99% совершенно бессмысленно, даже при наличии хорошего опыта и больших шишек в ASM-описании. Результат-же большинства писателей на ASM (читай тех, кто только уровень ASM сумел понять и принять) вообще начинает не лезть в никакие ворота  . Вышесказанное, естественно, совершенно не означает того, что любой освоивший copy-paste мусора из интернету и прочитавший книгу типа Редькинской способен вообще что-то вменяемое написать на C. Тут порог вхождения в качественное программирование повыше будет.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 5 2011, 12:59
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zltigo @ Jul 5 2011, 12:03)  Для получения такого "результата" нужно писать даже не левой ногой, а протезом левой ноги и после многократной лоботомии. На прикладных программах в десятки килобайт, ситуация с ASM становится еще печальнее, если программа создается за конечное время. Достаточно одного неаккуратного оператора "*", "/" чтобы занять 2KB в 8-ми битнике. Речь не о прикладных программах. Bootloader имеет самое постоянное и самое длительное время жизни. Требует высокой скорости работы, компактности и функционала. То что там состряпает winavr и есть код писанный протезом левой ноги. Цитата Совершенно достаточный размер для более,чем многофункционального загрузчика. При условии что есть возможность поместить тот же функционал в 1KB, тратить 2KB неразумно. Цитата Все, что больше 1K редко способно выдержать конкуренцию с C. загрузчик по TFTP через ethernet на asm укладывается в 2KB секцию.
|
|
|
|
|
Jul 5 2011, 13:22
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (defunct @ Jul 5 2011, 15:59)  Bootloader имеет самое постоянное и самое длительное время жизни. Требует высокой скорости работы, Скорость работы ему требуется в последнюю очередь, ибо работает он редко, в идеале никогда. QUOTE компактности и функционала. Компактность и функционал должны быть достаточными, а не самоцелью. QUOTE То что там состряпает winavr и есть код писанный протезом левой ноги. То, что Вы назвали winavr, есть GCC. Не самый плохой компилятор. Делает то, что ему прикажут. Для AVR, правда, есть и получше. QUOTE При условии что есть возможность поместить тот же функционал в 1KB, тратить 2KB неразумно. Повторяю, cегодня, а не в середине 80x, на уровне программ размером 1-2K выигрыша в два раза между ASM и профессионально написанным C не бывает. Двухкратным превосходством можете изредка себя тешить на кусочках программ с единицы-десятки байт. QUOTE загрузчик по TFTP через ethernet на asm укладывается в 2KB секцию. TFTP/UDP/IP как раз тот случай когда смысл использования ASM равен ровно нулю. Проверено неоднократно. Та-же поддержка сети в на рубеже 80/90х писалась для своей операционки на 286 на ASM. На ASM тогда писалось все по причине того, что 12MHz 286 был отнюдь не гигант производительности и экономился каждый такт в системе жесткого реального времени с эмулятором виртуальной машины. Всякие фокусы, типа модифицируемого на лету кода тоже приходилось использовать. Доступные тогда C компиляторы были совершенно сырыми  . Эта фигня, как ни странно, живет и немного сопровождается по сей день. Не переписана на C по двум причинам - там все-таки набежало более 120K кода, что по любому немалая работа, и в общем-то это уже лет 10 минимум развивать бессмысленно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|