你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【源码】STM32的printf重定向解决方案——史上最强?

[复制链接]
radio2radio 发布时间:2020-12-13 19:15
为什么要用printf,废话,不用你用啥? 我在下面的把printf换了一个名,LOG,少打3个字。您也可以换成您喜欢的字母组合,这不是重点。

说是“解决方案+史上最强”,也不过就是下面的几行代码。
笔者仅在CubeMX+HAL+MDK+AC5下,测试过F1和F4。 其他环境要修改后使用。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. //Debug mode On/Off switch
  5. #define DEBUG                   1 //set=0, disable all LOG lines

  6. //select one of the following "printf" retarget methods
  7. #define PRINTF_UART             0 //printf using UART port, 1-use this, 0-not
  8. #define PRINTF_RTT              1 //printf using Segger RTT, 1-use this, 0-not
  9. #define PRINTF_SWO              0 //printf using SWO port, 1-use this, 0-not
  10. #define PRINTF_CDC              0 //printf using USBD_CDC, 1-use this, 0-not

  11. #if ((PRINTF_UART + PRINTF_CDC + PRINTF_SWO + PRINTF_RTT) != 1)
  12. #error "!!!!!! printf retarget function Not define or Multi-defined !!!!!!"
  13. #endif

  14. #if DEBUG
  15.   #if PRINTF_RTT
  16.     #include "SEGGER_RTT.h"
  17.     #define LOG(format, args...)  SEGGER_RTT_printf(0, "[%s:%d] "format, __FILE__, __LINE__, ##args)
  18.     #define printf(format, args...)  SEGGER_RTT_printf(0, format, ##args)
  19.    
  20.   #else //#if PRINTF_RTT
  21.     #define LOG(format, args...)  printf("[%s:%d] "format, __FILE__, __LINE__, ##args)
  22.    
  23.     #if PRINTF_CDC
  24.     #include "usbd_cdc_if.h"
  25.     #endif
  26.    
  27.     int fputc(int ch, FILE *f)
  28.     {
  29.       #if PRINTF_UART
  30.         HAL_UART_Transmit(&huart3, (uint8_t*)(&ch), 1, 1000); //UART3
  31.         
  32.       #elif PRINTF_SWO
  33.         ITM_SendChar(ch);
  34.         
  35.       #elif PRINTF_CDC
  36.         uint8_t u8Temp = 0;
  37.         while(CDC_Transmit_FS((uint8_t*)(&ch), 1) != USBD_OK)
  38.         {
  39.           HAL_Delay(1);
  40.           if (++u8Temp >= 3) break;
  41.         }
  42.       #endif //#if PRINTF_UART
  43.         
  44.       return(ch);
  45.     }
  46.   #endif //#if PRINTF_RTT
  47.   
  48. #else //#if DEBUG == 0
  49.   #define LOG(args...) //disable all LOGs when compiling
  50. #endif //#if DEBUG
复制代码

这里有4种方法重定向printf,必有一款适合你:

1. PRINTF_UART == 1,串口方法。
优点: 就是最多人使用的,大家也最熟悉。 配置简单,容易使用。 各种“PC终端软件”都能用。
缺点: 硬件上要有串口可以用,有时还需要UART转USB接口板(或者仿真器自带VCP/CDC的东东)配合。

2. PRINTF_RTT == 1,Segger_RTT 方法。  (笔者推荐此方法,至少值得尝试一次), 要安装RTT包,简单!
优点: 不占用额外的硬件资源, 据说速度超级快。 有多快,我不知道。
缺点: 要使用专用的PC软件接收,既然是仿真器大佬Segger的产品,自然是Segger的驱动程序功能多多。
           使用J-LINK仿真器,就一定要用JLinkRTTViewer等终端软件。
           使用CMSIS-DAP仿真器,可以用DRTTView终端软件, 多谢XIVN1987网友 ,不然DAP就不能用RTT了。
           使用STLINK仿真器,对不起,用不了。

3. PRINTF_SWO == 1,SWO的方法,这个是启动内核的ITM功能。
优点: 对原程序流的影响最小。 标准的JTAG/SWD/STLINK连接器,都已经准备好了SWO线,也算方便。
缺点: 相比2线的SWD,需要硬件连接一条SWO的输出线。 不能实现双向通信(其他方法都能)。
            软件配置SWO功能比较复杂很容易失败,重点是要做SWO速度匹配。
            SWO方法不能在JTAG模式下使用,只能是SWD模式。另外,ARM Cotex-M0/M0+也不能用。
            MDK/Keil有内置的SWO Viewer,不过不好用,一定要进入Debug模式,好处是各种仿真器都可以用。
            J-LINK 和 STLINK 仿真器,有自己的独立的SWO Viewer,不需要Keil进入Debug模式那么麻烦。

4. PRINTF_CDC == 1, CDC的方法,比较逆天的,属于玩具级别,你想用我都拦不住。
优点: 用法与UART一样,各种串口终端软件通杀。
           不占用串口。 利用IC本身的CDC-VCP节省了UART转USB接口板。
缺点: IC要有USB硬件,代码增加,软件复杂度增加。

实用中,还有一种方法,称为半主机模式(semihosting),据说速度慢和影响原程序运行严重,没有认真研究过。我甚至怀疑,上面的4种方法里面,有可能有后台使用了半主机模式,知道详情的朋友,请介绍一下。

毕竟printf指令对原程序流是多余的操作,或多或少都会干扰原程序流,特别是在一些速度比较慢的MCU上面。因此,printf的输出项要尽量简短,避免大量连续使用。 如果估计占用MCU时间太多,就要做需求评估。


附件是F103/F407用的完整的工程,与github上传的一样,上面的4种方法都有,可以试一试实现。
github:https://github.com/RadioOperator/STM32_HAL_retarget_printf



STM32_HAL_retarget_printf-master.zip

下载

1.36 MB, 下载次数: 12

评分

参与人数 1 ST金币 +10 收起 理由
子曰好人 + 10 很给力!

查看全部评分

收藏 3 评论5 发布时间:2020-12-13 19:15

举报

5个回答
goyhuan 回答时间:2020-12-14 08:20:52
强大
七哥 回答时间:2020-12-14 09:14:10
纳百家之所长,长己之技能
子曰好人 回答时间:2020-12-14 09:32:46
支持老兄,点个赞
kylixyao 回答时间:2020-12-14 18:21:45
非常不错!
radio2radio 回答时间:2020-12-15 12:22:34

多谢您的鼓励。
我还是把F407的例程放出来了,同时也上传了github,留个记录。

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版