Код перемещения ARM M3 - ›неисправности

ARM Cortex M3 (LPC1519)

Я написал загрузчик (который, кажется, пока работает), который запускается во флеш-памяти и записывает программу во флеш-память (за загрузчиком). Программа записывается и начинает нормально работать (по крайней мере, при отладке).

Когда я использую отладчик SEGGER Ozone, я могу установить точку останова на «main» и пройти через прошивку. Однако, когда я запускаю более крупную реакцию в коде (на другую точку останова), я всегда получаю неожиданные прерывания:

  • UsageFault_Handler
  • BusFault_Handler
  • и т.п.

Этого не происходит, когда я выполняю код команду за командой. Похоже, прерывания не будут работать должным образом.

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

У кого-нибудь были подобные проблемы?

Спасибо, Иоганн

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

Изменить - дополнительная информация. Я загрузил небольшой проект, в котором я могу найти ошибку в отладчике. В структуре есть переменная uint32_t, которая, кажется, вызывает ошибку. Он говорит:

Неправильно выровненное чтение из памяти: Адрес: 0x00001596, NumBytes: 8, Alignment: 4 (с выравниванием по словам)

На самом деле 0x1596 не делится на 4, поэтому ошибка оправдана, но как это может быть? Разве компилятор не должен позаботиться о выравнивании переменных в структурах?

Изменить - Дополнительная информация: Похоже, эта ошибка всегда возникает при срабатывании IRQ USART0 (txReady). Может быть, у меня проблема с прерываниями? ARM Cortex SysTick (SysTick_Handler) работает хорошо !?

[[noreturn]]
inline void startFirmware(std::uint32_t address) noexcept
{
    //<removed checks for correct address>

    //pointer to the address
    const auto ptr = reinterpret_cast<std::uint32_t*>(address);

    // Set vector table offset
    SCB->VTOR = address & SCB_VTOR_TBLOFF_Msk;

    // Set top stack handler
    __set_MSP(*ptr);

    // Get address of reset handler
    const auto resetHandler = *(ptr + 1);

    // Jump to reset handler
    reinterpret_cast<internal::ResetHandlerFunction>(resetHandler)();
    while(true);
}

Изменить - дополнительная информация. Похоже, что все прерывания, инициированные USART, CCTimer и т. д., попадают в исключения, но я не могу выяснить причину.


person Traummaennlein    schedule 17.05.2017    source источник
comment
Вы переместили векторную таблицу в начало вашего основного приложения?   -  person Colin    schedule 17.05.2017
comment
Фактически 0x1594 делится на 4 (но не на 8)!   -  person Realtime Rik    schedule 17.05.2017
comment
да, но не 0x1596. У меня это было прямо в сообщении об ошибке, но в предложении ниже ;-( исправлено - спасибо   -  person Traummaennlein    schedule 17.05.2017
comment
Я установил адрес векторной таблицы: SCB- ›VTOR = address;   -  person Traummaennlein    schedule 17.05.2017
comment
Я также установил указатель основного стека: __set_MSP (* ptr); где ptr - указатель на 'адрес'   -  person Traummaennlein    schedule 17.05.2017
comment
Я запустил пример, удалив много всего. Я подготовил USART0, но еще не запустил и прервал USART. Я подключил переключатель, который запускает прерывание готовности к передаче, и сразу получаю BusErrorInterrupt. SysTickInterrupt Worms в порядке.   -  person Traummaennlein    schedule 20.05.2017
comment
@old_timer добавление 1 перемещает указатель на следующий uint32_t, так как ptr сначала указывает на адрес, содержащий адрес указателя стека, а (ptr + 1) указывает на адрес, содержащий адрес обработчика сброса.   -  person Traummaennlein    schedule 22.05.2017
comment
Выровнен ли ваш стек на 8 байт, когда вы переходите к программе? Это требуется для eabi, и компилятор может хранить в нем 8-байтовые фрагменты, предполагая, что он выровнен   -  person Norbert Lange    schedule 22.05.2017
comment
ааа да, думал, вы используете это, чтобы установить lsbit. Как вы устанавливаете lsbit (при условии, что он установлен в таблице векторов, это нормально / хорошо). И использование VTOR с маской недостаточно, если адрес не выровнен должным образом, тогда таблица векторов не будет работать, поэтому это должна быть проверка и сбой, а не и с маской.   -  person old_timer    schedule 22.05.2017
comment
извините, не видел, что вы уже сами это поняли ...   -  person old_timer    schedule 23.05.2017
comment
Всем спасибо. Вы где тварь помогите !!   -  person Traummaennlein    schedule 24.05.2017


Ответы (1)


Я узнал, почему прерывания не сработали бы.

В ARM Doku Я нашел это предложение:

При установке TBLOFF необходимо выровнять смещение по количеству записей исключений в таблице векторов. Минимальное выравнивание - 32 слова, хватит до 16 прерываний. Чтобы получить больше прерываний, отрегулируйте выравнивание, округлив до следующей степени двойки. Например, если вам требуется 21 прерывание, выравнивание должно происходить по границе из 64 слов, потому что требуемый размер таблицы составляет 37 слов, а следующая степень двойки равна 64. Подробные сведения о выравнивании для вашего устройства см. В документации вашего поставщика.

Это означает, что когда у вас более 16 прерываний, вы не можете разместить свой SCB-> VTOR по адресам, выровненным по 32 словам (заканчивающимся на 0x80), а только по адресу, выровненному по 64 словам (заканчивающемуся на 0x00). В моем случае 0x1100 вместо 0x1080 (я использую первые 128 байт для информации о программе, которую загрузчик может проверить).

person Traummaennlein    schedule 22.05.2017