|
Некорректная работа загрузчика, Самодельный загрузчик не прыгает по нужному адресу |
|
|
|
Apr 9 2011, 17:28
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 3-10-10
Пользователь №: 59 900

|
Всем привет! Камень: AT91SAM7S256 Проблема в следующем: написал загрузчик, который принимает bin файл и записывает его во флеш по нужному адресу ( к примеру 0x00108000). После записи выполняется прыжок на начальный адрес записи. Соответственно у программы которую я записываю через этот загрузчик я подправляю линкер, что бы функция main записывалась на нужный адрес (к примеру на 0x00108000). Перед прыжком включаю/отключаю подтягивающий резисор - все как надо. Если записывать программы работающие только с ЮЗБ (к примеру программа, которая по нажатию кнопки выводит слово hallo в терминал) то никаких проблем нет, все работает как надо. Но если записывать программу, работающую не только с ЮЗБ, но и с флешем (например считывает и записывает что то во флеш память), то прыжка никакого не происходит. Вместо этого загрузчик начинает свою программу загрузки заново ( выводит меню интерфейса, которое появляется в самом начале при запуске загрузчика). Мои подозрения падают на функцию, которая используется в записываемой программе(хотя я могу и ошибаться): Код extern unsigned int edata,etext,__bss_start,__bss_end__,_data; void copy_rom_ram(void) { unsigned int* p_rom, *p_ram; //-------------------- p_rom=&etext; p_ram=(unsigned int*)0x200000; while(p_ram<&edata) { *p_ram=*p_rom; p_ram++; p_rom++; } //--------------------------- p_ram=&__bss_start; while(p_ram<&__bss_end__) { *p_ram=0; p_ram++; } } Данная функция необходима для работы с флеш памятью. Возможно она работает некорректно или что то не так с линкером загрузчика. Может кто встречался уже с такой проблемой? Какие в принципе могут быть причины такого сброса программы? P.S. Для написание загрузчика использовал стандартный IAR проект.
Сообщение отредактировал AlfaStar - Apr 9 2011, 17:56
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Apr 12 2011, 15:08
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 3-10-10
Пользователь №: 59 900

|
Ну неужели никто не встречался с такой проблемой? Загрузчик после записи просто сбрасывается на начало, то есть как будто ничего и не записал. Тут дело именно в загрузчике, ибо программы, которые я прошиваю им, на других загрузчиках работают нормально!
|
|
|
|
|
Apr 12 2011, 17:27
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 3-10-10
Пользователь №: 59 900

|
Скорее всего дело именно в загрузчике. После записи принятой программы во флеш у меня выполняется прыжок ((void (*)(void))(0x108001))(); Соответственно в ликере программы, которую я записываю я ставлю: Код ...
MEMORY { FLASH (r) : ORIGIN = 0x00108000, LENGTH = 0x00038000 DATA (rw) : ORIGIN = 0x00200000, LENGTH = 0x00010000 STACK (rw) : ORIGIN = 0x00210000, LENGTH = 0x00000000 }
/* Section Definitions */
SECTIONS { /* first section is .text which is used for code */ . = 0x0000000;
.text : { *(.start) *(.text) /* remaining code */
*(.glue_7t) *(.glue_7)
} /*>FLASH
. = ALIGN(4);
/* .rodata section which is used for read-only data (constants) */
.rodata : { *(.rodata) } >FLASH
. = ALIGN(4);
_etext = .; PROVIDE (etext = .);
... А в самой программе функцию main изменяю и сразу выполняю функцию copy_rom_ram, которая описана выше дабы потом использовать флеш память: Код int __attribute__ ((section (".start"))) main ( void ) {
copy_rom_ram(); Именно использование этой функции и вызывает подозрения. Не работает именно тогда когда я ее добавляю. Но как я понимаю без нее никуда, с флешем если работать, то она нужна...
|
|
|
|
|
Apr 13 2011, 13:22
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 3-10-10
Пользователь №: 59 900

|
Загрузчик записывает принятую программу во флеш полностью (программа принимается по протоколу Ymodem). Затем выполняется прыжок. Получается что линкер тут не поможет и нам самим надо вручную (то есть такой функцией) прописывать перенос функций в RAM.
|
|
|
|
|
Apr 13 2011, 14:23
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 3-10-10
Пользователь №: 59 900

|
Сам загрузчик я записываю SAM-BA. Я тут не совсем понимаю конечно, но думаю что Самба сама выполняет запись функций в RAM. Линкер же просто обозначает что и по какому адресу должно лежать. Если при записи Самбой она сама помещает нужные функции в RAM, то когда загрузчик принимает файл bin он просто его записывает во флеш и ничего более. Ну по крайней мере, программа с функциями записи и чтения флеш памяти, при ее загрузке САмбой работает как надо... Если же эту программу прошить загрузчиком (ну с соответствующими изменениями в линкере), то ничего не работает. Андебаг (мигание светодиодом) показал что программа виснет именно на функции copy_rom_ram. Если ее просто исключить, то программа вообще не работает.
|
|
|
|
|
Apr 13 2011, 15:09
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 3-10-10
Пользователь №: 59 900

|
Для полного понимая, привожу полный код линкера программы, которую я записываю с помощью загрузчика: Код MEMORY { FLASH (r) : ORIGIN = 0x00108000, LENGTH = 0x00038000 DATA (rw) : ORIGIN = 0x00200000, LENGTH = 0x00010000 STACK (rw) : ORIGIN = 0x00210000, LENGTH = 0x00000000 }
/* Section Definitions */
SECTIONS { /* first section is .text which is used for code */ . = 0x0000000; /*.text : { *Cstartup.o (.text) }>FLASH =0*/ .text : { *(.start) *(.text) /* remaining code */
*(.glue_7t) *(.glue_7)
} /*>FLASH
. = ALIGN(4);
/* .rodata section which is used for read-only data (constants) */
.rodata : { *(.rodata) } >FLASH
. = ALIGN(4);
_etext = .; PROVIDE (etext = .);
/* .data section which is used for initialized data */
.data : AT (_etext) { _data = .; *(.data) SORT(CONSTRUCTORS) *(.ramfunc) } >DATA . = ALIGN(4);
_edata = .; PROVIDE (edata = .); /* .bss section which is used for uninitialized data */
.bss : { __bss_start = .; __bss_start__ = .; *(.bss) *(COMMON) } . = ALIGN(4); __bss_end__ = .; __bss_end__ = .; _end = .; PROVIDE (end = .);
. = ALIGN(4); .int_data : { *(.internal_ram_top) }> STACK
/* 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) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } } Дело в том что старт-ап в загружаемой программе я удалил, объясняя это тем, что вся инициализация железа прошла когда еще САм-ба прописывала загрузчик. А в загрузчике тоже присутствуют функции записи во флеш.
|
|
|
|
|
Apr 13 2011, 16:04
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 3-10-10
Пользователь №: 59 900

|
Попробую поэкспериментировать со Стартапом. Посмотрим, что получиться...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|