I’m experiencing a annoying issue when attempting to use the AC6/eclipse debugger to run/debug my application that runs in conjunction with a bootloader.
I’m using v2.0 (latest version as of 13 Jun 2017) of SW4STM32 under Windows and Eclipse Neon v3. Target is a STM32F091; it’s a custom board but for all practical purposes it looks like a STM32F091 Nucleo board. Debug interface is STLink v2.1 (a Nucleo board). The problem I describe below is seen when I run my application on a STM32F091 Nucleo board as well as my custom hardware.
My application is split into a bootloader which resides in the first 32K of FLASH at 0x08000000, and application code that follows it at 0x08008000. The bootloader and application code perform the appropriate operations to put their respective interrupt vector tables (IVT) into effect when they run or control is passed back and forth between the two; this process works flawlessly when I run the application normally.
I’ve made appropriate changes to the linker configuration files, linker invocation and other project settings to ensure that the two pieces (bootloader and main app) coexist and won’t overwrite or erase each other when they are loaded onto the target via the debugger.
The problem I experience is that when I load and start the main app through the debugger, the debugger does not start up the target in the way I would expect. My expectation would be that the target would get reset, or at very least the reset vector would be fetched from the bootloader’s interrupt vector table (the one in effect after a MCU reset) and execution would start with the bootloader, eventually branching off to run the main app, which would hit the breakpoint set by the debugger at the start of main(), then stop.
What I see instead is that execution begins at what I think is the application code’s entry point. I’m not really sure. What I do know is that it is NOT starting at the bootloader’s reset/entry point. Since the bootloader portion never gets executed, the system environment (which is partially set up by the bootloader), and in particular, the operations done to make the application’s IVT active are not done. The application starts up running in a unexpected, misconfigured environment and crashes as soon as interrupts are enabled.
The crash and behavior I see is not at all unexpected if it is being started up without the bootloader running first. My concern here is not the crash or misbehavior itself, but the fact that the target is being started up in an unusual / unexpected fashion when the debugger starts up.
Now, if I force a debugger/target reset using the new “reset button” feature added to the debugger in the v2.x SW4STM32 branch, everything works as expected. Bootloader runs, sets up environment, passes control to application, which halts due to breakpoint auto-set by the debugger at the start of the application’s main().
What I’m asking for here is a high-level explanation of how the debugger starts up the target when it is first entered, and if there’s a workaround that I can achieve, perhaps through the use of customized OpenOCD or GDB scripts, to make the debugger perform a full target reset on debugger startup, or at least start execution at the targets normal reset vector - the one normally feched by the core out of FLASH following a reset at address 0x00000000.
I’m also wondering if there’s a way to get both bootloader and application symbol tables loaded into the debugger at the same time, so I can perform source-level debug on both bootloader and application at the same time. At present, I can load either the bootloader -xor- application and source-level debug for the portion loaded, but can only debug at the asm level the portion that was not explicitly loaded. Unfortunately, it appears that the Eclipse “Launch group” concept does not work for this, as this is more geared for starting up multiple processes in a OS-hosted environment.