环境

  • 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[BUG分析]FreeRTOS中使用printf输出浮点数导致Hardfault - 图1

原因锁定

Newlib是STM32Cube中唯一使用的运行时库,它是不支持FreeRTOS下线程安全的动态内存分配的(无论是直接还是间接调用malloc),这个问题ST官方也没有很好地解决。

解决方案

确实没有既方便又能从根本上解决问题的方法,但是只选其一的话还是有办法的

  • 便捷的解决方案:不使用printf输出浮点数,正常输出整型字符型不会出现此bug
  • 完整的解决方案:参考这篇文章的Recommended Solution Details,会有些繁琐……

PS

其实已经有许多地方对这个问题进行了说明,只是太不容易找到了……