假日嵌入式系統工程師:SEGGER RTT (2)
假日嵌入式系統工程師:SEGGER RTT (2)
簡介
這篇文章介紹我怎麼在WINDOWS平台跑起SEGGER-RTT。看完以後,你大概會發現這東西比想像還要容易設定。因為SEGGER RTT Viewer只提供WINDOWS版,所以這篇文章沒得選;不過下一篇SEGGER RTT (3)就會介紹怎麼在Linux/ Mac使用。而且這個形式是我個人最滿意的Log system的樣貌。再聊一下SEGGER JLINK
我用中國做的NRF51822板子,上面有謎版的JLINK。我有買一顆JLINK-EDU,也算是合法使用吧。SEGGER的JLINK是相當出色的工具,基礎版的JLINK-EDU價格殺到2400NTD,值得投資一套。另一個合法管道是買NRF51-DK,上面也有JLINK on board。RTT 程式碼
安裝完SEGGER driver以後,可以在底下目錄找到壓縮檔/c/Program Files (x86)/SEGGER/JLink_V50i/Samples/SEGGER_RTT_V510i.zip
解壓縮以後,把裡面的這些檔案拷貝到自己的MCU projects裡:RTT/SEGGER_RTT.c
RTT/SEGGER_RTT.h
RTT/SEGGER_RTT_Conf.h
RTT/SEGGER_RTT_printf.c
我用的NRF SDK (nRF51_SDK_10.0.0_dc26b5e)也有RTT library,路徑是$(NRF51_SDK)/components/drivers_ext/segger_rtt/
編譯 RTT 程式
把上面四個C file加到MCU project某個目錄,應該很容易就能編譯過。我用了GCC & KEIL-C都沒問題。SEGGER RTT Library提供一個簡化版的printf()
int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);
我們在MCU寫一個簡單的程式:unsigned int buf_idx = 0;
while(1) {
unsigned int i;
for(i=0; i<256; i++) {
SEGGER_RTT_printf(buf_idx, "Hello World %d\n", i);
nrf_delay_ms(100);
}
}
Host-Side Application
在Windows裡打開RTT Viewer,這個程式需要設定JLINK參數:- Connection type,選USB
- SWD Speed
- MCU Type
然後J-Link RTT Viewer就會show出我們的debug訊息了,超簡單的!
JLINK 的 TELNET SERVER
JLINK.exe會創造一個TELNET server,跑在port 19021。連上去以後就能取得MCU丟出來的資訊。用這招的話,可以把RTT嵌在別的程式裡,比如把丟出來的數值當場算一下FFT做圖。底下是這個能力的介紹,下一篇文章會擴充這個idea。Step.1 單獨跑JLINK.EXE
開一個terminal window跑JLINK.exe,底下是我塞到Makefile的指令,這些參數其實和塞給JLink RTT Viewer的一樣,而且會自動連線。執行下去後,會產生一個視窗如下。看到下圖,Telnet Server @ port 19021就啟動了:"/c/Program Files (x86)/SEGGER/JLink_V510i/JLink.exe" -device nrf51822 -if swd -speed 4000 -autoconnect 1
Step.2 用Windows內建的TELNET連到JLINK-RTT
如果用Windows 10,預設系統沒telnet;用Administrator開一個cmd視窗跑底下的命令安裝:dism /online /Enable-Feature /FeatureName:TelnetClient
接下來就連線到本機的 port 19021,就可以看到如JLINK RTT Viewer的結果了:telnet localhost:19021
Step.3 用Python的Telnet Library 連線 JLINK RTT
要把RTT嵌在自己的應用程式裡,(2)的telnet顯然不合用。Python正好有Telnet library能提供(2)的效果。底下的Python code應該意義非常明確,在最內層的While Loop會不斷把訊息印出來。這個框架稍微加工一下,就能輕易的做各種後處理,比如把log寫到檔案,或即時做FFT作圖之類的應用。import sys
import telnetlib
import os
def main():
os.system('taskkill -im jlink.exe')
os.system(r'start "" "c:\Program Files (x86)\SEGGER\JLink_V510i\JLink.exe" -device nrf51822 -if swd -speed 4000 -autoconnect 1')
rtt = telnetlib.Telnet('localhost', 19021)
while(True):
data = rtt.read_until('\n')
print(data), # one may do further processing here
return 0
if __name__ == '__main__':
sys.exit(main())
結論
- 如果只要一個Log window,我建議使用RTT Viewer。他可以印彩色字串,還有Virtual terminal能用,用這個取代TeraTerm就能讓日子過得不錯。
- 在Mac/Linux就算沒有RTT Viewer,使用Python版本的script也是不錯的替代品。
- 如果想對log做點手腳,比如一邊印一邊紀錄到檔案,或著算點有的沒有的,用Python telnetlib連線再做後處理很合用。
- 如果想進一步壓縮Log的開銷,下一篇文章有更潮的手段。
參考文章
[1]: SEGGER’s RTT introduction website, https://www.segger.com/jlink-rtt.html[2]: Debugging with Real Time Terminal, https://devzone.nordicsemi.com/tutorials/6/
[3]: Python’s telnetlib, https://docs.python.org/2/library/telnetlib.html
[4]: SEGGER-RTT (1), http://lihgong.blogspot.com/2016/04/segger-rtt-1.html
留言
import telnetlib
import os
def main():
os.system('taskkill -im jlink.exe')
os.system(r'start "" "C:\Program Files (x86)\SEGGER\JLink\JLink.exe" -device STM32F103RC -if swd -speed 4000 -autoconnect 1')
sleep(20) #最好睡一下
rtt = telnetlib.Telnet('localhost', 19021)
while(True):
data = rtt.read_until('\r\n'.encode())#我用python3,这里要加encode()
print(data), # one may do further processing here
return 0
if __name__ == '__main__':
sys.exit(main())