Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: bootloader в WinAVR
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
MaxiMuz
Простая программка:
Код
************************************************
ПРИМЕР МИГАНИЯ СВЕТОДИОДАМИ
************************************************
#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 ?
зачем он тут нужен ?
Как исключить его из кода ?
_Артём_
Цитата
Оставшийся код как я понимаю bootloader ?
зачем он тут нужен ?


Неправильно понимаете: Bootloader в AVR - область во flash. содержащая программу самопрограммирования (обновления версии прошивки)
ataradov
Оставшийся код - это то, что позволяет неинициализированным глобальным переменным иметь 0 знаение, как и положено по стандарту Си.
MaxiMuz
Цитата(Taradov Alexander @ Jun 25 2011, 21:19) *
Оставшийся код - это то, что позволяет неинициализированным глобальным переменным иметь 0 знаение, как и положено по стандарту Си.

я подозревал это sm.gif ну а как это выключить ?
zltigo
QUOTE (MaxiMuz @ Jun 25 2011, 22:38) *
я подозревал это sm.gif ну а как это выключить ?

Это можно, только ответьте сначала на два вопроса:
1) Вы находясь в здравом уме собираетесь работать с неициализированными переменными с произвольным значением?
2) Если нет, то не стоит-ли Вам подумать, что инициализация их по одной займет больше кода, нежели оптом?

P.S.
На форуме есть раздел для начинающих. И не стоит по каждому чиху создавать новую тему, тем более не подобающих разделах.
MaxiMuz
Цитата(zltigo @ Jun 25 2011, 23:49) *
P.S.
На форуме есть раздел для начинающих. И не стоит по каждому чиху создавать новую тему, тем более не подобающих разделах.

Чем же этот раздел не подобает ? Других я не нашел
А на вопрос вы не ответили !
ataradov
QUOTE (MaxiMuz @ Jun 26 2011, 10:48) *
А на вопрос вы не ответили !

С помощью линерного скрипта можно выкинуть все что угодно, читайте документацию на ld и правьте стандартный скрипт.

PS: Только помните, что весь остальной код компилятор будет делать рассчитывая на то, что этот код присутствует, удачи в поимке странных и трудноуловимых багов.
zltigo
QUOTE (MaxiMuz @ Jun 26 2011, 08:48) *
Других я не нашел

Не верю, просто обычная привычка гадить, где попало sad.gif, не читать ни документации на компилятор, ни пользоваться знаниями накопленными на форуме.
QUOTE
А на вопрос вы не ответили !

Моим условием ответа на вопрос был для начала ответ на два моих вопроса - тоже типа "не нашли" sad.gif.
XVR
То, что вы видели называется Statrup. Он написан на ассемблере и присутствует в виде сорца в библиотеке (crt0.s или что то похожее). Его можно заменить из скрипта линкера.
Пишите свой и подменяйте sm.gif
MaxiMuz
Цитата(zltigo @ Jun 25 2011, 23:49) *
Это можно, только ответьте сначала на два вопроса:
1) Вы находясь в здравом уме собираетесь работать с неициализированными переменными с произвольным значением?
2) Если нет, то не стоит-ли Вам подумать, что инициализация их по одной займет больше кода, нежели оптом?

Непонимаю смысл инициализации все области памяти , если я с ней не работаю
Палыч
Цитата(MaxiMuz @ Jun 27 2011, 19:59) *
Непонимаю смысл инициализации все области памяти , если я с ней не работаю
В Вашем случае (примере) никакой инициализации и не производится: фактически производится проверка, что инициализация не нужна (точнее, что инициализировать нужно 0 слов памяти). Реальные программы, обычно, гораздо сложнее Вашего примера, и, обычно, без инициализации некоторых областей памяти не обойтись. Если что-то в стандартном startup'е Вас не устраивает, то можно его поправить...
MaxiMuz
Цитата(Палыч @ Jun 27 2011, 19:40) *
... Если что-то в стандартном startup'е Вас не устраивает, то можно его поправить...

можно - это хорошо ! каким образом ?
jorikdima
Цитата(MaxiMuz @ Jun 28 2011, 11:17) *
можно - это хорошо ! каким образом ?

У вас контроллер имеет 128 байт памяти? Или ради принципа?
MaxiMuz
Цитата(jorikdima @ Jun 28 2011, 13:30) *
У вас контроллер имеет 128 байт памяти? Или ради принципа?

К примеру взять ATtiny2313 контроллер имеет 2кБ памяти программ , а фактически 1кБ слов (команд). И часто случается что каждый байт на счету. Поэтому 128 байт - тоже обьем, и принцып тут ни причем
alexeyv
Цитата
Поэтому 128 байт - тоже обьем, и принцып тут ни причем


Тогда надо учится писать на AVR-ассемблере, или брать контроллер подходящий по объему флеша к реализуемой задаче
Сергей Борщ
QUOTE (MaxiMuz @ Jun 29 2011, 09:56) *
И часто случается что каждый байт на счету. Поэтому 128 байт - тоже обьем, и принцып тут ни причем
У вас такое бывало? Вероятнее всего - нет. Ибо ужать 2К программу на 128 байт обычно не составляет труда. Дальнейшая дискуссия неинтересна - вы спорите о вкусе устриц с теми, кто их ел.
MaxiMuz
Цитата(Сергей Борщ @ Jun 30 2011, 08:50) *
У вас такое бывало? Вероятнее всего - нет. Ибо ужать 2К программу на 128 байт обычно не составляет труда. Дальнейшая дискуссия неинтересна - вы спорите о вкусе устриц с теми, кто их ел.

У меня в ближайшем будущем стоит задача ужать хотябы на 100Б код для АТтини2313 ... Прога писана в Ассеблере, изначально уже оптимизирована и по обьему кода и по скорости. В случае написании на Си и оптимизации по обьему (Оs), код , я думаю , тоже будет ужат нормально, а этих 128Б может как раз не хватить
defunct
Цитата
В случае написании на Си и оптимизации по обьему (О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 байт (чаще больше) аппликейшину, а там они явно нужнее.
zltigo
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 сумел понять и принять) вообще начинает не лезть в никакие ворота sad.gif. Вышесказанное, естественно, совершенно не означает того, что любой освоивший copy-paste мусора из интернету и прочитавший книгу типа Редькинской способен вообще что-то вменяемое написать на C. Тут порог вхождения в качественное программирование повыше будет.
defunct
Цитата(zltigo @ Jul 5 2011, 12:03) *
Для получения такого "результата" нужно писать даже не левой ногой, а протезом левой ноги и после многократной лоботомии. На прикладных программах в десятки килобайт, ситуация с ASM становится еще печальнее, если программа создается за конечное время.

Достаточно одного неаккуратного оператора "*", "/" чтобы занять 2KB в 8-ми битнике.
Речь не о прикладных программах. Bootloader имеет самое постоянное и самое длительное время жизни. Требует высокой скорости работы, компактности и функционала.

То что там состряпает winavr и есть код писанный протезом левой ноги.

Цитата
Совершенно достаточный размер для более,чем многофункционального загрузчика.

При условии что есть возможность поместить тот же функционал в 1KB, тратить 2KB неразумно.

Цитата
Все, что больше 1K редко способно выдержать конкуренцию с C.

загрузчик по TFTP через ethernet на asm укладывается в 2KB секцию.
zltigo
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 компиляторы были совершенно сырыми sad.gif. Эта фигня, как ни странно, живет и немного сопровождается по сей день. Не переписана на C по двум причинам - там все-таки набежало более 120K кода, что по любому немалая работа, и в общем-то это уже лет 10 минимум развивать бессмысленно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.