Debugging FreeRTOS on STM32 Bluepill

Hi,

I believe I have found the problem and a solution - although I don’t understand why my solution solved anything.

In an earlier post, I stated that I had compared the compiler flags bing used and that no obvious differences sprang to my eye. However, while toying around with the build settings for the debug build yesterday I noticed that the example project uses quite a lot of build_flags and that PlatformIO uses dedicated debug_build_flags for the debug build - the regular build_flagsare completely ignored. Grasping at straws at this point, I just copied all the build_flags over to the debug_build_flags - and suddenly the debug build worked!

Armed with this knowledge and now a somewhat bigger straw I decided to systematically analyze whether I could point to any one of the build flags as the culprit (or savior, rather). I disabled all build flags and enabled them one by one, uploading the project each time to test it out. And it turns out: As soon as I set -Os, the project immediately started to work. Going back to the build logs I saw that the rehease build would always use -Os, whereas the debug build would use -Og. And sure enough: Using -Ogin the release build breaks the project as well.

Now, debugging a size-optimized executable makes for some funky debugging experience with the program counter going all over the place or breakpoints being hit only half of the time - but at least, the breakpoint in task1() was hit occasionally. So setting -Osfor the debugging usecase does not really help me with my actual proejct.

Fortunately, there are two ways to integrate libopencm3 and FreeRTOS. One is to use the forwarder-file opencm3.c proposed by Warren and used by Bastiaan. The other is to #define the names of the FreeRTOS function implementations to the names that libopencm3 expects:

#define vPortSVCHandler sv_call_handler
#define xPortPendSVHandler pend_sv_handler
#define xPortSysTickHandler sys_tick_handler

I verified that I hadn’t made a typo by patching libopencm3 on my disk to temporarily un-weak these symbols. Without the defines you get a linker error, with the defines the project links. And even better: with this approach, the project works reliably in both release build and debug build and the debugger hits the breakpoints just as you would expect. I recreated the experiment with an unmodified libopencm3 as currently provided by PlatformIO as well as with my actual project. They all work now. I created both an Issue and a Pull Request on Bastiaans’ repo.

However, I don’t understand why this optimization option causes this issue. While I would be ready to believe that size optimization causes the linker to replace the forwarding functions with the call to the actual function right away, why does having the forwarder then possibly present in the debug code break the project?

Regards
Damian