嵌入式開發筆記——除錯元件SEGGER_RTT
阿新 • • 發佈:2020-12-20
# 一、前言
在嵌入式開發過程中,經常會通過列印輸出一些除錯資訊來除錯引數、查詢問題等,通常我的做法都是使用晶片的串列埠硬體裝置配合串列埠助手軟體來進行除錯。但是這次專案的PCB硬體設計並未預留串列埠除錯介面,所以想使用串列埠除錯就不方便了。經過查詢資料發現**Segger** 提供了一種非常方便的除錯方式——自家的`J-Link`硬體配合`J-Link RTT Viewer`軟體進行資訊輸入輸出除錯。
# 二、元件新增
要使用該除錯元件,需要新增Segger提供的SEGGER_RTT元件程式碼,該程式碼位於J-Link軟體安裝目錄下,而且在使用者手冊中提供了詳細的說明。
> 元件原始碼位置:
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012547505-1278875697.png)
> 使用者手冊位置:
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012600923-78502058.png)
在手冊的16章節對RTT元件進行了說明:
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012611159-469197709.png)
> 將元件原始碼複製到工程目錄下,工程中新增相關檔案及包含路徑:
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012622239-208762045.png)
最後在需要使用列印除錯資訊的檔案中包含`#include "SEGGER_RTT.h"`標頭檔案就可以使用該元件了。
# 三、元件應用
關於元件提供的各API函式在手冊中都有相應的說明。舉例應用如下:
> 輸出測試:
```c
int a = 3;
SEGGER_RTT_TerminalOut(0,RTT_CTRL_BG_BLACK""RTT_CTRL_TEXT_BRIGHT_GREEN"SEGGER_RTT_TerminalOut 0\r\n");
SEGGER_RTT_TerminalOut(1,RTT_CTRL_BG_BLUE""RTT_CTRL_TEXT_BRIGHT_YELLOW"SEGGER_RTT_TerminalOut 1\r\n");
SEGGER_RTT_SetTerminal(2);
SEGGER_RTT_printf(0,RTT_CTRL_BG_WHITE""RTT_CTRL_TEXT_BRIGHT_BLACK"SEGGER_RTT_printf 2\r\n");
SEGGER_RTT_SetTerminal(3);
SEGGER_RTT_printf(0,"SEGGER_RTT_printf %d\r\n", a);
```
開啟`J-Link RTT Viewer`軟體
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012647436-72055555.png)
RTT Viewer列印結果如下:
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012658495-1273453009.png)
> 輸入測試:
```c
int a;
while(1)
{
if ((a = SEGGER_RTT_WaitKey()) > 0)
{
SEGGER_RTT_SetTerminal(0);
SEGGER_RTT_printf(0, "SEGGER_RTT_GetKey = %c\r\n", a);
}
}
```
RTT Viewer列印結果如下:
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012712136-977651510.png)
# 四、擴充套件應用
經過上面對SEGGER_RTT的使用,發現其確實非常的方便,大多數除錯都能夠替代串列埠除錯實現了,但是`SEGGER_RTT_printf()`函式無法列印浮點數。手冊中對該函式列出了支援的轉換說明符如下:
| Conversion specifier | Meaning |
| :------------------: | :----------------------------------------------------------: |
| c | Print the argument as one char |
| d | Print the argument as a signed integer |
| u | Print the argument as an unsigned integer |
| x | Print the argument as an hexadecimal integer |
| s | Print the string pointed to by the argument |
| p | Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) |
其中並沒有浮點數`f`選項。但是可以使用SEGGER_RTT輸出函式自己修改一個printf函式,這樣就可以使用完整的printf函數了。
> 新增自己修改的printf函式如下:
```c
/*********************************************************************
*
* rtt_printf()
*
* Function description
* print a formatted string using RTT and standard library formatting.
**********************************************************************/
int rtt_printf(const char *fmt,...)
{
int n;
char aBuffer[256]; //根據應用需求調整大小
va_list args;
va_start (args, fmt);
n = vsnprintf(aBuffer, sizeof(aBuffer), fmt, args);
if (n > (int)sizeof(aBuffer)) {
SEGGER_RTT_Write(0, aBuffer, sizeof(aBuffer));
} else if (n > 0) {
SEGGER_RTT_Write(0, aBuffer, n);
}
va_end(args);
return n;
}
```
> 接下來測試浮點數列印:
```c
double fa = 0.1f;
double fb = 2.0f;
while(1)
{
fa += 0.0001f;
fb -= 0.0002f;
rtt_printf("floating test:\tfa = %f, fb = %f\r\n", fa, fb);
delay(0x0fffffff);
}
```
![](https://img2020.cnblogs.com/blog/2193174/202012/2193174-20201220012727855-21040580