Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Cortex-M3 GCC, копия таблицы векторов в 2 адресах
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Cosmojam
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 адресу, то как это сделать?
demiurg_spb
Цитата(Cosmojam @ Aug 17 2013, 15:42) *
LPC1788, gcc. Есть загрузчик и приложение. Нужно сделать чтобы один и тот же бинарник с приложением можно было прошивать и через загрузчик и напрямую через ISP без оного.
Не совсем понимаю что вы хотите...
ИМХО возможны 4 варианта:
1) Бинарник бутлоадера (для прошивки по ISP).
2) Бинарник приложения склеенный с бутлоадером (для прошивки по ISP).
3) Бинарник приложения (для прошивки через бутлоадер).
4) Бинарник приложения (для прошивки через ISP).

И во всех этих случаях мы имеем разные результирующие бинарные файлы.
Cosmojam
Цитата(demiurg_spb @ Aug 17 2013, 14:56) *
Не совсем понимаю что вы хотите...
ИМХО возможны 4 варианта:
1) Бинарник бутлоадера (для прошивки по ISP).
2) Бинарник приложения склеенный с бутлоадером (для прошивки по ISP).
3) Бинарник приложения (для прошивки через бутлоадер).
4) Бинарник приложения (для прошивки через ISP).

И во всех этих случаях мы имеем разные результирующие бинарные файлы.

Нужно чтобы один и тот же бинарник приложения (только приложение, не склеенное с бутлоадером) можно было прошивать и через ISP и через бутлоадер.
demiurg_spb
Цитата(Cosmojam @ Aug 17 2013, 16:11) *
Нужно чтобы один и тот же бинарник приложения (только приложение, не склеенное с бутлоадером) можно было прошивать и через ISP и через бутлоадер.

Ок. Т.е. вы хотите совместить пункты 3 и 4. Не думал, что это возможно (я ещё не реализовывал пока загрузчик для cm3)...

Тогда вам видимо нужно держать копию таблицы векторов в ОЗУ.
И не важно кто её туда будет копировать загрузчик или приложение или оба, как видимо вы хотите.
Важно не забыть поправить SCB->VTOR.

У меня всё равно нет окончательного понимания как оно заработает.
При наличии загрузчика он проверит целостность приложения, настроит NVIC для работы с нужной таблицей векторов и передаст управление приложению.
Когда нет загрузчика, то приложение сразу стартует и всё делает само.
Получается приложение находится в этих двух случаях по разным адресам, т.е. это разные бинарники.
Golikov A.
можно склеить 2 приложения в одно
то есть 3 и 4 друг за другом положить, получив двойной объем но легкий старт... хотя конечно метод кривой...
andrewlekar
Вопрос, конечно, интересный, но по-моему сделать так, как хочет ТС нереально. Если даже что-то получится, то бинарнику придётся затирать загрузчик, так как в начале находятся вектора загрузчика, а ТС желает, чтобы после загрузки по ISP стартовало приложение - придётся затирать вектора и загрузчик похерится.
Если делать приложение совмещённое с загрузчиком, то будет всё равно как загружать, через ISP или через бутлоадер, однако нужно будет организовать релокацию приложения в ОЗУ (что накладывает серьёзные ограничения на размер приложения), либо делать хитрый загрузчик с подменой адресов (тут я себе плохо представляю как организовать), либо размещать в ОЗУ только часть, связанную с загрузкой приложения. Все варианты одинаково плохи.
Cosmojam
ТС сам плохо представляет это возможным, но заказчик требует так и предлагает вариант с копией таблицы векторов приложения по 0 адресу. Тогда по идее загрузчик может записывать приложение с нужным смещением из файла игнорируя первые 0x4000 байт из файла. Вот пробуя это не получилось разместить 2 копии таблицы по 0 и 0x4000 адресам.
andrewlekar
Я же говорю, если будет копия векторов по 0 адресу, то загрузчик перестанет запускаться.
_Артём_
Цитата(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. Если его нет, то и так будет работать.
demiurg_spb
Цитата(_Артём_ @ Aug 18 2013, 00:29) *
В случае если загрузчик есть, то он должен перед запуском приложения задать VTOR. Если его нет, то и так будет работать.
Я правильно понимаю, что вы предлагаете откусить от бинарника загрузчика таблицу векторов и передать её приложению?
А что будет при неудачном обновлении приложения?

Cosmojam
Артём, спасибо большое. То что надо. Вроде получилось.

Для повторения самому себе:
У приложения посредствам линкера зарезервирована область памяти, в которой должен располагаться загрузчик (первые 0x4000 байт в моём случае);
У приложения 2 копии таблицы векторов: одна в 0, и одна в 0x4000;
В случае прошивки бинарника приложения напрямую через ISP используется таблица, которая по 0 адресу. Загрузчика нет в этом случае;
В случае использования загрузчика для прошивки приложения, от бинарника приложения откусываются первые 0x4000 байт (они зарезервированы линкером) и файл прошивается по адресу 0x4000 с таким же смещением внутри файла;
Поскольку у приложения копия таблицы векторов расположена по 0x4000, то переход на этот адрес из загрузчика приведёт к запуску приложения. В самом приложении необходимо указать расположение таблицы векторов на 0x4000.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.