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:
- On startup, checks for a valid app image; if none available, it enters upgrade mode;
- It checks for a button press as a request for enter upgrade mode; if it finds that, it enters upgrade mode.
- 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?