[MSP432 – gcc] Works with linker option -Og but geneates hardfault with linker option -Os

Hi, I am using msp 432 port blinky demo modified to use software timer to toggle periodically instead of taskDelayUntil. toolchain: GNU ARM embedded toolchain 5-2016-q3 update ID: eclipse cdt with plugin http://gnuarmeclipse.github.io/ working set up: compiler flags: -mcpu=cortex-m$(CORTEX_M) -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -ffunction-sections -fdata-sections -Dgcc -Wall -std=c11 -Og -g -gstrict-dwarf -fmessage-length=80 –specs=nano.specs linker flags: -mcpu=cortex-m$(CORTEX_M) -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -ffunction-sections -fdata-sections -Dgcc -Wall -Og -g -gstrict-dwarf -Xlinker –cref -Wl,–gc-sections –specs=nano.specs Not working( hardfault ) set up: compiler flags: -mcpu=cortex-m$(CORTEX_M) -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -ffunction-sections -fdata-sections -Dgcc -Wall -std=c11 ****-Os -g -gstrict-dwarf **** linker flags: -mcpu=cortex-m$(CORTEX_M) -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -ffunction-sections -fdata-sections -Dgcc -Wall ****-Os -g -gstrict-dwarf**** -Xlinker –cref -Wl,–gc-sections –specs=nano.specs the only difference between these two setups is the optimization level -Og and -Os. I tried this setup: http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html. It enters hardfault handler. But it doesnt hit the breakpoint at end of prvGetRegistersFromStack instead it jumps back to main. Please provide inputs on how it could be resolved.

[MSP432 – gcc] Works with linker option -Og but geneates hardfault with linker option -Os

Jumping back to main() makes it sound like the board is resetting. Could it be a watchdog reset? Do you have an infinite loop at the end of the hardfault handler? Something like: for( ;; ); so the code should not go anywhere even if the breakpoint is not hit? I suspect the breakpoint isn’t being hit because with the high optimisation level GCC cannot directly correlate a line of C code to its assembly code output.

[MSP432 – gcc] Works with linker option -Og but geneates hardfault with linker option -Os

Thank you for the reply. It seems like an issue in ResetHandler ISR and I added the code in ResetHandler to zero fill the bss and the problem seems to have disappeared. Now, the question is, since bss was uninitialized and heap for freertos is in bss segment(as I observed in linker map file), would it have caused prvMalloc to fail? if yes, I do not understand why it worked with optimization level -Og ?

[MSP432 – gcc] Works with linker option -Og but geneates hardfault with linker option -Os

yes, the hardfault handler has an infinite loop at the end but couldnt get it to hit the breakpoint.

[MSP432 – gcc] Works with linker option -Og but geneates hardfault with linker option -Os

Thank you for the reply. It seems like an issue in ResetHandler ISR and I added the code in ResetHandler to zero fill the bss and the problem seems to have disappeared.
None of executed compiled C code is going to be valid if the C run-time is not set up BEFORE main() is called.
Now, the question is, since bss was uninitialized and heap for freertos is in bss segment(as I observed in linker map file), would it have caused prvMalloc to fail? if yes, I do not understand why it worked with optimization level -Og ?
The answer to that is, it might have caused it to fail or it might not, and it may have been inconsistent between builds. Like I said, C assumes things are initialised correctly before the C code is executed, and any execution that occurs when things are not initialised cannot be predicted in advance. Changing the optimisation level will greatly change how, when and which variables are accessed, and if the variables have random numbers in them rather than initialised values then it is conceivable the behaviour will be completely different at different optimisation levels.

[MSP432 – gcc] Works with linker option -Og but geneates hardfault with linker option -Os

This seems to be an issue with TI’s compiler setup. For some reason, TI have always insisted on /not/ clearing bss at startup, with all their compilers and libraries. I first had problems with this 20 years ago, and it is still their policy on all their tools (it is part of the startup code, rather than the compiler itself, that is responsible for this clearing). I have seen a mention of this mis-feature deep within one of their compiler manuals, with a note saying that this is not standard C behaviour. Their reasoning is that clearing bss increases startup time, and means hardware watchdogs may trigger before main() starts – though there are several far better methods of solving such issues. I think TI’s compilers should come with a warning message “Warning – TI feels it is more important that your code starts quickly than that it works correctly, and we don’t think following C standard behaviour is important.” As for why the code works with -Og and not -Os, the most likely reason is that when you have -Og you are probably debugging and the microcontroller is not being powered off between runs. So once there is data in the bss variables that works (or appears to work), the next time you start the program you will see the same values there. But if you have been powering the card off and on again, then there will be random data in the memory.