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; }
