基于jlink-RTT-view 和 lettershell的shell管理工具
在我们实际的项目里,很多时候都没有串口留出来用于调试,这样增加了调试的难度,做一些测试也没有预留的接口可以修改,很麻烦,因此我这边整合了RTT-view和lettershell,提供了一套只需要使用jlink即可使用shell工具调试代码的功能。
在我们实际的项目里,很多时候都没有串口留出来用于调试,这样增加了调试的难度,做一些测试也没有预留的接口可以修改,很麻烦,因此我这边整合了RTT-view和lettershell,提供了一套只需要使用jlink即可使用shell工具调试代码的功能。
1.RTT-View如何使用
【嵌入式小技巧】STM32 实现 SEGGER RTT 打印(超详细)-CSDN博客
基本移植我就不再赘述,我这边介绍一些一个如何快速上手
1.1RTT-View初始化
#define SEGGER_UP_BUFF_SIZE (256)
#define SEGGER_DOWN_BUFF_SIZE (256)
#define SEGGER_INDEX_LINE (0)
uint8_t g_ucaRTTUp0Buffer[SEGGER_UP_BUFF_SIZE] = {0};
uint8_t g_ucaRTT_BufferDown0Buffer[SEGGER_DOWN_BUFF_SIZE] = {0};
void SeggerInit(void)
{
SEGGER_RTT_ConfigUpBuffer(SEGGER_INDEX_LINE, "Terminal", g_ucaRTTUp0Buffer, sizeof(g_ucaRTTUp0Buffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
SEGGER_RTT_ConfigDownBuffer(SEGGER_INDEX_LINE, "Terminal", g_ucaRTT_BufferDown0Buffer, sizeof(g_ucaRTT_BufferDown0Buffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
SEGGER_RTT_SetTerminal(SEGGER_INDEX_LINE);
}
初始化代码很简单,只需要指定指定发送的端口,并且设置收发的缓冲区即可,但事实上,我指定rtt-view发出的端口无效,最终内容输出在All Terminals,但是无伤大雅。
SEGGER_RTT_Write(SEGGER_INDEX_LINE, buff, size)
RTT发送十分简单,直接调用SEGGER_RTT_Write即可
if(SEGGER_RTT_HasKey())
{
uint8_t ucGetChar;
ucGetChar = SEGGER_RTT_GetKey();
buff[0] = ucGetChar;
return 1;
}
RTT的接受有多种方式,我这边通过SEGGER_RTT_HasKey和SEGGER_RTT_GetKey组合即可,SEGGER_RTT_HasKey判断接受的缓冲是否有内容,SEGGER_RTT_GetKey读取一个字节
2.Letter-shell如何使用
STM32HAL 移植功能强大letter-shell开源库(裸机开发)_裸机 letter shell-CSDN博客
介绍letter-shell的文章也很多,我这边简述以下
void log_write(char *buff,short len);
Shell shell;
char shellBuffer[512];
Log uartLog = {
.write = log_write,
.active = LOG_ENABLE,
.level = LOG_DEBUG
};
signed short shell_read(char *buff, unsigned short len)
{
if(SEGGER_RTT_HasKey())
{
uint8_t ucGetChar;
ucGetChar = SEGGER_RTT_GetKey();
buff[0] = ucGetChar;
return 1;
}
return 0;
}
signed short shell_write(char *buff, unsigned short len)
{
SEGGER_OUT(buff, len);
return len;
}
void log_write(char *buff,short len)
{
SEGGER_OUT(buff, len);
}
void userShellInit(void)
{
shell.write = shell_write;
shell.read = shell_read;
shellInit(&shell, shellBuffer, 512);
logRegister(&uartLog, &shell);
}
实际上letter-shell的移植也就三个部分,实现shell的读,写,以及日志的读写,如果不需要使用日志,有关日志注册的内容可以删除,我这边就保留了
简单介绍以下代码shell_write直接调用SEGGER_OUT,将内容打印到RTT-View上,shell_read通过读取一个字节,并返回给shell,log部分的内容我就不介绍了
注意,letter-shell有两种使用办法,第一种办法是在接受到字符的中断中调用 shellHandler,第二种办法实在主循环中调用shellTask(&shell),其中的shell是我们注册的shell结构体。
以上我们就能将letter-shell和RTT-View结合到一起
3.快速入手
我这边已经将所需要的文件打包好,并且写了注册有关代码,只需要调用几个初始化函数即可使用,我简单的介绍一些文件文件结构

tool.c中集成了我一些平时用的常见的模块,可以不用理会

在tool.h中有USE_SEGGER_RTT 的宏定义,需要设置为1,其他设为0即可

letter_shell文件夹下除了user_shell以外的内容都是letter-shell本身自带的文件,包括log文件夹下的内容,user_shell则是注册letter-shell读写的内容,就是上面第二部分的内容

RTT文件夹下是RTT—View所移植的文件,直接添加到编译即可,无需修改
另外两个文件夹的内容是用于单元测试,不用处理
我现在总结使用流程
1.将tool.h tool.c letter_shell文件夹 RTT文件夹下的内容添加到编译中
2.设置 USE_SEGGER_RTT 为 1
3.调用初始,初始化RTT-View和letter-shell
SeggerInit();
userShellInit();
4.在主循环中调用 shellTask(&shell);
5.打开j-link RTT Viewer

6.选择对应的芯片

7.点击OK,打开

8.点击input ->Sending->send on Enter
9.输入help,点击enter查看是否正常工作

4.仓库地址
以上代码我提交在gitee仓库,需要的自取
5.Unity 单元测试框架
基于以上 RTT-Viewer输如输出结合Letter-shell 管理框架,在此基础上可以添加Uniyt单元测试框架,用于进行单元测试,方便修改参数
Unity单元测试框架是由UNITY_OUTPUT_CHAR 宏定义来实现输出接口函数,因此只要将该宏定义修改成RTT-Viewer的输出即可,代码如下


在此基础上,只需要完成测试样例,并且将测试函数定向到外部指令,则可以通过shell工具调用单元测试样例。
编写测试样例

调用测试样例

将测试样例定向到shell指令

调用单元测试指令

更多推荐



所有评论(0)