Ошибка использования STM32 RTX PSP 0x00000020
У меня есть проект с STM32F446, с RTX, 3 потока (основной + 2 объявлен мной) +, конечно, бездействующий. Основной поток переходит в состояние ожидания после запуска двух потоков, поэтому у меня работает только два потока. RTX отключил циклический перебор. Приложение работает с модулем Bluetooth через SPI.
Моя проблема заключается в том, что иногда во время передачи SPI (инициируемой одним потоком и выполняемой в другом) MCU врезается в UsageFault_Handler, и один из потоков (не всегда один и тот же) показывается переполненным. Теперь я прочитал о том, как отлаживать аппаратные ошибки и что нет, но проблема в том, что все методы основаны на адресах MSP/PSP, а для меня PSP - 0x00000020. Кто-нибудь когда-либо сталкивался с чем-то подобным? Есть идеи, что может быть не так?
Л.Э.: С тех пор я узнал, что код работает с FreeRTOS, а не с RTX. Код использует критические разделы. Я пытался использовать ту же реализацию для критического раздела для RTX, что и для FreeRTOS(BASEPRI), но я часто оказываюсь в UsageFault. Я знаю, что RTX широко использует SVC в коде.
Может ли быть так, что критические разделы должны быть реализованы по-другому? Знаете ли вы о каких-либо других различиях между FreeRTOS и RTX, которые могут вызвать проблемы?
Позднее редактирование (решено): выясняется, что проблема связана с приоритетом, назначенным SysTick. Сначала он был настроен на самый низкий приоритет, как и должно быть, но где-то фрагмент кода где-то устанавливал SysTick на очень высокий приоритет.
Спасибо!
1 ответ
Когда функция возвращает свой указатель стека восстанавливается, если стек был поврежден, неверное значение может быть восстановлено, поэтому значение в SP не особенно полезно или информативно.
Конечно, все остальные регистры, включая программный счетчик, также могут быть повреждены. UsageFault происходит по неопределенным инструкциям, доступ к памяти без выравнивания - любой из которых вероятен, если возврат выполняется с поврежденным стеком, так как возврат может закончиться где угодно. Вы можете даже обнаружить, что изменение кода приводит к различным типам ошибок. Без учета кода невозможно определить причину, но вероятными проблемами являются переполнение буфера локальных данных или просто недостаточно выделенного стекового пространства.
Возможно, самый простой способ диагностировать эту ошибку - это использовать оборудование для отладки с возможностью трассировки, хотя это дороже, чем более простой отладчик JTAG или SWI.