maudlu 发表于 2024-7-22 16:07

使用jlink-RTT Viewer组件进行打印

安装jlink驱动jlink官网 https://www.segger.com/downloads/jlink/ 一般下载最新版本即可https://i-blog.csdnimg.cn/blog_migrate/a9b987b641ff1b2775e3224678c3d3a8.png
安装完驱动后,开始菜单就会有 j-Link RTT Viewer图标
https://i-blog.csdnimg.cn/blog_migrate/0035eefe8b32569ac4b0857e4b9e829f.png移植RTT组件
[*]打开jlink驱动安装目录下的 \Samples\RTT\SEGGER_RTT_V722\RTT 文件夹 将文件复制到自己工程中
[*]RTT是jlink的组件,因此也可以移植到IAR工程使用,只要使用的是jlink或者DAP-link调试器即可
https://i-blog.csdnimg.cn/blog_migrate/dff8c3d16c8ba8408849cb44bc47ca2f.png
[*]将文件添加到工程中并添加文件路径
https://i-blog.csdnimg.cn/blog_migrate/a0d3c19973dc597a5cf4c0c929512e35.png
https://i-blog.csdnimg.cn/blog_migrate/ba3cde338ef4f3a02785dd7488230254.png
初始化RTT组件RTT组件默认有3个上行(单片机到RTT Viewer软件)缓冲区和3个下行(RTT Viewer软件到单片机)缓冲区,其中缓冲区0 用作printf打印功能,其他缓冲区可以用作波形显示
缓冲区0 大小可以在SEGGER_RTT_Conf.h中配置https://i-blog.csdnimg.cn/blog_migrate/9401437dafc4f86bd70b651b8efa2782.png
[*]RTT的速度除了和jlink硬件有关外,还和缓冲区大小有关
segger官方测试RTT速度在 STM32F407 168 MHz 情况下,发送一个字符在1个us,当然了官方用的jlink应该是36MHz的
根据jlink速度和自己上行带宽,可以粗略计算出缓冲区大小,官方也给出了参考缓冲区大小意见 https://www.segger.com/products/ ... real-time-transfer/https://i-blog.csdnimg.cn/blog_migrate/ac43a1f4fc4801873c0cea346eb0a869.png
[*]使用手头72MHz的stm32f105,配合keil 的Event Recorder中间件对打印10个字符进行测速,发现会比使用Event Recorder中间件的printf速度快上一些,原因大概是Event Recorder中间件使用的是printf,而SEGGER的RTT则是自己精简了printf函数(不支持浮点数和中文)
https://i-blog.csdnimg.cn/blog_migrate/dafdbdb6823384d26bd33287ce69790b.png
[*]只使用RTT组件的打印功能,只需要调用 SEGGER_RTT_Init()进行初始化即可。即使不初始化,在打印时,如果检测到没有初始化,会自行进行初始化,当然为了稳健最好还是调用SEGGER_RTT_Init()进行初始化
初始化将RTT的控制块名字赋值为"SEGGERRTT",并且将上行通道和下行通道0名字赋值为"Terminal",方便jlink通过扫描内存中的"SEGGERRTT"和"Terminal"找到RTT使用的内存。最重要的是将上行通道0和下行通道0和SEGGER_RTT.c中已经定义好了的缓冲区数组绑定起来(如果想使用其他通道,则需要自己开辟缓冲区数组)https://i-blog.csdnimg.cn/blog_migrate/96f56262fa3f519743646bda39e0422f.pngRTT组件打印#include "SEGGER_RTT.h"/* BufferIndex只能是0sFormat要打印的东西 *//* 该函数不支持打印中文和浮点型 *//* 如果想要打印中文和浮点型 可以使用printf函数,然后在 fputc 函数调用该函数 */int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...);https://i-blog.csdnimg.cn/blog_migrate/200fb8e17f7edeb571630cf442813e2c.pngjlink连接目标板,打开 j-Link RTT Viewer图标,设置单片机型号,连接成功后就会显示打印信息
https://i-blog.csdnimg.cn/blog_migrate/08e4ce23733e0d3f1f245ba89715566d.pnghttps://i-blog.csdnimg.cn/blog_migrate/6ab90113512e99337e32dc108ab75834.png
修改Terminal窗口j-Link RTT Viewer软件上有16个 Terminal窗口(都是利用上行缓冲区0发送数据的),在通过在SEGGER_RTT_printf函数打印前,使用 SEGGER_RTT_SetTerminal 函数设置 Terminal显示窗口,让不同信息显示在不同的Terminal窗口内,例如警告信息显示在一个Terminal窗口,错误信息显示在一个Terminal窗口,正常的log信息显示在一个窗口/* TerminalId 通道范围 0 - 15 */int   SEGGER_RTT_SetTerminal      (unsigned char TerminalId);RTT组件接受数据打印功能利用了RTT组件的上行缓冲区0,而接受则利用下行缓冲区0,如果要发送多个字符,可以适当改大下行缓冲区0的大小/* *    SEGGER_RTT_GetKey * *    函数描述:从缓冲区0读取一个字符 * *    返回值 *    <0 -   缓冲区没有数据 *    >= 0 -   缓冲区字符 */int          SEGGER_RTT_GetKey                  (void);/* *    SEGGER_RTT_HasData * *    函数描述:判断缓冲区是否有数据 *    BufferIndex:缓冲区序号 *    返回值 *    == 0 -   没有数据 *    != 0 -   有数据 */unsigned   SEGGER_RTT_HasData               (unsigned BufferIndex);/* *    SEGGER_RTT_HasKey * *    函数描述:判断缓冲区0是否有数据 * *    返回值 *    == 0 -   缓冲区没有数据 *    == 1 -   缓冲区有数据 */int          SEGGER_RTT_HasKey                  (void);/* *    SEGGER_RTT_Read * *    函数描述:从缓冲区读取N个字符 *    BufferIndex:缓冲区序号 *    pBuffer    :存放读取数据 *    BufferSize :读取长度 *    返回值   :实际读取的字节数 */unsigned   SEGGER_RTT_Read                  (unsigned BufferIndex,       void* pBuffer, unsigned BufferSize);/* *    SEGGER_RTT_ReadNoLock* *    函数描述:从缓冲区读取N个字符 *    BufferIndex:缓冲区序号 *    pBuffer    :存放读取数据 *    BufferSize :读取长度 *    返回值   :实际读取的字节数 *    注意       :和SEGGER_RTT_Read的区别是不带临界区保护 */unsigned   SEGGER_RTT_ReadNoLock            (unsigned BufferIndex,       void* pData,   unsigned BufferSize);/* *    SEGGER_RTT_GetBytesInBuffer * *    函数描述:获取缓冲区中数据数量 *    BufferIndex:缓冲区序号 *    返回值   :数据数量 */unsigned   SEGGER_RTT_GetBytesInBuffer      (unsigned BufferIndex);这些API互相配合,接收数据十分简单
https://i-blog.csdnimg.cn/blog_migrate/c891183527defd12e57ba6b8ba88d74a.pngRTT组件临界区保护RTT组件的临界区保护和freertos一样,使用basepri寄存器关闭中断,也就是说不受RTT组件临界区保护的中断服务函数中不能出现RTT组件的API函数。https://i-blog.csdnimg.cn/blog_migrate/f33e1af3092eeefcb619d2e30eff04fc.png
默认0x20,在stm32中(stm32只用了高四位)只有中断优先级0和1的不受RTT组件临界区关中断影响,因此中断优先级0和1的中断服务函数中不能出现RTT组件的API函数,否则可能会出现错乱。
https://i-blog.csdnimg.cn/blog_migrate/dc6c2d42204973f7c28a3a413f5b4657.png
后缀带NoLock的函数均不使用关中断临界区保护,一般不要使用

guijial511 发表于 2024-7-24 08:33

JLINK其实有很多实用的功能大部分人都没有用到。

地瓜patch 发表于 2024-7-29 21:58

在线仿真,喜欢仿真
页: [1]
查看完整版本: 使用jlink-RTT Viewer组件进行打印