SEGGER 的实时传输 (RTT) 是一种用于嵌入式应用程序中交互式用户 I/O 的技术。它以非常高的性能结合了 SWO 和半主机的优势。但是在笔者使用时(RTT v758版本),其暂时不支持浮点数打印的功能。我们可以通过修改源码添加该功能。
-
跳转到
RTT>SEGGER_RTT_printf.c>SEGGER_RTT_vprintf(unsigned, const char*, va_list*)
函数中。 -
找到原代码中判断输出类型的部分,是使用switch-case判断类型的。
// // Handle specifiers // switch (c) { case 'c': { char c0; v = va_arg(*pParamList, int); c0 = (char)v; _StoreChar(&BufferDesc, c0); break; } case 'd': v = va_arg(*pParamList, int); _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); break; case 'u': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); break; case 'x': case 'X': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); break; case 's': { const char * s = va_arg(*pParamList, const char *); do { c = *s; s++; if (c == '\0') { break; } _StoreChar(&BufferDesc, c); } while (BufferDesc.ReturnValue >= 0); } break; case 'p': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); break; case '%': _StoreChar(&BufferDesc, '%'); break; default: break; }
-
将该部分代码略作修改,添加打印浮点数的部分。默认输出两位浮点数。
// // Handle specifiers // switch (c) { case 'c': { char c0; v = va_arg(*pParamList, int); c0 = (char)v; _StoreChar(&BufferDesc, c0); break; } case 'd': v = va_arg(*pParamList, int); _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); break; case 'u': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); break; case 'x': case 'X': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); break; case 's': { const char * s = va_arg(*pParamList, const char *); do { c = *s; s++; if (c == '\0') { break; } _StoreChar(&BufferDesc, c); } while (BufferDesc.ReturnValue >= 0); } break; case 'p': v = va_arg(*pParamList, int); _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); break; case '%': _StoreChar(&BufferDesc, '%'); break; // 添加输出浮点数的功能。默认带两位小数。 case 'f': case 'F': { float fv = (float)va_arg(*pParamList, double); // 取出输入的浮点数值 if(fv < 0) _StoreChar(&BufferDesc, '-'); // 判断正负号 v = abs((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; } default: break; }