Grr, I just lost the fairly long post I wrote up on this topic.
I’ll try it again, but it’s going to be just the bare bones, no examples, just hints.
The key to getting app and loader to coexist and load properly (without overwriting each other) with the SW4STM32 tools is to make sure you’ve got the linker config files (*.ld) for both loader and app set up properly.
Make sure that the MEMORY ROM region defined only includes the portion of FLASH that your loader or application will reside in. That is, the ROM definition should exclude the portion of FLASH that belongs to the other component.
In my particular case, the loader is allocated the first 16K, and the application gets the rest. If your FLASH size is 128K, you’d specify:
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 16K
for the loader, and
ROM (rx) : ORIGIN = 0x08004000, LENGTH = 96K
for the application.
You need to make sure that the interrupt vectors are getting loaded into the right place. I recall having some problems with this at one time during development of my app/loader project, but looking at what I have now, I don’t see the need to change anything related to the .isr_vector section handling in the linker config or the system_xxx.s source file where the vectors are defined.
If you’re using a device with a M0 core (STM32F0xxx variant) you’ll have to jump through a bunch of hoops and play around with RAM/FLASH overlaying to get the right interrupt vector table (app or loader) in effect. All other core types (including the STM32F4 - M4 core) you can just set SCB->VTOR to point to the IVT you want to be in effect.
One issue I DO have with all versions of SW4STM32 is that if I attempt to run a full debug session on my (F0-based) application, it won’t start up properly after initial load, even if both loader and app are resident in FLASH. It seems as if the debugger does not perform a true target reset when it starts up; it tries to jump to the app entry point (which will fail miserably in a mixed app+loader environment, esp. on a M0 core with no VTOR), instead of resetting so the loader gets initial control. With the addition of the reset button in the debugger since ver. 2.0, I can work around this problem - the debugger works exactly as expected if I reset the target using the debugger UI’s reset button first.