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 и т. д., попадают в исключения, но я не могу выяснить причину.