SEGGER RTT printf 的移植和浮点数处理

SEGGER RTT printf 的移植和浮点数处理,第1张

1. 从安装目录下找到RTT源代码

C:\Program Files\SEGGER\JLink\Samples\RTT

将压缩包解压,解压后目录如下

将RTT中源代码拷贝至项目工程中

2. 修改配置和源代码
  1. SEGGER_RTT_Config.h 中可根据需要裁剪内存占用大小,和是否启动LOCK和UNLOCK, 并添加浮点数支持的宏定义

    //! 浮点数的支持(需要420 BYTE的flash空间)
    #ifndef SEGGER_RTT_PRINT_FLOAT_ENABLE
        #define SEGGER_RTT_PRINT_FLOAT_ENABLE                 (1)
    #endif
    
  2. 如何支持浮点数打印,修改SEGGER_RTT_printf.c

  3. 调用关系SEGGER_RTT_printf–>SEGGER_RTT_vprintf, 固在SEGGER_RTT_vprintf中添加如下代码

    int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) {
      char c;
      SEGGER_RTT_PRINTF_DESC BufferDesc;
      int v;
      unsigned NumDigits;
      unsigned FormatFlags;
      unsigned FieldWidth;
      char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE];
    
      BufferDesc.pBuffer        = acBuffer;
      BufferDesc.BufferSize     = SEGGER_RTT_PRINTF_BUFFER_SIZE;
      BufferDesc.Cnt            = 0u;
      BufferDesc.RTTBufferIndex = BufferIndex;
      BufferDesc.ReturnValue    = 0;
    
      do {
        c = *sFormat;
        sFormat++;
        if (c == 0u) {
          break;
        }
        if (c == '%') {
          //
          // Filter out flags
          //
          FormatFlags = 0u;
          v = 1;
          do {
            c = *sFormat;
            switch (c) {
            case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break;
            case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO;     sFormat++; break;
            case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN;   sFormat++; break;
            case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE;    sFormat++; break;
            default:  v = 0; break;
            }
          } while (v);
          //
          // filter out field with
          //
          FieldWidth = 0u;
          do {
            c = *sFormat;
            if ((c < '0') || (c > '9')) {
              break;
            }
            sFormat++;
            FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0');
          } while (1);
    
          //
          // Filter out precision (number of digits to display)
          //
          NumDigits = 0u;
          c = *sFormat;
          if (c == '.') {
            sFormat++;
            do {
              c = *sFormat;
              if ((c < '0') || (c > '9')) {
                break;
              }
              sFormat++;
              NumDigits = NumDigits * 10u + ((unsigned)c - '0');
            } while (1);
          }
          //
          // Filter out length modifier
          //
          c = *sFormat;
          do {
            if ((c == 'l') || (c == 'h')) {
              sFormat++;
              c = *sFormat;
            } else {
              break;
            }
          } while (1);
          //
          // Handle specifiers
          //
          switch (c) {
    		...
    
    //! ============================================================
            //! 支持浮点数  
    #if (SEGGER_RTT_PRINT_FLOAT_ENABLE != 0)	
            case 'f':
            case 'F':
            {
                float fv;
                fv = (float)va_arg(*pParamList, double);    //取出输入的浮点数值
    
                v = (int)fv;                                //取整数部分
    
                _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); //显示整数,支持负数
                _StoreChar(&BufferDesc, '.');                                        //显示小数点
    
                v = abs((int)(fv * 100));               
                v = v % 100;
                _PrintInt(&BufferDesc, v, 10u, 2, FieldWidth, FormatFlags);          //显示小数点后两位
            }
            break;
    #endif	
    //! ============================================================
    
          default:
            break;
          }
          sFormat++;
        } else {
          _StoreChar(&BufferDesc, c);
        }
      } while (BufferDesc.ReturnValue >= 0);
        
        ...
    }
    
3. 用户层封装, 在头文件中实现如下代码
//! 调试输出配置
#define RTT_DBG_ENABLE          (1)

#if RTT_DBG_ENABLE
    #include "SEGGER_RTT.h"
	/* 初始化调试模块 */
    #define DEBUG_INIT()    SEGGER_RTT_Init()
    /* RTT 终端号 */
    #define RTT_DBG_PORT        0
    #define LOG_PROTO(type,color,format,...)                        \
            SEGGER_RTT_printf(RTT_DBG_PORT,"%s%s"format"\r\n%s",    \
                            color,                                  \
                            type,                                   \
                            ##__VA_ARGS__,                          \
                            RTT_CTRL_RESET)
    /* 清屏*/
    #define log_clear()     SEGGER_RTT_WriteString(RTT_DBG_PORT, "  "RTT_CTRL_CLEAR)
    /* 无颜色日志输出 */
    #define log_debug(format,...)   LOG_PROTO("D:","",format,##__VA_ARGS__)
    /* 有颜色格式日志输出 */
    #define log_info(format,...)    LOG_PROTO("I:", RTT_CTRL_TEXT_BRIGHT_GREEN , format, ##__VA_ARGS__)
    #define log_warn(format,...)    LOG_PROTO("W:", RTT_CTRL_TEXT_BRIGHT_YELLOW, format, ##__VA_ARGS__)
    #define log_error(format,...)   LOG_PROTO("E:", RTT_CTRL_TEXT_BRIGHT_RED   , format, ##__VA_ARGS__)

#else
    #define DEBUG_INIT()
    #define log_clear()
    #define log_debug
    #define log_info
    #define log_warn
    #define log_error
#endif
4. 测试

这样浮点数打印以及日志颜色都能使用了,注意:浮点数只能打印两位,如需要更多则修改源码即可

参考链接1:用VS Code开发STM32(四)——增加SEGGER RTT日志输出支持
参考链接2:给SEGGER RTT的 SEGGER_RTT_printf() 函数添加浮点显示功能

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/713524.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-24
下一篇 2022-04-24

发表评论

登录后才能评论

评论列表(0条)

保存