Shell 组件
简介
LISA Shell 是一个基于 Letter Shell 的命令行交互组件,为 ARCS SDK 提供串口命令行界面支持。通过 UART 接口,用户可以在终端中执行自定义命令、查看系统信息、调试应用程序等。
主要特性
UART 串口通信:基于 lisa_uart 驱动实现串口收发
FreeRTOS 任务集成:独立的 shell 任务处理用户输入
灵活配置:通过 Kconfig 配置任务优先级、缓冲区大小等参数
日志集成:自动接管系统日志输出到串口
命令扩展:支持使用
SHELL_EXPORT_CMD宏注册自定义命令多种回车模式:支持 LF、CR、CRLF 等多种命令行回车触发方式
组件架构
┌─────────────────────────────────────────┐
│ 用户应用程序 │
│ ┌──────────────────────────────────┐ │
│ │ SHELL_EXPORT_CMD 宏注册命令 │ │
│ └──────────────────────────────────┘ │
└─────────────┬───────────────────────────┘
│
┌─────────────▼───────────────────────────┐
│ LISA Shell 组件 │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ shell_task │ │ shell_write │ │
│ │ (接收处理) │ │ (输出函数) │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ ┌──────▼─────────────────▼───────┐ │
│ │ Letter Shell 核心库 │ │
│ │ (命令解析、命令管理、TAB补全) │ │
│ └──────────────────────────────┬─┘ │
└─────────────────────────────────┼──────┘
│
┌─────────────────────────────────▼──────┐
│ lisa_uart 驱动 │
│ (UART 接收/发送、缓冲区管理) │
└────────────────────────────────────────┘
配置选项
在 menuconfig 或 prj.conf 中可配置以下选项:
基本配置
配置项 |
说明 |
默认值 |
|---|---|---|
|
启用 LISA Shell 组件 |
n |
任务配置
配置项 |
说明 |
默认值 |
范围 |
|---|---|---|---|
|
Shell 任务栈大小 (字节) |
1024 |
- |
|
Shell 任务优先级 |
5 |
0-31 |
缓冲区配置
配置项 |
说明 |
默认值 |
|---|---|---|
|
Shell 命令缓冲区大小 (字节) |
512 |
|
UART 接收缓冲区大小 (字节) |
32 |
|
格式化输入缓冲区大小 (字节) |
128 |
行为配置
配置项 |
说明 |
默认值 |
|---|---|---|
|
支持尾行模式 |
y |
|
使用 LF ( |
y |
|
使用 CR ( |
y |
|
使用 CRLF ( |
n |
注意:
SHELL_ENTER_CRLF不能与SHELL_ENTER_LF或SHELL_ENTER_CR同时启用。
快速开始
1. 启用组件
在项目的 prj.conf 文件中添加:
CONFIG_LISA_SHELL=y
2. 配置 UART 设备
LISA Shell 使用系统日志 UART 设备,需要配置对应的 UART:
# 选择 UART0 作为 Shell 串口
CONFIG_SYSLOG_UART_DEVICE_UART0=y
3. 初始化 Shell
在应用程序的 main 函数中调用初始化函数:
#include "lisa_shell.h"
int main(int argc, char **argv)
{
// 初始化 shell
lisa_shell_init();
// 你的应用代码
while (1) {
vTaskDelay(1000);
}
return 0;
}
4. 注册自定义命令
使用 SHELL_EXPORT_CMD 宏注册命令:
#include "shell.h"
// 简单命令示例
static int cmd_hello(int argc, char **argv)
{
printf("Hello World\n");
return 0;
}
// 带参数的命令示例
static int cmd_echo(int argc, char **argv)
{
if (argc < 1) {
printf("Usage: echo <message>\n");
return -1;
}
for (int i = 0; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
return 0;
}
// 注册命令
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
hello,
cmd_hello,
"Print hello world"
);
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
echo,
cmd_echo,
"Echo arguments"
);
5. 命令组示例
创建命令组来组织相关的命令:
// 命令表
struct cmd_entry {
char *name;
int (*exec)(int argc, char **argv);
char *help;
};
static int subcmd_test(int argc, char **argv)
{
printf("Running test...\n");
return 0;
}
static int subcmd_info(int argc, char **argv)
{
printf("System information\n");
return 0;
}
static const struct cmd_entry my_cmds[] = {
{"test", subcmd_test, "Run test"},
{"info", subcmd_info, "Show info"},
};
// 命令组处理函数
static int cmd_group_handler(int argc, char **argv)
{
if (argc == 1) {
// 显示帮助
printf("Available subcommands:\n");
for (int i = 0; i < sizeof(my_cmds) / sizeof(my_cmds[0]); i++) {
printf(" %-10s : %s\n", my_cmds[i].name, my_cmds[i].help);
}
return 0;
}
// 查找并执行子命令
for (int i = 0; i < sizeof(my_cmds) / sizeof(my_cmds[0]); i++) {
if (strcmp(my_cmds[i].name, argv[1]) == 0) {
return my_cmds[i].exec(argc - 2, argv + 2);
}
}
printf("Unknown subcommand: %s\n", argv[1]);
return -1;
}
// 注册命令组
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_DISABLE_RETURN,
myapp,
cmd_group_handler,
"My application command group"
);
API 参考
lisa_shell_init
int lisa_shell_init(void);
功能:初始化 LISA Shell 组件
返回值:
0:初始化成功-1:初始化失败(UART 设备未就绪、配置失败或内存分配失败)
说明:
自动配置 UART 设备(波特率、缓冲区等)
创建 shell 任务进行命令接收和处理
将系统日志输出重定向到 shell 串口
注意事项
UART 设备共享:Shell 使用系统日志的 UART 设备,确保日志和 Shell 配置一致
任务优先级:根据系统需求调整 Shell 任务优先级,避免影响实时性要求高的任务
缓冲区大小:根据命令复杂度和长度调整
SHELL_BUFFER_SIZE内存分配:Shell 使用动态内存分配,确保系统有足够的堆内存
命令注册:
SHELL_EXPORT_CMD宏必须在全局作用域使用,不能在函数内部格式化输入:
SHELL_SCAN_BUFFER功能会阻塞 shell 任务,仅适用于 RTOS 环境
常见问题
Q: Shell 初始化失败怎么办?
A: 检查以下几点:
UART 设备是否正确配置并初始化
系统是否有足够的堆内存
CONFIG_SYSLOG_UART_DEVICE_UARTx配置是否正确
Q: 无法输入命令?
A: 检查:
串口终端配置(波特率、数据位等)是否正确
UART 引脚连接是否正常
回车触发模式(LF/CR/CRLF)配置是否与终端匹配
Q: 命令注册后在 help 中看不到?
A: 确保:
命令正确使用了
SHELL_EXPORT_CMD宏宏调用在全局作用域(不在函数内部)
对应的源文件已链接到最终二进制文件
依赖项
SDK_MODULE_LETTER_SHELL:Letter Shell 核心库LISA_PORTING:LISA 平台移植层lisa_uart:UART 驱动lisa_log:日志系统lisa_mem:内存管理FreeRTOS:实时操作系统