使用pylink访问SEGGER RTT

关于SEGGER RTT

具体的描述还是看官网的介绍吧,点这里。一般只用来输出调试日志,偶尔也需要通过它来配置一些参数。虽然segger官方提供了RTT Viewer来查看输出数据,也可以发送数据,类似于精简版的串口调试助手,但毕竟过于简单。某些场景,比如生产测试工具,还是差了不少。本文主要是通过一个例子说明如何访问RTT,从而开发自己需要工具。

关于pylink

pylink是一个用python写的jlink操作库。通过这个库,可以很方便的通过jlink访问目标芯片,从而实现自己的想法。这个库的安装、使用方法,点这里

访问RTT的例子

这个例子通过将写入的数据读回来说明如何访问RTT,这个是需要芯片端程序支持的,固件需要将down buffer里的数据写到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、设置连接目标芯片的接口,一般是SWD,如果缺少这一步,连接目标芯片时很容易失败;
  • 3、通过名字连接目标芯片,这个名字可以在jlink的工具里找到,比如
  • 4、操作RTT前,需要使用rtt_start开启RTT,不开启的话,后续对RTT的操作都是无效的;
  • 5、通过rtt_write将需要的数据写入RTT,第一个参数是RTT的down buffer的索引,第二参数就是要写的数据,单次写的数据量取决于下位机中down buffer的最大值。这部分设置是在芯片程序上配置的,默认是有3个down buffer,最大16个bytes;
    这里着重讲一下[ord(x) for x in list(writedata)]
    • (1)、list(writedata)是将要发送的数据转成列表,比如发送数据为"test",那就转为['t', 'e', 's', 't']。可以把这个看作C语言的数组,每个元素就是一个byte,所以['test']是会报错的;
    • (2)、[ord(x) for x in list(writedata)]将前面列表中的每个元素转为对应的ascii码,[116, 101, 115, 116],直接写['t', 'e', 's', 't']是会报错的;
    • (3)、因为rtt_write第二个参数要求是一个列表,所以带了[]
  • 6、通过rtt_read读取RTT中的数据,第一个参数是up buffer的索引,第二个参数是要读回来的数据量,如果buffer中的数据小于这个值,那就读完回来了。''.join([chr(x) for x in jlink.rtt_read(0, len(writedata))])的操作正好跟上一步的写数据相反,[chr(x) for x in jlink.rtt_read(0, len(writedata))]将读到的数据转为字符,再通过''.join将字符拼接为字符串。
  • 7、操作结束后,通过rtt_stop停止RTT;
  • 8、最后通过close断开与jlink的连接,同时也断开了与目标芯片的连接。
读写接口

前面的例子可以看到,pylink提供的读写接口只是单纯的读写数据,需要我们自己进行字符串到列表或者列表到字符串的转换。下面是自己封装的读写接口,其中BUFFER_SIZE_UP需要根据自己的实际情况定义。

def RTT_write_string(link, string, end=b'\r\n'):
    """写字符串到RTT down buffer
    Args:
        link: the ``JLink`` instance
        string: 待写入的字符串
        end: 字符串的结尾,默认使用windows格式,可选项
    Returns:
        成功写入的字节数
    """
    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的驱动版本>= 6.0b,该版本的jlink SDK原生提供了RTT的访问。如果使用5.xx或者更低版本的驱动,可以通过在内存中搜索_SEGGER_RTT并解析它,从而实现RTT的操作。这里分享一个例子

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。