關(guān)于SEGGER RTT
具體的描述還是看官網(wǎng)的介紹吧,點(diǎn)這里仅仆。一般只用來輸出調(diào)試日志,偶爾也需要通過它來配置一些參數(shù)蛔糯。雖然segger官方提供了RTT Viewer來查看輸出數(shù)據(jù),也可以發(fā)送數(shù)據(jù)窖式,類似于精簡版的串口調(diào)試助手蚁飒,但畢竟過于簡單。某些場景萝喘,比如生產(chǎn)測試工具淮逻,還是差了不少。本文主要是通過一個例子說明如何訪問RTT阁簸,從而開發(fā)自己需要工具爬早。
關(guān)于pylink
pylink是一個用python寫的jlink操作庫。通過這個庫强窖,可以很方便的通過jlink訪問目標(biāo)芯片凸椿,從而實(shí)現(xiàn)自己的想法。這個庫的安裝翅溺、使用方法脑漫,點(diǎn)這里。
訪問RTT的例子
這個例子通過將寫入的數(shù)據(jù)讀回來說明如何訪問RTT咙崎,這個是需要芯片端程序支持的优幸,固件需要將down buffer里的數(shù)據(jù)寫到up buffer。
import pylink
jlink = pylink.JLink()
jlink.open()
jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
jlink.connect('AMAPH1KK-KBR')
jlink.rtt_start()
print('Please enter rtt write data and click ENTER:')
writedata = input()
jlink.rtt_write(0, [ord(x) for x in list(writedata)])
print()
print('Echo data:')
readdata = ''.join([chr(x) for x in jlink.rtt_read(0, len(writedata))])
print(readdata)
jlink.rtt_stop()
jlink.close()
步驟說明:
- 1褪猛、先
open
网杆,連接上jlink; - 2伊滋、設(shè)置連接目標(biāo)芯片的接口碳却,一般是
SWD
,如果缺少這一步笑旺,連接目標(biāo)芯片時很容易失斨缙帧; -
3筒主、通過名字連接目標(biāo)芯片关噪,這個名字可以在jlink的工具里找到,比如
- 4乌妙、操作RTT前使兔,需要使用
rtt_start
開啟RTT,不開啟的話藤韵,后續(xù)對RTT的操作都是無效的虐沥; - 5、通過
rtt_write
將需要的數(shù)據(jù)寫入RTT泽艘,第一個參數(shù)是RTT的down buffer的索引置蜀,第二參數(shù)就是要寫的數(shù)據(jù)奈搜,單次寫的數(shù)據(jù)量取決于下位機(jī)中down buffer的最大值。這部分設(shè)置是在芯片程序上配置的盯荤,默認(rèn)是有3個down buffer馋吗,最大16個bytes;
這里著重講一下[ord(x) for x in list(writedata)]
:- (1)秋秤、
list(writedata)
是將要發(fā)送的數(shù)據(jù)轉(zhuǎn)成列表宏粤,比如發(fā)送數(shù)據(jù)為"test"
,那就轉(zhuǎn)為['t', 'e', 's', 't']
灼卢∩馨ィ可以把這個看作C語言的數(shù)組,每個元素就是一個byte鞋真,所以['test']
是會報(bào)錯的崇堰; - (2)、
[ord(x) for x in list(writedata)]
將前面列表中的每個元素轉(zhuǎn)為對應(yīng)的ascii碼涩咖,[116, 101, 115, 116]海诲,直接寫['t', 'e', 's', 't']
是會報(bào)錯的; - (3)檩互、因?yàn)?code>rtt_write第二個參數(shù)要求是一個列表特幔,所以帶了
[]
。
- (1)秋秤、
- 6闸昨、通過
rtt_read
讀取RTT中的數(shù)據(jù)蚯斯,第一個參數(shù)是up buffer的索引,第二個參數(shù)是要讀回來的數(shù)據(jù)量饵较,如果buffer中的數(shù)據(jù)小于這個值拍嵌,那就讀完回來了。''.join([chr(x) for x in jlink.rtt_read(0, len(writedata))])
的操作正好跟上一步的寫數(shù)據(jù)相反循诉,[chr(x) for x in jlink.rtt_read(0, len(writedata))]
將讀到的數(shù)據(jù)轉(zhuǎn)為字符横辆,再通過''.join
將字符拼接為字符串。 - 7打洼、操作結(jié)束后,通過
rtt_stop
停止RTT逆粹; - 8募疮、最后通過
close
斷開與jlink的連接,同時也斷開了與目標(biāo)芯片的連接僻弹。
讀寫接口
前面的例子可以看到阿浓,pylink提供的讀寫接口只是單純的讀寫數(shù)據(jù),需要我們自己進(jìn)行字符串到列表或者列表到字符串的轉(zhuǎn)換蹋绽。下面是自己封裝的讀寫接口芭毙,其中BUFFER_SIZE_UP
需要根據(jù)自己的實(shí)際情況定義筋蓖。
def RTT_write_string(link, string, end=b'\r\n'):
"""寫字符串到RTT down buffer
Args:
link: the ``JLink`` instance
string: 待寫入的字符串
end: 字符串的結(jié)尾,默認(rèn)使用windows格式退敦,可選項(xiàng)
Returns:
成功寫入的字節(jié)數(shù)
"""
writedata = list(bytearray(string, "utf-8") + end)
writeindex = 0
bytes_written = 0
try:
if link.target_connected():
while writeindex < len(writedata):
bytes_written = link.rtt_write(0, writedata[writeindex:])
writeindex = writeindex + bytes_written
time.sleep(0.03)
return bytes_written
except pylink.errors.JLinkException:
return -1
def RTT_read_string(link):
"""從RTT up buffer讀取字符串
Args:
link: the ``JLink`` instance
Returns:
讀到的字符串
"""
try:
if link.target_connected():
readdata = link.rtt_read(0, BUFFER_SIZE_UP)
if len(readdata) > 0:
readdata = ''.join(map(chr, readdata))
else:
readdata = []
except pylink.errors.JLinkException:
readdata = []
pass
return readdata
其它
pylink要求jlink的驅(qū)動版本>= 6.0b
粘咖,該版本的jlink SDK原生提供了RTT的訪問。如果使用5.xx
或者更低版本的驅(qū)動侈百,可以通過在內(nèi)存中搜索_SEGGER_RTT
并解析它瓮下,從而實(shí)現(xiàn)RTT的操作。這里分享一個例子钝域。