gccarmrtx

Controlling when Keil RTX starts


I am writing a bootloader for an ARM Cortex-M3 that utilizes a relatively complex communications interface; this is the same as the actual application uses. The application uses Keil's RTX as its kernel, and the communications stack relies on that. Using GCC, of course.

The bootloader does the following basic steps:

  1. On startup, checks for a valid app image; if none available, it enters upgrade mode;
  2. It checks for a button press as a request for enter upgrade mode; if it finds that, it enters upgrade mode.
  3. Having found a valid image and there is no request to upgrade, it "boots" the app.

This is rather simplified, but it describes the scenario adequately for our purposes.

The final problem that has surprisingly proved difficult is booting the app. The idea is to disable interrupts, set the vector table, stack pointer, and jump to the app's reset vector in the new vector table. All this works just peachy, except that shortly thereafter, I get a Hard Fault.

Through experiments, if I do this in a trivial bootloader (that does not use RTX or, of course, the comms stack), the boot to the app works fine. So it seems RTX is the problem.

The thing is, the real bootloader doesn't need RTX until it enters its Upgrade mode. So the obvious approach is to not start RTX until we have determined we need it; however, it seems it is hacked into the startup code, and so by the time I get into the bootloader code, it is too late; indeed, the bootloader main() function is a thread already!

The best approach seems to be not starting RTX (too bad I hadn't used FreeRTOS!) until I need it; however, that seems to require some hacking. An alternate approach would be to somehow disable all interrupts and exceptions, but for some reason, I haven't been successful there either. Does anyone have examples of either approach?


Solution

  • In case someone comes across this situation, the solution is actually quite simple. I just customized the SystemInit() function in the system_efm32gg.c file! While the _efm32gg is vendor specific, it does seems the system_X.c is a widely used ARM construct - at least, I've seen it with ST, NXP, and EnergyMicro/SiliconLab - so this is a decent general approach.

    I should have known better! sigh