环境
- STM32CubeIDE Version: 1.6.0 Build: 9614_20210223_1703 (UTC)
- STM32CubeMX Version: 6.2.0-RC3 Build: 20210219-1602 (UTC)
- FreeRTOS Kernel V10.0.1
- CMSIS-RTOS V1 API
现象
在Task中调用printf("%f",value)
来输出浮点数,却在任务切换时发生了HardFault中断
排查
最开始以为是printf不可重入,需要加临界区,但加了portENTER_CRITICAL()
后问题并未解决
曾一度怀疑是不是FreeRTOS的bug……后来发现并不是,人家FreeRTOS运行挺稳定的
google搜索:“freertos printf %f”,发现遇到同样问题的人还挺多的……
st社区中的这篇文章以及openrtos中的这篇文章最后都将原因指向了newlib
原因锁定
Newlib是STM32Cube中唯一使用的运行时库,它是不支持FreeRTOS下线程安全的动态内存分配的(无论是直接还是间接调用malloc),这个问题ST官方也没有很好地解决。
解决方案
确实没有既方便又能从根本上解决问题的方法,但是只选其一的话还是有办法的
- 便捷的解决方案:不使用printf输出浮点数,正常输出整型字符型不会出现此bug
- 完整的解决方案:参考这篇文章的Recommended Solution Details,会有些繁琐……
PS
其实已经有许多地方对这个问题进行了说明,只是太不容易找到了……
- STM32Cube的配置页面
- FreeRTOS Kernel Customisation