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

 
 
9 страниц V  « < 2 3 4 5 6 > »   
Reply to this topicStart new topic
> WinAVR-20100110, Пишем отзывы сюда
Сергей Борщ
сообщение Feb 18 2010, 11:32
Сообщение #46


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(misyachniy @ Feb 18 2010, 11:49) *
Переобъявил, секция попала сразу за таблицей векторов.
"Ну тогда не знаю laughing.gif "
Цитата(misyachniy @ Feb 18 2010, 11:49) *
Как в скрипте линкера без --section-start настраивать я не умею.
Идете в WinAVR/avr/lib/ldscripts, берете там скрипт для своего семейства, копируете в проект, правите, добавляете к ключам линкера LDFLAGS += -Wl,-T,<имя скрипта> и получаете полный контроль над адресным пространством. Вот пример для загрузчика m88 (регион и секция serial_no):
CODE
/* 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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 19 2010, 14:25
Сообщение #47


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

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



Забавный прикол:
Код
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>


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 20 2010, 08:06
Сообщение #48


;
******

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



Цитата(ReAl @ Feb 17 2010, 22:53) *
Мне не удалось полeчить такую бяку. Код странноватый (оптимизатор явно перемудрил) но корректный.

Так. Вернувшись к вопросу, вынужден признать, что воссоздать ошибку снова мне не удалось. Это означает, что я поспешил с выводами. Приношу свои искренние извинения. Теперь осталось найти истинную причину, почему для получения рабочей программы требовалось volatile... 07.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 16 2010, 18:05
Сообщение #49


;
******

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



Цитата(Сергей Борщ @ Feb 18 2010, 15:32) *
Вот пример для загрузчика m88

Кстати - столкнулся с проблемой написания загрузчика на мегу48. Условия уродливые - надо расшаривать протокол связи. В связи с этим разбил программу на две части :
Код
vectors
fixed_boot
progmem
init0
итд итп

В секцию fixed_boot помещаю весь протокол, контр.сумму и стартап.
После этого остутствует необходимость в таблице системных вызовов, обращаться в мини-биосу можно обычными вызовами функций, т.к. эта часть намертво пришпилена после таблицы векторов[attachment=41881:qstart.zip]
Кто что думает о таком варианте?
UPD: makefile был с ошибкой. Исправлено
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 16 2010, 23:25
Сообщение #50


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_Pasha @ Mar 16 2010, 20:05) *
т.к. эта часть намертво пришпилена после таблицы векторов
До первой найденой ошибки или добавления еще одной функции в протокол.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 17 2010, 05:39
Сообщение #51


;
******

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



Цитата(Сергей Борщ @ Mar 17 2010, 03:25) *
До первой найденой ошибки или добавления еще одной функции в протокол.

Обойти можно - в #ifdef-ах исходника предусмотреть часть, которая просто копирует страницы флеша из одного места в другое, обновляя только биос.
А прямее путь кто-нить знает?
Go to the top of the page
 
+Quote Post
ReAl
сообщение Mar 20 2010, 13:24
Сообщение #52


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(_Pasha @ Feb 12 2010, 19:49) *
Еще прикол. Кто нибудь знает, как избавиться от неправильного назначения регистровых пар?
...
Компилер немедленно взялся за ум и функция изрядно похудела, т.к. пошли в ход инструкции LDD/STD
cranky.gif Неужели эту фигню никогда не причешут?
А у KGP как с этим дела? (Нету времени попробовать...)
Тоже так и не попробовал, но наткнулся недавно на avrfreaks на линк сюда
https://www.mikrocontroller.net/topic/65923#530326
Костыль, конечно, но на всякий случай запасся.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 25 2010, 08:45
Сообщение #53


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



а я вот не увидел в этой версии компилятора опции -relax... или я куда-то не туда смотрю?


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 25 2010, 08:56
Сообщение #54


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(ARV @ Mar 25 2010, 10:45) *
или я куда-то не туда смотрю?
Это опция линкера.
LDFLAGS += -Wl,-relax


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 25 2010, 09:17
Сообщение #55


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



во блин... странно... вчера вроде не получалось обнаружить эффект, а сегодня получилось... извините за беспокойство - я прошляпил...

P.S. что это опция линкера - я и был в курсе...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Клим
сообщение Aug 19 2010, 13:22
Сообщение #56


Местный
***

Группа: Свой
Сообщений: 230
Регистрация: 7-04-08
Из: Украина, Запорожье
Пользователь №: 36 541



Возможно уже такой вопрос был, сходу не нашел.
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.
Каким образом можно это победить ?
Go to the top of the page
 
+Quote Post
SysRq
сообщение Aug 19 2010, 13:46
Сообщение #57


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(Клим @ Aug 19 2010, 17:22) *
Каким образом можно это победить ?
Использовать атрибуты OS_main, OS_task? http://electronix.ru/forum/index.php?s=&am...st&p=441344
Go to the top of the page
 
+Quote Post
Клим
сообщение Aug 19 2010, 14:40
Сообщение #58


Местный
***

Группа: Свой
Сообщений: 230
Регистрация: 7-04-08
Из: Украина, Запорожье
Пользователь №: 36 541



Цитата(SysRq @ Aug 19 2010, 16:46) *
Использовать атрибуты OS_main, OS_task? http://electronix.ru/forum/index.php?s=&am...st&p=441344

Спасибо, помогло. OS_main убирает ненужные заталкивания в стек, но call main все равно остается )
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 20 2010, 15:53
Сообщение #59


;
******

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



Цитата(Клим @ Aug 19 2010, 18:40) *
call main все равно остается )

Это уже из области стартапа. Поменяйте в стартапе rcall на rjmp
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 8 2011, 07:48
Сообщение #60


;
******

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



Кто-нибудь может объяснить феномен. -Os
CODE

#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;
}

Листинг правильный - его не привожу, т.к. все тривиально
Дальше, если это сделать в таком виде
CODE

#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;
}

Листинг - конец света. Выкинул, родимый, все на корню.
CODE

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.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 05:46
Рейтинг@Mail.ru


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