Сергей Борщ 119 18 февраля, 2010 Опубликовано 18 февраля, 2010 · Жалоба Переобъявил, секция попала сразу за таблицей векторов."Ну тогда не знаю :laughing: " Как в скрипте линкера без --section-start настраивать я не умею.Идете в WinAVR/avr/lib/ldscripts, берете там скрипт для своего семейства, копируете в проект, правите, добавляете к ключам линкера LDFLAGS += -Wl,-T,<имя скрипта> и получаете полный контроль над адресным пространством. Вот пример для загрузчика m88 (регион и секция serial_no):/* ATmega88 bootloader linker script */ OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr") OUTPUT_ARCH(avr:4) MEMORY { application (rx) : ORIGIN = 0, LENGTH = 7K bootloader (rx) : ORIGIN = 7K, LENGTH = 1K - 4 serial_no (rx) : ORIGIN = 8K-4, LENGTH = 4 ram (rw!x) : ORIGIN = 0x800100, LENGTH = 1K eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 512 } SECTIONS { /* Internal text space or external memory. */ .app : { __app_start = . ; /* reserve space */ . = 7K; __app_end = . ; } > application __app_len = . - __app_start; .text : { KEEP(*(.vectors)) /* For data that needs to reside in the lower 64k of progmem. */ *(.progmem.gcc*) *(.progmem*) . = ALIGN(2); __trampolines_start = . ; /* The jump trampolines for the 16-bit limited relocs will reside here. */ *(.trampolines) *(.trampolines*) __trampolines_end = . ; /* For future tablejump instruction arrays for 3 byte pc devices. We don't relax jump/call instructions within these sections. */ *(.jumptables) *(.jumptables*) /* For code that needs to reside in the lower 128k progmem. */ *(.lowtext) *(.lowtext*) __ctors_start = . ; KEEP(SORT(*)(.ctors)) __ctors_end = . ; __dtors_start = . ; KEEP(SORT(*)(.dtors)) __dtors_end = . ; /* From this point on, we don't bother about wether the insns are below or above the 16 bits boundary. */ KEEP (*(.init0)) /* Start here after reset. */ KEEP (*(.init1)) KEEP (*(.init2)) /* Clear __zero_reg__, set up stack pointer. */ KEEP (*(.init3)) KEEP (*(.init4)) /* Initialize data and BSS. */ KEEP (*(.init5)) KEEP (*(.init6)) /* C++ constructors. */ KEEP (*(.init7)) KEEP (*(.init8)) KEEP (*(.init9)) /* Call main(). */ *(.text) . = ALIGN(2); *(.text.*) . = ALIGN(2); KEEP (*(.fini9)) /* _exit() starts here. */ KEEP (*(.fini8)) KEEP (*(.fini7)) KEEP (*(.fini6)) /* C++ destructors. */ KEEP (*(.fini5)) KEEP (*(.fini4)) KEEP (*(.fini3)) KEEP (*(.fini2)) KEEP (*(.fini1)) KEEP (*(.fini0)) /* Infinite loop after program termination. */ _etext = . ; } > bootloader .data : { PROVIDE (__data_start = .) ; *(.gnu.linkonce.d*) *(.rodata) *(.rodata*) *(.data) *(.data*) . = ALIGN(2); _edata = . ; PROVIDE (__data_end = .) ; } > ram AT > bootloader .bss : { PROVIDE (__bss_start = .) ; *(.bss) *(.bss*) *(COMMON) PROVIDE (__bss_end = .) ; } > ram __data_load_start = LOADADDR(.data); __data_load_end = __data_load_start + SIZEOF(.data); .serial_no : { KEEP(*(.serial_no)) } > serial_no /* Global data not cleared after reset. */ .noinit : { PROVIDE (__noinit_start = .) ; *(.noinit*) PROVIDE (__noinit_end = .) ; _end = . ; PROVIDE (__heap_start = .) ; } > ram .eeprom : { *(.eeprom*) __eeprom_end = . ; } > eeprom /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } } И еще - мне показалось удобнее хранить не константу серийного номера, а функцию, возвращающую серийный номер. А уже в код самой функции на этапе программирования подставлять коды LDI с серийным номером (avreal умеет). Это позволяет разместить такой серийник в защищенном от чтения по LPM загрузчике и тратить на чтение один ( R )CALL вместо сохранения Z, его загрузки, LPM, восстановления Z: __attribute__((section(".serial_no"), noinline)) uint8_t serial_no() { return 0; } 177 .section .serial_no,"ax",@progbits 178 .global serial_no 180 serial_no: 181 .LFB15: 182 .LSM26: 183 /* prologue: function */ 184 /* frame size = 0 */ 185 .LSM27: 186 0000 80E0 ldi r24,lo8(0) 187 /* epilogue start */ 188 0002 0895 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 19 февраля, 2010 Опубликовано 19 февраля, 2010 · Жалоба Забавный прикол: uint16_t x; .... if ((x&1)==0) {...} // случай 1 if (!(x&1)) {...} // случай 2 Получаем листинг: // случай 1: 1fd3c: 20 fd sbrc r18, 0 1fd3e: 03 c0 rjmp .+6 ; 0x1fd46 <main+0x4e4> // случай 2 1fd40: c9 01 movw r24, r18 1fd42: 81 70 andi r24, 0x01; 1 1fd44: 90 70 andi r25, 0x00; 0 1fd46: 89 2b or r24, r25 1fd48: 19 f4 brne .+6 ; 0x1fd50 <main+0x4ee> Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 20 февраля, 2010 Опубликовано 20 февраля, 2010 · Жалоба Мне не удалось полeчить такую бяку. Код странноватый (оптимизатор явно перемудрил) но корректный. Так. Вернувшись к вопросу, вынужден признать, что воссоздать ошибку снова мне не удалось. Это означает, что я поспешил с выводами. Приношу свои искренние извинения. Теперь осталось найти истинную причину, почему для получения рабочей программы требовалось volatile... :07: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 16 марта, 2010 Опубликовано 16 марта, 2010 · Жалоба Вот пример для загрузчика m88 Кстати - столкнулся с проблемой написания загрузчика на мегу48. Условия уродливые - надо расшаривать протокол связи. В связи с этим разбил программу на две части : vectors fixed_boot progmem init0 итд итп В секцию fixed_boot помещаю весь протокол, контр.сумму и стартап. После этого остутствует необходимость в таблице системных вызовов, обращаться в мини-биосу можно обычными вызовами функций, т.к. эта часть намертво пришпилена после таблицы векторов Кто что думает о таком варианте? UPD: makefile был с ошибкой. Исправлено Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 16 марта, 2010 Опубликовано 16 марта, 2010 · Жалоба т.к. эта часть намертво пришпилена после таблицы векторовДо первой найденой ошибки или добавления еще одной функции в протокол. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 17 марта, 2010 Опубликовано 17 марта, 2010 · Жалоба До первой найденой ошибки или добавления еще одной функции в протокол. Обойти можно - в #ifdef-ах исходника предусмотреть часть, которая просто копирует страницы флеша из одного места в другое, обновляя только биос. А прямее путь кто-нить знает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 20 марта, 2010 Опубликовано 20 марта, 2010 · Жалоба Еще прикол. Кто нибудь знает, как избавиться от неправильного назначения регистровых пар? ... Компилер немедленно взялся за ум и функция изрядно похудела, т.к. пошли в ход инструкции LDD/STD :cranky: Неужели эту фигню никогда не причешут? А у KGP как с этим дела? (Нету времени попробовать...) Тоже так и не попробовал, но наткнулся недавно на avrfreaks на линк сюда https://www.mikrocontroller.net/topic/65923#530326 Костыль, конечно, но на всякий случай запасся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба а я вот не увидел в этой версии компилятора опции -relax... или я куда-то не туда смотрю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба или я куда-то не туда смотрю?Это опция линкера. LDFLAGS += -Wl,-relax Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба во блин... странно... вчера вроде не получалось обнаружить эффект, а сегодня получилось... извините за беспокойство - я прошляпил... P.S. что это опция линкера - я и был в курсе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tklim 0 19 августа, 2010 Опубликовано 19 августа, 2010 · Жалоба Возможно уже такой вопрос был, сходу не нашел. WINAVR 20100110: 000006a0 <.do_clear_bss_start>: 6a0: a2 3f cpi r26, 0xF2; 242 6a2: b1 07 cpc r27, r17 6a4: e1 f7 brne .-8 ; 0x69e <.do_clear_bss_loop> 6a6: 0e 94 b3 03 call 0x766; 0x766 <main> 6aa: 0c 94 0c 3d jmp 0x7a18; 0x7a18 <_exit> Ну и собственно: int main (void) { 766: 2f 92 push r2 768: 3f 92 push r3 76a: 4f 92 push r4 76c: 5f 92 push r5 76e: 6f 92 push r6 770: 7f 92 push r7 772: 8f 92 push r8 774: 9f 92 push r9 776: af 92 push r10 778: bf 92 push r11 77a: cf 92 push r12 77c: df 92 push r13 77e: ef 92 push r14 780: ff 92 push r15 782: 0f 93 push r16 784: 1f 93 push r17 786: cf 93 push r28 788: df 93 push r29 Зачем call main и зачем так загаживать стек ? В старых версиях, если не ошибаюсь, был rjmp main. Каким образом можно это победить ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NullPointer 0 19 августа, 2010 Опубликовано 19 августа, 2010 · Жалоба Каким образом можно это победить ?Использовать атрибуты OS_main, OS_task? http://electronix.ru/forum/index.php?s=&am...st&p=441344 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tklim 0 19 августа, 2010 Опубликовано 19 августа, 2010 · Жалоба Использовать атрибуты OS_main, OS_task? http://electronix.ru/forum/index.php?s=&am...st&p=441344 Спасибо, помогло. OS_main убирает ненужные заталкивания в стек, но call main все равно остается ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 20 августа, 2010 Опубликовано 20 августа, 2010 · Жалоба call main все равно остается ) Это уже из области стартапа. Поменяйте в стартапе rcall на rjmp Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 8 февраля, 2011 Опубликовано 8 февраля, 2011 · Жалоба Кто-нибудь может объяснить феномен. -Os #include <avr/io.h> int main(void); volatile uint32_t interf; int main(void) { while(PINB & 4) { uint32_t data=0; for(uint8_t msk=0;msk < 24; msk++) { PORTB |= 0x80; if(PINB & 0x40) data |= 1; data <<= 1; PORTB &= 0x7F; } interf = data; } return 0; } Листинг правильный - его не привожу, т.к. все тривиально Дальше, если это сделать в таком виде #include <avr/io.h> int main(void); volatile uint32_t interf; int main(void) { while(PINB & 4) { uint32_t data; for(uint8_t msk=0,data=0;msk < 24; msk++) { PORTB |= 0x80; if(PINB & 0x40) data |= 1; data <<= 1; PORTB &= 0x7F; } interf = data; } return 0; } Листинг - конец света. Выкинул, родимый, все на корню. int main(void) { 44: 0f c0 rjmp .+30 ; 0x64 <main+0x20> while(PINB & 4) 46: 80 e0 ldi r24, 0x00 ; 0 { uint32_t data; for(uint8_t msk=0,data=0;msk < 24; msk++) { PORTB |= 0x80; 48: c7 9a sbi 0x18, 7 ; 24 if(PINB & 0x40) data |= 1; 4a: 96 b3 in r25, 0x16 ; 22 data <<= 1; PORTB &= 0x7F; 4c: c7 98 cbi 0x18, 7 ; 24 int main(void) { while(PINB & 4) { uint32_t data; for(uint8_t msk=0,data=0;msk < 24; msk++) 4e: 8f 5f subi r24, 0xFF ; 255 50: 88 31 cpi r24, 0x18 ; 24 52: d1 f7 brne .-12 ; 0x48 <main+0x4> PORTB |= 0x80; if(PINB & 0x40) data |= 1; data <<= 1; PORTB &= 0x7F; } interf = data; 54: 10 92 60 00 sts 0x0060, r1 58: 10 92 61 00 sts 0x0061, r1 5c: 10 92 62 00 sts 0x0062, r1 60: 10 92 63 00 sts 0x0063, r1 #include <avr/io.h> int main(void); volatile uint32_t interf; int main(void) { while(PINB & 4) 64: b2 99 sbic 0x16, 2 ; 22 66: ef cf rjmp .-34 ; 0x46 <main+0x2> PORTB &= 0x7F; } interf = data; } return 0; } 68: 80 e0 ldi r24, 0x00 ; 0 6a: 90 e0 ldi r25, 0x00 ; 0 6c: 08 95 ret Что же такого крамольного в for(uint8_t msk=0,data=0;msk < 24; msk++) ? :cranky: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться