LPC1768 загружает приложение в новое смещение памяти

Вопрос: - как найти приложение по адресу, отличному от 0x0000.0000? Процессор: NXP LPC1768 Система разработки: Keil ARM 4.73

Используемые шаги: 1) приведенный ниже файл разброса, используемый для установки области загрузки и области выполнения на 0x0000.2000 2) скопированная векторная таблица на 0x2000 3) обновленный регистр vtor на 0x2000

Проблема: Приложение не запускается.

Scatter file used:
LR_IROM1 0x00002000 0x00000D000     
{   ; load region size_region
  ER_IROM1 0x00002000 0x0000D000    
  { ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x10000000 0x00008000    {   ; RW data
   .ANY (+RW +ZI)
  }
}

Это следует инструкциям, указанным в примечании к приложению NXP AN10744, что-то еще, что я упустил?


person whitedog    schedule 14.04.2014    source источник


Ответы (1)


Регистр смещения векторной таблицы (VTOR) указывает на 0x00000000 при сбросе. Таким образом, указатель стека должен быть на 0x00000000, а начальный адрес программы (счетчик программы) на 0x00000004.

Если вы измените местоположение векторной таблицы в настройках компоновщика, вам необходимо обновить VTOR, чтобы он указывал на это новое местоположение. Это может произойти только во время выполнения.

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

Загрузчик должен:

  1. Убедитесь, что прерывания отключены, чтобы случайно не использовать VTOR.
  2. Обновите регистр VTOR по адресу 0x2000.
  3. Получить адрес указателя стека из 0x2000 и обновить регистр указателя стека.
  4. Получите начальный адрес программы от 0x2004 и обновите счетчик программ.

Возможно, вы захотите проверить библиотеку CMSIS, в ней есть такие функции, как NVIC_SetVTOR и __set_MSP, которые немного упрощают настройку этих регистров.

Чтобы установить программный счетчик, вы можете привести адрес к указателю функции, а затем вызвать функцию:

uint32_t * vtor = (uint32_t *)0x2000;
uint32_t startAddr = vtor[1];
( (void(*)(void))startAddr )(); // Cast and call
person user694733    schedule 16.04.2014