Управление при запуске Keil RTX
Я пишу загрузчик для ARM Cortex-M3, который использует относительно сложный интерфейс связи; это то же самое, что и фактическое использование приложения. Приложение использует RTX Keil в качестве своего ядра, и коммуникационный стек полагается на это. Использование GCC, конечно.
Загрузчик выполняет следующие основные шаги:
- При запуске проверяет правильность образа приложения; если ничего не доступно, он входит в режим обновления;
- Проверяется нажатие кнопки как запрос на вход в режим обновления; если он находит это, он входит в режим обновления.
- Найдя действительный образ и не запрашивая обновления, он "загружает" приложение.
Это довольно упрощенно, но описывает сценарий адекватно нашим целям.
Последняя проблема, которая оказалась неожиданно сложной, - это загрузка приложения. Идея состоит в том, чтобы отключить прерывания, установить таблицу векторов, указатель стека и перейти к вектору сброса приложения в новой таблице векторов. Все это работает просто замечательно, за исключением того, что вскоре после этого я получаю Hard Fault.
В ходе экспериментов, если я делаю это в тривиальном загрузчике (который не использует RTX или, конечно, стек comms), загрузка приложения работает нормально. Так что, похоже, проблема в RTX.
Дело в том, что настоящему загрузчику не нужен RTX, пока он не войдет в режим обновления. Таким образом, очевидный подход заключается в том, чтобы не запускать RTX, пока мы не определим, что он нам нужен; однако кажется, что он взломан в коде запуска, и поэтому, когда я вхожу в код загрузчика, уже слишком поздно; действительно, функция загрузчика main() уже является потоком!
Лучшим подходом, кажется, не является запуск RTX (жаль, что я не использовал FreeRTOS!), Пока он мне не понадобится; однако, это, кажется, требует некоторого взлома. Альтернативный подход заключается в том, чтобы каким-то образом отключить все прерывания и исключения, но по какой-то причине я тоже не добился успеха там. У кого-нибудь есть примеры того или иного подхода?
1 ответ
В случае, если кто-то сталкивается с этой ситуацией, решение на самом деле довольно простое. Я только что настроил функцию SystemInit() в файле system_efm32gg.c! Хотя _efm32gg зависит от поставщика, похоже, что system_X.c является широко используемой конструкцией ARM - по крайней мере, я видел ее с ST, NXP и EnergyMicro/SiliconLab - так что это приличный общий подход.
Я должен был знать лучше! вздох