|
|
  |
Cortex-M3 GCC, копия таблицы векторов в 2 адресах |
|
|
|
Aug 17 2013, 11:42
|
Местный
  
Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182

|
LPC1788, gcc. Есть загрузчик и приложение. Нужно сделать чтобы один и тот же бинарник с приложением можно было прошивать и через загрузчик и напрямую через ISP без оного. Я не понимаю как это сделать, но говорят что надо разместить копию таблицы векторов приложения по 0 адресу. Т.е. на случай приложения без загрузчика (прошито через ISP, например) мы стартуем с 0 адреса, оттуда попадаем по нужному адресу с приложением (0x4000), там таблица векторов перемещается на начальный адрес приложения (0x4000) и т.к. таблицы одинаковые и на 0 и на 0x4000, то всё должно работать. Пока пытаюсь запустить такой вариант и не получается. Делаю в скрипте линкера Код MEMORY { FLASH (rx) : ORIGIN = 0x4000 LENGTH = 0x7C000 SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x10000 PIRAM(rw) : ORIGIN = 0x20000000, LENGTH = 0x8000 SDRAM (rw) : ORIGIN = 0xA0080000, LENGTH = 0x10000 VECTORS_AT_ZERO (rx) : ORIGIN = 0x0 LENGTH = 0x1FF } .text : { KEEP(*(.isr_vector)) } > VECTORS_AT_ZERO .text : { KEEP(*(.isr_vector)) *(.text*) *(.rodata*)
} > FLASH В стартап файле Код extern void (* const g_pfnVectors[])(void); __attribute__ ((section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { // Core Level - CM3 (void *)&_vStackTop, // The initial stack pointer ResetISR, // The reset handler Но работает только 1 раз сразу же после прошивки через ISP, потом после сброса уже не работает до следующей прошивки. Подскажите как можно решить эту задачу? Если размещением копии таблицы векторов по 0 адресу, то как это сделать?
--------------------
typedef enum { no, yes, maybe } bool; | блог тут
|
|
|
|
|
Aug 17 2013, 11:56
|

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

|
Цитата(Cosmojam @ Aug 17 2013, 15:42)  LPC1788, gcc. Есть загрузчик и приложение. Нужно сделать чтобы один и тот же бинарник с приложением можно было прошивать и через загрузчик и напрямую через ISP без оного. Не совсем понимаю что вы хотите... ИМХО возможны 4 варианта: 1) Бинарник бутлоадера (для прошивки по ISP). 2) Бинарник приложения склеенный с бутлоадером (для прошивки по ISP). 3) Бинарник приложения (для прошивки через бутлоадер). 4) Бинарник приложения (для прошивки через ISP). И во всех этих случаях мы имеем разные результирующие бинарные файлы.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 17 2013, 12:11
|
Местный
  
Группа: Свой
Сообщений: 311
Регистрация: 12-01-11
Из: Калининград (Koenigsberg)
Пользователь №: 62 182

|
Цитата(demiurg_spb @ Aug 17 2013, 14:56)  Не совсем понимаю что вы хотите... ИМХО возможны 4 варианта: 1) Бинарник бутлоадера (для прошивки по ISP). 2) Бинарник приложения склеенный с бутлоадером (для прошивки по ISP). 3) Бинарник приложения (для прошивки через бутлоадер). 4) Бинарник приложения (для прошивки через ISP).
И во всех этих случаях мы имеем разные результирующие бинарные файлы. Нужно чтобы один и тот же бинарник приложения (только приложение, не склеенное с бутлоадером) можно было прошивать и через ISP и через бутлоадер.
--------------------
typedef enum { no, yes, maybe } bool; | блог тут
|
|
|
|
|
Aug 17 2013, 12:51
|

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

|
Цитата(Cosmojam @ Aug 17 2013, 16:11)  Нужно чтобы один и тот же бинарник приложения (только приложение, не склеенное с бутлоадером) можно было прошивать и через ISP и через бутлоадер. Ок. Т.е. вы хотите совместить пункты 3 и 4. Не думал, что это возможно (я ещё не реализовывал пока загрузчик для cm3)... Тогда вам видимо нужно держать копию таблицы векторов в ОЗУ. И не важно кто её туда будет копировать загрузчик или приложение или оба, как видимо вы хотите. Важно не забыть поправить SCB->VTOR. У меня всё равно нет окончательного понимания как оно заработает. При наличии загрузчика он проверит целостность приложения, настроит NVIC для работы с нужной таблицей векторов и передаст управление приложению. Когда нет загрузчика, то приложение сразу стартует и всё делает само. Получается приложение находится в этих двух случаях по разным адресам, т.е. это разные бинарники.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 17 2013, 18:30
|
Знающий
   
Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163

|
Вопрос, конечно, интересный, но по-моему сделать так, как хочет ТС нереально. Если даже что-то получится, то бинарнику придётся затирать загрузчик, так как в начале находятся вектора загрузчика, а ТС желает, чтобы после загрузки по ISP стартовало приложение - придётся затирать вектора и загрузчик похерится. Если делать приложение совмещённое с загрузчиком, то будет всё равно как загружать, через ISP или через бутлоадер, однако нужно будет организовать релокацию приложения в ОЗУ (что накладывает серьёзные ограничения на размер приложения), либо делать хитрый загрузчик с подменой адресов (тут я себе плохо представляю как организовать), либо размещать в ОЗУ только часть, связанную с загрузкой приложения. Все варианты одинаково плохи.
|
|
|
|
|
Aug 17 2013, 20:29
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Cosmojam @ Aug 17 2013, 21:47)  Вот пробуя это не получилось разместить 2 копии таблицы по 0 и 0x4000 адресам. Скрипт линкера: CODE ENTRY(Reset_Handler)
_Minimum_Stack_Size = 0x100;
MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K }
/* higher address of the user mode stack */ PROVIDE ( _estack = ALIGN(ORIGIN(RAM) + LENGTH(RAM) - 8 ,8) );
SECTIONS {
.text : { . = ALIGN(4); KEEP(*(.isr_vector)) . = ALIGN(4);
. = 0x0B8;// первый байт после таблицы векторов KEEP(*(.bootloader_code)); . = 0x1000; KEEP(*(.isr_vector2)) __ctors_start__ = .; KEEP(SORT(*)(.init_array)) /* eabi uses .init_array for static constructor lists */ __ctors_end__ = .;
__dtors_start__ = .; __dtors_end__ = .; *(.text) /* remaining code */ *(.text.*) *(.rodata) /* read-only data (constants) */ *(.rodata.*)
*(.eh_frame_hdr) *(.eh_frame)
//----- и так далее startup.c: CODE __attribute__ ((section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { /* Core interrupt vectors */ (intfunc)((unsigned long)&_estack), Reset_Handler, NMI_Handler, HardFault_Handler, MemManage_Handler, BusFault_Handler, UsageFault_Handler, 0, 0, 0, 0, SVC_Handler, DebugMon_Handler, 0, PendSVC_ISR, SysTick_Handler,
/* Device interrupt vectors */ // остальные вектора };
// та же таблица, но по другому адресу __attribute__ ((section(".isr_vector2"))) void (* const g_pfnVectorsCopy[])(void) = { /* Core interrupt vectors */ (intfunc)((unsigned long)&_estack), Reset_Handler, NMI_Handler, HardFault_Handler, MemManage_Handler, BusFault_Handler, UsageFault_Handler, 0, 0, 0, 0, SVC_Handler, DebugMon_Handler, 0, PendSVC_ISR, SysTick_Handler,
/* Device interrupt vectors */
// остальные вектора }; В случае если загрузчик есть, то он должен перед запуском приложения задать VTOR. Если его нет, то и так будет работать.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|