mirror of
https://github.com/NevermindZZT/letter-shell.git
synced 2025-01-21 10:02:54 +08:00
shell 3.0
This commit is contained in:
parent
f3a81ebb90
commit
912bbf5851
493
README.md
493
README.md
@ -1,47 +1,51 @@
|
||||
# letter shell
|
||||
# letter shell 3.0
|
||||
|
||||
![version](https://img.shields.io/badge/version-2.0.8-brightgreen.svg)
|
||||
![build](https://img.shields.io/badge/build-2020.01.14-brightgreen.svg)
|
||||
![version](https://img.shields.io/badge/version-3.0.0_beta1-brightgreen.svg)
|
||||
![build](https://img.shields.io/badge/build-2020.01.17-brightgreen.svg)
|
||||
![build](https://img.shields.io/badge/license-MIT-brightgreen.svg)
|
||||
|
||||
一个体积极小的嵌入式shell
|
||||
一个功能强大的嵌入式shell
|
||||
|
||||
- [letter shell](#letter-shell)
|
||||
- [功能](#%e5%8a%9f%e8%83%bd)
|
||||
- [移植说明](#%e7%a7%bb%e6%a4%8d%e8%af%b4%e6%98%8e)
|
||||
- [使用方式](#%e4%bd%bf%e7%94%a8%e6%96%b9%e5%bc%8f)
|
||||
- [函数定义](#%e5%87%bd%e6%95%b0%e5%ae%9a%e4%b9%89)
|
||||
- [main函数形式](#main%e5%87%bd%e6%95%b0%e5%bd%a2%e5%bc%8f)
|
||||
- [普通C函数形式](#%e6%99%ae%e9%80%9ac%e5%87%bd%e6%95%b0%e5%bd%a2%e5%bc%8f)
|
||||
- [在函数中获取当前shell对象](#%e5%9c%a8%e5%87%bd%e6%95%b0%e4%b8%ad%e8%8e%b7%e5%8f%96%e5%bd%93%e5%89%8dshell%e5%af%b9%e8%b1%a1)
|
||||
- [命令定义](#%e5%91%bd%e4%bb%a4%e5%ae%9a%e4%b9%89)
|
||||
- [命令导出方式](#%e5%91%bd%e4%bb%a4%e5%af%bc%e5%87%ba%e6%96%b9%e5%bc%8f)
|
||||
- [命令表方式](#%e5%91%bd%e4%bb%a4%e8%a1%a8%e6%96%b9%e5%bc%8f)
|
||||
- [组合按键](#%e7%bb%84%e5%90%88%e6%8c%89%e9%94%ae)
|
||||
- [shell变量](#shell%e5%8f%98%e9%87%8f)
|
||||
- [导出变量](#%e5%af%bc%e5%87%ba%e5%8f%98%e9%87%8f)
|
||||
- [读取变量](#%e8%af%bb%e5%8f%96%e5%8f%98%e9%87%8f)
|
||||
- [修改变量](#%e4%bf%ae%e6%94%b9%e5%8f%98%e9%87%8f)
|
||||
- [变量作为命令参数](#%e5%8f%98%e9%87%8f%e4%bd%9c%e4%b8%ba%e5%91%bd%e4%bb%a4%e5%8f%82%e6%95%b0)
|
||||
- [shell密码](#shell%e5%af%86%e7%a0%81)
|
||||
- [建议终端软件](#%e5%bb%ba%e8%ae%ae%e7%bb%88%e7%ab%af%e8%bd%af%e4%bb%b6)
|
||||
- [更新日志](#%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97)
|
||||
![shell_info.png](doc/img/shell_info.png)
|
||||
|
||||
- [letter shell 3.0](#letter-shell-30)
|
||||
- [简介](#简介)
|
||||
- [功能](#功能)
|
||||
- [移植说明](#移植说明)
|
||||
- [使用方式](#使用方式)
|
||||
- [函数定义](#函数定义)
|
||||
- [main函数形式](#main函数形式)
|
||||
- [普通C函数形式](#普通c函数形式)
|
||||
- [在函数中获取当前shell对象](#在函数中获取当前shell对象)
|
||||
- [命令定义](#命令定义)
|
||||
- [定义方式](#定义方式)
|
||||
- [定义宏说明](#定义宏说明)
|
||||
- [命令属性字段说明](#命令属性字段说明)
|
||||
- [权限系统说明](#权限系统说明)
|
||||
- [建议终端软件](#建议终端软件)
|
||||
|
||||
## 简介
|
||||
|
||||
[letter shell 3.0](https://github.com/NevermindZZT/letter-shell/tree/shell3.0)是一个C语言编写的,可以嵌入在程序中的嵌入式shell,主要面向嵌入式设备,以C语言函数为运行单位,可以通过命令行调用,运行程序中的函数
|
||||
|
||||
相对2.x版本,letter shell 3.0增加了用户管理,权限管理,后续会增加对文件系统的支持
|
||||
|
||||
此外3.0版本修改了命令格式和定义,2.x版本的工程需要经过简单的修改才能完成迁移
|
||||
|
||||
## 功能
|
||||
|
||||
- 命令自动补全,使用tab键补全命令
|
||||
- 命令长帮助,使用help [command]显示命令长帮助
|
||||
- 长帮助补全,输入命令后双击tab键补全命令长帮助指令
|
||||
- 快捷键,支持使用Ctrl + A~Z组合按键直接调用函数
|
||||
- shell变量,支持在shell中查看和修改变量值,支持变量作为命令参数
|
||||
- 登录密码,支持在shell中使用登录密码,支持超时自动锁定
|
||||
- 命令自动补全
|
||||
- 快捷键功能定义
|
||||
- 命令权限管理
|
||||
- 用户管理
|
||||
- 变量支持
|
||||
|
||||
## 移植说明
|
||||
|
||||
1. 定义shell对象
|
||||
|
||||
```C
|
||||
SHELL_TypeDef shell;
|
||||
Shell shell;
|
||||
```
|
||||
|
||||
2. 定义shell读,写函数,函数原型如下
|
||||
@ -65,15 +69,21 @@
|
||||
typedef void (*shellWrite)(const char);
|
||||
```
|
||||
|
||||
3. 调用shellInit进行初始化
|
||||
3. 申请一片缓冲区
|
||||
|
||||
```C
|
||||
char shellBuffer[512];
|
||||
```
|
||||
|
||||
4. 调用shellInit进行初始化
|
||||
|
||||
```C
|
||||
shell.read = shellRead;
|
||||
shell.write = shellWrite;
|
||||
shellInit(&shell);
|
||||
shellInit(&shell, shellBuffer, 512);
|
||||
```
|
||||
|
||||
4. 调用(建立)shell任务
|
||||
5. 调用(建立)shell任务
|
||||
|
||||
对于运行在操作系统的情况,建立`shellTask`任务(确保sell_cfg.h中的配置无误),任务参数为shell对象
|
||||
|
||||
@ -81,54 +91,53 @@
|
||||
OsTaskCreate(shellTask, &shell, ...);
|
||||
```
|
||||
|
||||
对于裸机环境,在主循环中调用`shellTask`,或者在接收到数据时,调用`shellInput`
|
||||
对于裸机环境,在主循环中调用`shellTask`,或者在接收到数据时,调用`shellHandler`
|
||||
|
||||
5. 说明
|
||||
6. 说明
|
||||
|
||||
- 对于中断方式使用shell,不用定义`shell->read`,但需要在中断中调用`shellInput`
|
||||
- 对于在无操作系统环境下,可以使用查询的方式,使能```SHELL_UISNG_TASK```,然后在循环中不断调用shellTask
|
||||
- 对于使用操作系统的情况,使能```SHELL_USING_TASK```和```SHEHLL_TASK_WHILE```宏,然后创建shellTask任务
|
||||
- 打印函数返回值,使能```SHELL_DISPLAY_RETURN```宏,返回值均作为整型数据打印
|
||||
- 对于中断方式使用shell,不用定义`shell->read`,但需要在中断中调用`shellHandler`
|
||||
- 对于使用操作系统的情况,使能```SHEHLL_TASK_WHILE```宏,然后创建shellTask任务
|
||||
|
||||
6. 其他配置
|
||||
7. 其他配置
|
||||
|
||||
- 定义宏```SHELL_GET_TICK()```为获取系统tick函数,使能tab双击操作,用户长帮助补全
|
||||
- 定义宏`SHELL_GET_TICK()`为获取系统tick函数,使能tab双击操作,用户长帮助补全
|
||||
|
||||
7. 配置宏
|
||||
8. 配置宏
|
||||
|
||||
shell_cfg.h文件中包含了所有用于配置shell的宏,在使用前,需要根据需要进行配置
|
||||
|
||||
| 宏 | 意义 |
|
||||
| -------------------------- | ------------------------------ |
|
||||
| SHELL_USING_TASK | 是否使用默认shell任务 |
|
||||
| SHELL_USING_CMD_EXPORT | 是否使用命令导出方式 |
|
||||
| SHELL_DISPLAY_RETURN | 是否显示命令调用函数返回值 |
|
||||
| SHELL_TASK_WHILE | 是否使用默认shell任务while循环 |
|
||||
| SHELL_AUTO_PRASE | 是否使用shell参数自动解析 |
|
||||
| SHELL_LONG_HELP | 是否使用shell长帮助 |
|
||||
| SHELL_COMMAND_MAX_LENGTH | shell命令最大长度 |
|
||||
| SHELL_PARAMETER_MAX_NUMBER | shell命令参数最大数量 |
|
||||
| SHELL_HISTORY_MAX_NUMBER | 历史命令记录数量 |
|
||||
| SHELL_DOUBLE_CLICK_TIME | 双击间隔(ms) |
|
||||
| SHELL_GET_TICK() | 获取系统时间(ms) |
|
||||
| SHELL_DEFAULT_COMMAND | shell默认提示符 |
|
||||
| SHELL_MAX_NUMBER | 管理的最大shell数量 |
|
||||
| SHELL_USING_AUTH | 是否使用密码功能 |
|
||||
| SHELL_USER_PASSWORD | 用户密码 |
|
||||
| SHELL_LOCK_TIMEOUT | shell自动锁定超时 |
|
||||
| 宏 | 意义 |
|
||||
| --------------------------- | ------------------------------ |
|
||||
| SHELL_TASK_WHILE | 是否使用默认shell任务while循环 |
|
||||
| SHELL_USING_CMD_EXPORT | 是否使用命令导出方式 |
|
||||
| SHELL_HELP_LIST_USER | 是否在输入命令列表中列出用户 |
|
||||
| SHELL_HELP_LIST_VAR | 是否在输入命令列表中列出变量 |
|
||||
| SHELL_HELP_LIST_KEY | 是否在输入命令列表中列出按键 |
|
||||
| SHELL_ENTER_LF | 使用LF作为命令行回车触发 |
|
||||
| SHELL_ENTER_CR | 使用CR作为命令行回车触发 |
|
||||
| SHELL_ENTER_CRLF | 使用CRLF作为命令行回车触发 |
|
||||
| SHELL_COMMAND_MAX_LENGTH | shell命令最大长度 |
|
||||
| SHELL_PARAMETER_MAX_NUMBER | shell命令参数最大数量 |
|
||||
| SHELL_HISTORY_MAX_NUMBER | 历史命令记录数量 |
|
||||
| SHELL_DOUBLE_CLICK_TIME | 双击间隔(ms) |
|
||||
| SHELL_MAX_NUMBER | 管理的最大shell数量 |
|
||||
| SHELL_GET_TICK() | 获取系统时间(ms) |
|
||||
| SHELL_DEFAULT_USER | shell默认用户 |
|
||||
| SHELL_DEFAULT_USER_PASSWORD | 默认用户密码 |
|
||||
| SHELL_LOCK_TIMEOUT | shell自动锁定超时 |
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 函数定义
|
||||
|
||||
letter shell 支持两种形式的函数定义方式,形如main函数定义的```func(int argc, char *agrv[])```以及形如普通C函数的定义```func(int i, char *str, ...)```,这两种方式目前不可共存,只能选择其中的一种,通过宏```SHELL_AUTO_PRASE```选择
|
||||
letter shell 3.0同时支持两种形式的函数定义方式,形如main函数定义的`func(int argc, char *agrv[])`以及形如普通C函数的定义`func(int i, char *str, ...)`,两种函数定义方式适用于不同的场景
|
||||
|
||||
#### main函数形式
|
||||
|
||||
使用此方式,一个函数定义的例子如下:
|
||||
|
||||
```C
|
||||
func(int argc, char *agrv[])
|
||||
int func(int argc, char *agrv[])
|
||||
{
|
||||
printf("%dparameter(s)\r\n", argc);
|
||||
for (char i = 1; i < argc; i++)
|
||||
@ -136,13 +145,13 @@ func(int argc, char *agrv[])
|
||||
printf("%s\r\n", argv[i]);
|
||||
}
|
||||
}
|
||||
SHELL_EXPORT_CMD(func, func, test)
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), func, func, test);
|
||||
```
|
||||
|
||||
终端调用
|
||||
|
||||
```sh
|
||||
letter>>func "hello world"
|
||||
letter:/$ func "hello world"
|
||||
2 parameter(s)
|
||||
hello world
|
||||
```
|
||||
@ -152,239 +161,195 @@ hello world
|
||||
使用此方式,shell会自动对参数进行转化处理,目前支持二进制,八进制,十进制,十六进制整形,字符,字符串的自动处理,如果需要其他类型的参数,请使用字符串的方式作为参数,自行进行处理,例子如下:
|
||||
|
||||
```C
|
||||
func(int i, char ch, char *str)
|
||||
int func(int i, char ch, char *str)
|
||||
{
|
||||
printf("input int: %d, char: %c, string: %s\r\n", i, ch, str);
|
||||
}
|
||||
SHELL_EXPORT_CMD(func, func, test)
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), func, func, test);
|
||||
```
|
||||
|
||||
终端调用
|
||||
|
||||
```sh
|
||||
letter>>func 666 'A' "hello world"
|
||||
letter:/$ func 666 'A' "hello world"
|
||||
input int: 666, char: A, string: hello world
|
||||
```
|
||||
|
||||
#### 在函数中获取当前shell对象
|
||||
|
||||
shell采取一个静态数组对定义的多个shell进行管理,shell数量可以修改宏```SHELL_MAX_NUMBER```定义(为了不使用动态内存分配,此处通过数据进行管理),从而,在shell执行的函数中,可以调用```shellGetCurrent()```获得当前活动的shell对象,从而可以实现某一个函数在不同的shell对象中发生不同的行为,也可以通过这种方式获得shell对象后,调用```shellDisplay(shell, string)```进行shell的输出
|
||||
shell采取一个静态数组对定义的多个shell进行管理,shell数量可以修改宏`SHELL_MAX_NUMBER`定义(为了不使用动态内存分配,此处通过数据进行管理),从而,在shell执行的函数中,可以调用`shellGetCurrent()`获得当前活动的shell对象,从而可以实现某一个函数在不同的shell对象中发生不同的行为,也可以通过这种方式获得shell对象后,调用`shellWriteString(shell, string)`进行shell的输出
|
||||
|
||||
### 命令定义
|
||||
## 命令定义
|
||||
|
||||
letter shell 3.0将可执行的函数命令定义,用户定义,按键定义以及变量定义统一归为命令定义,使用相同的结构储存,查找和执行
|
||||
|
||||
### 定义方式
|
||||
|
||||
letter shell 支持使用命令导出方式和命令表方式进行命令的添加,定义,通过宏```SHELL_USING_CMD_EXPORT```控制
|
||||
|
||||
命令导出方式支持keil,IAR(未测试)以及GCC
|
||||
|
||||
### 命令导出方式
|
||||
1. 命令导出方式
|
||||
|
||||
letter shell 支持在函数体外部,采用定义常量的方式定义命令,例如```SHELL_EXPORT_CMD_EX(help, shellHelp, command help, help [command] --show help info of command);```,或者```SHELL_EXPORT_CMD(help, shellHelp, command help);```
|
||||
letter shell 支持在函数体外部,采用定义常量的方式定义命令,例如`SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE (SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN,help, shellHelp, show command info\r\nhelp [cmd]);`
|
||||
|
||||
对于使用keil进行编译,需要在keil的target option中增加--keep shellCommand*,防止定义的命令被优化掉
|
||||
对于使用keil进行编译,需要在keil的target option中增加--keep shellCommand*,防止定义的命令被优化掉
|
||||
|
||||
使用GCC编译时,需要在ld文件中的只读数据区(建议)添加:
|
||||
使用GCC编译时,需要在ld文件中的只读数据区(建议)添加:
|
||||
|
||||
```ld
|
||||
_shell_command_start = .;
|
||||
KEEP (*(shellCommand))
|
||||
_shell_command_end = .;
|
||||
```
|
||||
|
||||
### 命令表方式
|
||||
|
||||
- 当使用其他编译器时,暂时不支持使用类似keil中命令导出的方式,需要在命令表中添加
|
||||
|
||||
```C
|
||||
const SHELL_CommandTypeDef shellDefaultCommandList[] =
|
||||
{
|
||||
SHELL_CMD_ITEM_EX(help, shellHelp, command help, help [command] --show help info of command),
|
||||
};
|
||||
```ld
|
||||
_shell_command_start = .;
|
||||
KEEP (*(shellCommand))
|
||||
_shell_command_end = .;
|
||||
```
|
||||
|
||||
- 其中,带有EX的命令导出宏最后一个参数为命令的长帮助信息,在shell中使用help [command]可查看帮助信息,通过shell.h中的SHELL_LONG_HELP宏可设置是否使用此功能
|
||||
2. 命令表方式
|
||||
|
||||
### 组合按键
|
||||
- 当使用其他暂时不支持使用命令导出方式的编译器时,需要在`shell_cmd_list.c`文件的命令表中添加
|
||||
|
||||
letter shell支持使用Ctrl键加任意字母键的组合按键一键执行操作,使用时,在任意文件定义按键命令表
|
||||
```C
|
||||
const SHELL_CommandTypeDef shellDefaultCommandList[] =
|
||||
{
|
||||
SHELL_CMD_ITEM(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN,
|
||||
help, shellHelp, show command info\r\nhelp [cmd]),
|
||||
};
|
||||
```
|
||||
|
||||
### 定义宏说明
|
||||
|
||||
letter shell 3.0对可执行命令,按键,用户以及变量分别提供了一个宏,用于进行命令定义
|
||||
|
||||
1. 可执行命令定义
|
||||
|
||||
使用宏`SHELL_EXPORT_CMD`定义可执行命令,定义如下
|
||||
|
||||
```C
|
||||
/**
|
||||
* @brief shell 命令定义
|
||||
*
|
||||
* @param _attr 命令属性
|
||||
* @param _name 命令名
|
||||
* @param _func 命令函数
|
||||
* @param _desc 命令描述
|
||||
*/
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellCommand##_name SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.cmd.name = shellCmd##_name, \
|
||||
.data.cmd.function = (int (*)())_func, \
|
||||
.data.cmd.desc = shellDesc##_name \
|
||||
}
|
||||
```
|
||||
|
||||
2. 变量定义
|
||||
|
||||
使用宏`SHELL_EXPORT_VAR`定义变量,定义如下
|
||||
|
||||
```C
|
||||
/**
|
||||
* @brief shell 变量定义
|
||||
*
|
||||
* @param _attr 变量属性
|
||||
* @param _name 变量名
|
||||
* @param _value 变量值
|
||||
* @param _desc 变量描述
|
||||
*/
|
||||
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellVar##_name SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.var.name = shellCmd##_name, \
|
||||
.data.var.value = (void *)_value, \
|
||||
.data.var.desc = shellDesc##_name \
|
||||
}
|
||||
```
|
||||
|
||||
3. 用户定义
|
||||
|
||||
使用宏`SHELL_EXPORT_USER`定义用户,定义如下
|
||||
|
||||
```C
|
||||
/**
|
||||
* @brief shell 用户定义
|
||||
*
|
||||
* @param _attr 用户属性
|
||||
* @param _name 用户名
|
||||
* @param _password 用户密码
|
||||
* @param _desc 用户描述
|
||||
*/
|
||||
#define SHELL_EXPORT_USER(_attr, _name, _password, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellPassword##_name[] = #_password; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellUser##_name SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \
|
||||
.data.user.name = shellCmd##_name, \
|
||||
.data.user.password = shellPassword##_name, \
|
||||
.data.user.desc = shellDesc##_name \
|
||||
}
|
||||
```
|
||||
|
||||
4. 按键定义
|
||||
|
||||
使用宏`SHELL_EXPORT_KEY`定义按键,定义如下
|
||||
|
||||
```C
|
||||
/**
|
||||
* @brief shell 按键定义
|
||||
*
|
||||
* @param _attr 按键属性
|
||||
* @param _value 按键键值
|
||||
* @param _func 按键函数
|
||||
* @param _desc 按键描述
|
||||
*/
|
||||
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \
|
||||
const char shellDesc##_value[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellKey##_value SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
|
||||
.data.key.value = _value, \
|
||||
.data.key.function = (void (*)(Shell *))_func, \
|
||||
.data.key.desc = shellDesc##_value \
|
||||
}
|
||||
```
|
||||
|
||||
按键键值为在终端输入按键会发送的字符串序列,以大端模式表示,比如在SecureCRT中断,按下Tab键,会发送0x0B,则这个按键的键值为0x0B000000,如果按下方向上,会依次发送0x1B, 0x5B, 0x41, 则这个键的键值为0x1B5B4100
|
||||
|
||||
### 命令属性字段说明
|
||||
|
||||
在命令定义中,有一个`attr`字段,表示该命令的属性,具体定义为
|
||||
|
||||
```C
|
||||
SHELL_KeyFunctionDef keyFuncList[] =
|
||||
union
|
||||
{
|
||||
{SHELL_KEY_CTRL_T, switchUlog}
|
||||
};
|
||||
struct
|
||||
{
|
||||
unsigned char permission : 8; /**< command权限 */
|
||||
ShellCommandType type : 4; /**< command类型 */
|
||||
unsigned char enableUnchecked : 1; /**< 在未校验密码的情况下可用 */
|
||||
unsigned char disableReturn : 1; /**< 禁用返回值输出 */
|
||||
} attrs;
|
||||
int value;
|
||||
} attr;
|
||||
```
|
||||
|
||||
然后使用`shellSetKeyFuncList`进行注册
|
||||
在定义命令时,需要给定这些值,可以通过宏`SHELL_CMD_PERMISSION(permission)`, `SHELL_CMD_TYPE(type)`, `SHELL_CMD_ENABLE_UNCHECKED`, `SHELL_CMD_DISABLE_RETURN`快速声明
|
||||
|
||||
```C
|
||||
shellSetKeyFuncList(&shell, keyFuncList, sizeof(keyFuncList) / sizeof(SHELL_KeyFunctionDef));
|
||||
```
|
||||
### 权限系统说明
|
||||
|
||||
### shell变量
|
||||
|
||||
letter shell支持shell变量,通过导出变量,将变量进行注册,可以在shell中读取,修改变量的值,可以将变量作为参数传递给shell命令
|
||||
|
||||
使用时,在shell_cfg.h文件中将`SHELL_USING_VAR`修改为1
|
||||
|
||||
执行`vars`命令查看所有变量
|
||||
|
||||
#### 导出变量
|
||||
|
||||
使用变量导出方式时,通过宏`SHELL_EXPORT_VAR_INT`,`SHELL_EXPORT_VAR_SHORT`,`SHELL_EXPORT_VAR_CHAR`,`SHELL_EXPORT_VAR_POINTER`导出变量,例如:
|
||||
|
||||
```C
|
||||
SHELL_EXPORT_VAR_INT(testVar1, testVar1, var for test);
|
||||
```
|
||||
|
||||
使用变量表方式时,定义一个命令表,并调用`shellSetVariableList`进行注册,参考命令导出
|
||||
|
||||
#### 读取变量
|
||||
|
||||
shell变量使用`$[var]`的方式读取,直接在命令行输入即可,例如:
|
||||
|
||||
```sh
|
||||
letter>>$testVar1
|
||||
testVar1 = 100, 0x00000064
|
||||
```
|
||||
|
||||
#### 修改变量
|
||||
|
||||
使用`setVar`命令修改变量,例如:
|
||||
|
||||
```sh
|
||||
letter>>setVar testVar1 200
|
||||
testVar1 = 200, 0x000000c8
|
||||
```
|
||||
|
||||
#### 变量作为命令参数
|
||||
|
||||
直接使用`$[var]`即可将变量的值作为参数传递给shell命令,例如:
|
||||
|
||||
```sh
|
||||
letter>>getVar $testVar1
|
||||
```
|
||||
|
||||
### shell密码
|
||||
|
||||
letter shell支持shell密码,支持在一定时间shell无操作时自动锁定
|
||||
|
||||
使能宏`SHELL_USING_AUTH`开启shell密码功能,同时修改宏`SHELL_USER_PASSWORD`定义shell密码
|
||||
|
||||
在使用密码,并且宏`SHELL_GET_TICK()`有有效定义后,可以使用shell超时自动锁定,通过宏`SHELL_LOCK_TIMEOUT`设置超时时长,当此宏设为0时,禁用超时自动锁定功能
|
||||
letter shell 3.0的权限管理同用户定义紧密相关,letter shell 3.0使用8个bit位表示命令权限,当用户和命令的权限按位与为真,或者命令权限为0时,表示该用户拥有此命令的权限,可以调用改命令
|
||||
|
||||
### 建议终端软件
|
||||
|
||||
- 对于基于串口移植,letter shell建议使用secureCRT软件,letter shell中的相关按键映射都是按照secureCRT进行设计的,使用其他串口软件可能会出现某些功能无法使用的情况
|
||||
|
||||
## 更新日志
|
||||
|
||||
- 2018/4/20 v1.0
|
||||
|
||||
- 第一版
|
||||
|
||||
- 2018/4/23 v1.1
|
||||
|
||||
- 加入对带参命令的支持
|
||||
|
||||
- 2018/4/25 v1.2
|
||||
|
||||
- 合并带参函数和不带参函数命令表
|
||||
|
||||
- 2018/7/10 v1.3
|
||||
|
||||
- 修复带参命令最后输入空格时传入参数数量出错的问题
|
||||
- 修复不带参数调用带参命令时程序跑死的问题,指令处理相关代码优化
|
||||
- 加入对于输入超出命令长度的情况的处理措施
|
||||
|
||||
- 2018/7/11 v1.4
|
||||
|
||||
- 新增对于方向键的处理,暂时未对方向键添加具体功能
|
||||
- 修复单独的空格,制表符等无效操作被识别为指令进行解析,造成程序死机的问题
|
||||
- 取消制表符作为参数分隔符的用途
|
||||
|
||||
- 2018/7/12 v1.5
|
||||
|
||||
- 新增历史命令的功能,使用上下方向键操作
|
||||
- 新增tab键输入最近一条命令
|
||||
- 无历史记录时,tab键输入help命令
|
||||
- 新增一条用于清屏的默认指令
|
||||
|
||||
- 2018/7/18 v1.6
|
||||
|
||||
- 修改tab键功能,加入自动补全
|
||||
- 无输入情况下,按下tab输入help命令
|
||||
- 有输入情况下,进行自动补全
|
||||
|
||||
- 2018/7/24 v1.7
|
||||
|
||||
- 增加SHELL_TypeDef结构体
|
||||
- 采用新的命令添加方式,现在可以在任意文件的函数 外部采用宏SHELL_EXPORT_CMD进行命令定义
|
||||
|
||||
- 2018/7/26 v1.7.1
|
||||
|
||||
- 修复不使用带参函数(SHELL_USE_PARAMETER = 0)的情况下,无法匹配命令的问题
|
||||
- 修复不使用历史命令(SHELL_USE_HISTORY = 0)的情况下,无法使用命令补全的问题
|
||||
|
||||
- 2018/8/9 v1.8
|
||||
|
||||
- 新增左右键移动光标功能,方便对输错的命令进行修改使用宏SHELL_ALLOW_SHIFT开启
|
||||
- 优化结构体成员命名
|
||||
- 对开启移动光标功能后,输入参数过长的情况采用新的处理方式
|
||||
|
||||
- 2018/11/19 v1.8.3
|
||||
|
||||
- 修复不使用光标移动功能的时候,输入命令过长时无法正常删除的问题
|
||||
- 针对不使用MDK编译,重新加入命令表定义的方式
|
||||
- 新增对双引号的识别处理,支持带空格的参数
|
||||
|
||||
- 2019/01/07 2.0.0
|
||||
|
||||
- 重构代码,优化逻辑结构,减少内存开销
|
||||
- 新增shell扩展模块,支持函数参数自动转化
|
||||
- 精简shell可选项
|
||||
- 新增多shell支持
|
||||
|
||||
- 2019/02/20 2.0.1
|
||||
|
||||
- 新增命令导出方式对于IAR,GCC的支持
|
||||
- 新增命令长帮助
|
||||
- 新增二进制参数支持
|
||||
- 修复bug以及一些优化
|
||||
|
||||
- 2019/03/29 2.0.2
|
||||
|
||||
- 新增函数返回值打印
|
||||
- 新增shell对象管理,支持在shell调用的函数中获取当前shell对象
|
||||
- bug修复
|
||||
|
||||
- 2019/08/16 2.0.3
|
||||
|
||||
- 新增一个shell格式化输出函数
|
||||
|
||||
- 2019/08/20 2.0.4
|
||||
|
||||
- 新增组合按键功能自定义
|
||||
- 新增shell变量
|
||||
|
||||
- 2019/08/21 2.0.5
|
||||
|
||||
- 新增shell常量
|
||||
- 修复bug以及一些优化
|
||||
|
||||
- 2019/11/16 2.0.6
|
||||
|
||||
- 修复历史命令概率性异常的问题
|
||||
- 新增shell密码
|
||||
- 一些细节优化
|
||||
|
||||
- 2019/11/30 2.0.7
|
||||
|
||||
- 新增shell超时自动锁定
|
||||
- 修复未验证密码的情况下,仍能查看历史命令,使用tab查看命令表的问题
|
||||
- 修复双击tab补全,可能在使用多shell的时候有冲突的问题
|
||||
- 细节优化
|
||||
|
||||
- 2020/01/14 2.0.8
|
||||
|
||||
- 修复命令名过长时,显示命令列表异常的问题
|
||||
- 修复命令被限制在256个的问题
|
||||
- 对于基于串口移植,letter shell建议使用secureCRT软件,letter shell中的相关按键映射都是按照secureCRT进行设计的,使用其他串口软件时,可能需要修改键值
|
||||
|
119
demo/stm32-freertos/shell_cfg.h
Normal file
119
demo/stm32-freertos/shell_cfg.h
Normal file
@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @file shell_cfg.h
|
||||
* @author Letter (nevermindzzt@gmail.com)
|
||||
* @brief shell config
|
||||
* @version 3.0.0
|
||||
* @date 2019-12-31
|
||||
*
|
||||
* @copyright (c) 2019 Letter
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHELL_CFG_H__
|
||||
#define __SHELL_CFG_H__
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义
|
||||
* 使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell
|
||||
* 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()`
|
||||
*/
|
||||
#define SHELL_TASK_WHILE 1
|
||||
|
||||
/**
|
||||
* @brief 是否使用命令导出方式
|
||||
* 使能此宏后,可以使用`SHELL_EXPORT_CMD()`等导出命令
|
||||
* 定义shell命令,关闭此宏的情况下,需要使用命令表的方式
|
||||
*/
|
||||
#define SHELL_USING_CMD_EXPORT 1
|
||||
|
||||
/**
|
||||
* @brief 是否在输入命令列表中列出用户
|
||||
*/
|
||||
#define SHELL_HELP_LIST_USER 0
|
||||
|
||||
/**
|
||||
* @brief 是否在输入命令列表中列出变量
|
||||
*/
|
||||
#define SHELL_HELP_LIST_VAR 0
|
||||
|
||||
/**
|
||||
* @brief 是否在输入命令列表中列出按键
|
||||
*/
|
||||
#define SHELL_HELP_LIST_KEY 0
|
||||
|
||||
/**
|
||||
* @brief 使用LF作为命令行回车触发
|
||||
* 可以和SHELL_ENTER_CR同时开启
|
||||
*/
|
||||
#define SHELL_ENTER_LF 0
|
||||
|
||||
/**
|
||||
* @brief 使用CR作为命令行回车触发
|
||||
* 可以和SHELL_ENTER_LF同时开启
|
||||
*/
|
||||
#define SHELL_ENTER_CR 0
|
||||
|
||||
/**
|
||||
* @brief 使用CRLF作为命令行回车触发
|
||||
* 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启
|
||||
*/
|
||||
#define SHELL_ENTER_CRLF 1
|
||||
|
||||
/**
|
||||
* @brief shell命令参数最大数量
|
||||
* 包含命令名在内,超过8个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
*/
|
||||
#define SHELL_PARAMETER_MAX_NUMBER 8
|
||||
|
||||
/**
|
||||
* @brief 历史命令记录数量
|
||||
*/
|
||||
#define SHELL_HISTORY_MAX_NUMBER 5
|
||||
|
||||
/**
|
||||
* @brief 双击间隔(ms)
|
||||
* 使能宏`SHELL_LONG_HELP`后此宏生效,定义双击tab补全help的时间间隔
|
||||
*/
|
||||
#define SHELL_DOUBLE_CLICK_TIME 200
|
||||
|
||||
/**
|
||||
* @brief 管理的最大shell数量
|
||||
*/
|
||||
#define SHELL_MAX_NUMBER 5
|
||||
|
||||
/**
|
||||
* @brief shell格式化输出的缓冲大小
|
||||
* 为0时不使用shell格式化输出
|
||||
*/
|
||||
#define SHELL_PRINT_BUFFER 128
|
||||
|
||||
/**
|
||||
* @brief 获取系统时间(ms)
|
||||
* 定义此宏为获取系统Tick,如`HAL_GetTick()`
|
||||
* @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定
|
||||
*/
|
||||
#define SHELL_GET_TICK() HAL_GetTick()
|
||||
|
||||
/**
|
||||
* @brief shell默认用户
|
||||
*/
|
||||
#define SHELL_DEFAULT_USER "letter"
|
||||
|
||||
/**
|
||||
* @brief shell默认用户密码
|
||||
* 若默认用户不需要密码,设为""
|
||||
*/
|
||||
#define SHELL_DEFAULT_USER_PASSWORD ""
|
||||
|
||||
/**
|
||||
* @brief shell自动锁定超时
|
||||
* 使能`SHELL_USING_AUTH`的情况下生效,超时后会自动重新锁定shell
|
||||
* 设置为0时关闭自动锁定功能,时间单位为`SHELL_GET_TICK()`单位
|
||||
* @note 使用超时锁定必须保证`SHELL_GET_TICK()`有效
|
||||
*/
|
||||
#define SHELL_LOCK_TIMEOUT 0 * 60 * 1000
|
||||
|
||||
#endif
|
62
demo/stm32-freertos/shell_port.c
Normal file
62
demo/stm32-freertos/shell_port.c
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file shell_port.c
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2019-02-22
|
||||
*
|
||||
* @Copyright (c) 2019 Unicook
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shell.h"
|
||||
#include "serial.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "usart.h"
|
||||
|
||||
|
||||
Shell shell;
|
||||
char shellBuffer[512];
|
||||
|
||||
/**
|
||||
* @brief 用户shell写
|
||||
*
|
||||
* @param data 数据
|
||||
*/
|
||||
void userShellWrite(char data)
|
||||
{
|
||||
serialTransmit(&debugSerial, (uint8_t *)&data, 1, 0xFF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 用户shell读
|
||||
*
|
||||
* @param data 数据
|
||||
* @return char 状态
|
||||
*/
|
||||
signed char userShellRead(char *data)
|
||||
{
|
||||
if (serialReceive(&debugSerial, (uint8_t *)data, 1, 0) == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 用户shell初始化
|
||||
*
|
||||
*/
|
||||
void userShellInit(void)
|
||||
{
|
||||
shell.write = userShellWrite;
|
||||
shell.read = userShellRead;
|
||||
shellInit(&shell, shellBuffer, 512);
|
||||
}
|
||||
|
21
demo/stm32-freertos/shell_port.h
Normal file
21
demo/stm32-freertos/shell_port.h
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @file shell_port.h
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2019-02-22
|
||||
*
|
||||
* @Copyright (c) 2019 Unicook
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHELL_PORT_H__
|
||||
#define __SHELL_PORT_H__
|
||||
|
||||
#include "serial.h"
|
||||
#include "shell.h"
|
||||
|
||||
extern Shell shell;
|
||||
|
||||
void userShellInit(void);
|
||||
#endif
|
BIN
doc/img/shell_info.png
Normal file
BIN
doc/img/shell_info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
363
shell.h
363
shell.h
@ -1,363 +0,0 @@
|
||||
/**
|
||||
* @file shell.h
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief letter shell
|
||||
* @version 2.0.0
|
||||
* @date 2018-12-29
|
||||
*
|
||||
* @Copyright (c) 2018 Letter
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHELL_H__
|
||||
#define __SHELL_H__
|
||||
|
||||
#include "shell_cfg.h"
|
||||
|
||||
#if SHELL_USING_AUTH == 1
|
||||
#if !defined(SHELL_USER_PASSWORD)
|
||||
#error "please config shell user password (int shell_cfg.h) "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SHELL_VERSION "2.0.8" /**< 版本号 */
|
||||
|
||||
/**
|
||||
* @brief shell键值定义
|
||||
*
|
||||
*/
|
||||
#define SHELL_KEY_LF 0x0A
|
||||
#define SHELL_KEY_CR 0x0D
|
||||
#define SHELL_KEY_TAB 0x09
|
||||
#define SHELL_KEY_BACKSPACE 0x08
|
||||
#define SHELL_KEY_DELETE 0x7F
|
||||
#define SHELL_KEY_ESC 0x1B
|
||||
|
||||
#define SHELL_KEY_CTRL_T 0x14
|
||||
#define SHELL_KEY_CTRL_A 0x01
|
||||
#define SHELL_KEY_CTRL_B 0x02
|
||||
#define SHELL_KEY_CTRL_C 0x03
|
||||
#define SHELL_KEY_CTRL_D 0x04
|
||||
#define SHELL_KEY_CTRL_E 0x05
|
||||
#define SHELL_KEY_CTRL_F 0x06
|
||||
#define SHELL_KEY_CTRL_G 0x07
|
||||
#define SHELL_KEY_CTRL_H 0x08
|
||||
#define SHELL_KEY_CTRL_I 0x09
|
||||
#define SHELL_KEY_CTRL_J 0x0A
|
||||
#define SHELL_KEY_CTRL_K 0x0B
|
||||
#define SHELL_KEY_CTRL_L 0x0C
|
||||
#define SHELL_KEY_CTRL_M 0x0D
|
||||
#define SHELL_KEY_CTRL_N 0x0E
|
||||
#define SHELL_KEY_CTRL_O 0x0F
|
||||
#define SHELL_KEY_CTRL_P 0x10
|
||||
#define SHELL_KEY_CTRL_Q 0x11
|
||||
#define SHELL_KEY_CTRL_R 0x12
|
||||
#define SHELL_KEY_CTRL_S 0x13
|
||||
#define SHELL_KEY_CTRL_T 0x14
|
||||
#define SHELL_KEY_CTRL_U 0x15
|
||||
#define SHELL_KEY_CTRL_V 0x16
|
||||
#define SHELL_KEY_CTRL_W 0x17
|
||||
#define SHELL_KEY_CTRL_X 0x18
|
||||
#define SHELL_KEY_CTRL_Y 0x19
|
||||
#define SHELL_KEY_CTRL_Z 0x1A
|
||||
|
||||
/**
|
||||
* @brief shell变量类型定义
|
||||
*
|
||||
*/
|
||||
#define SHELL_VAR_INT 0
|
||||
#define SHELL_VAR_SHORT 1
|
||||
#define SHELL_VAR_CHAR 2
|
||||
#define SHELL_VAR_POINTER 3
|
||||
#define SHELL_VAL 4
|
||||
|
||||
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000)
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#elif defined(__ICCARM__)
|
||||
#define SECTION(x) @ x
|
||||
#elif defined(__GNUC__)
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#else
|
||||
#define SECTION(x)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief shell命令导出
|
||||
*
|
||||
* @attention 命令导出方式支持keil,iar的编译器以及gcc,具体参考readme
|
||||
*/
|
||||
#if SHELL_USING_CMD_EXPORT == 1
|
||||
#if SHELL_LONG_HELP == 1
|
||||
#define SHELL_EXPORT_CMD(cmd, func, desc) \
|
||||
const char shellCmd##cmd[] = #cmd; \
|
||||
const char shellDesc##cmd[] = #desc; \
|
||||
const SHELL_CommandTypeDef \
|
||||
shellCommand##cmd SECTION("shellCommand") = \
|
||||
{ \
|
||||
shellCmd##cmd, \
|
||||
(int (*)())func, \
|
||||
shellDesc##cmd, \
|
||||
(void *)0 \
|
||||
}
|
||||
#define SHELL_EXPORT_CMD_EX(cmd, func, desc, help) \
|
||||
const char shellCmd##cmd[] = #cmd; \
|
||||
const char shellDesc##cmd[] = #desc; \
|
||||
const char shellHelp##cmd[] = #help; \
|
||||
const SHELL_CommandTypeDef \
|
||||
shellCommand##cmd SECTION("shellCommand") = \
|
||||
{ \
|
||||
shellCmd##cmd, \
|
||||
(int (*)())func, \
|
||||
shellDesc##cmd, \
|
||||
shellHelp##cmd \
|
||||
}
|
||||
#else /** SHELL_LONG_HELP == 1 */
|
||||
#define SHELL_EXPORT_CMD(cmd, func, desc) \
|
||||
const char shellCmd##cmd[] = #cmd; \
|
||||
const char shellDesc##cmd[] = #desc; \
|
||||
const SHELL_CommandTypeDef \
|
||||
shellCommand##cmd SECTION("shellCommand") = \
|
||||
{ \
|
||||
shellCmd##cmd, \
|
||||
(int (*)())func, \
|
||||
shellDesc##cmd \
|
||||
}
|
||||
#define SHELL_EXPORT_CMD_EX(cmd, func, desc, help) \
|
||||
const char shellCmd##cmd[] = #cmd; \
|
||||
const char shellDesc##cmd[] = #desc; \
|
||||
const SHELL_CommandTypeDef \
|
||||
shellCommand##cmd SECTION("shellCommand") = \
|
||||
{ \
|
||||
shellCmd##cmd, \
|
||||
(int (*)())func, \
|
||||
shellDesc##cmd \
|
||||
}
|
||||
#endif /** SHELL_LONG_HELP == 1 */
|
||||
|
||||
#if SHELL_USING_VAR == 1
|
||||
#define SHELL_EXPORT_VAR(var, variable, desc, type) \
|
||||
const char shellVar##var[] = #var; \
|
||||
const char shellDesc##var[] = #desc; \
|
||||
const SHELL_VaribaleTypeDef \
|
||||
shellVariable##var SECTION("shellVariable") = \
|
||||
{ \
|
||||
shellVar##var, \
|
||||
(void *)(variable), \
|
||||
shellDesc##var, \
|
||||
type \
|
||||
}
|
||||
#else
|
||||
#define SHELL_EXPORT_VAR(var, variable, desc, type)
|
||||
#endif /** SHELL_USING_VAR == 1 */
|
||||
|
||||
#else
|
||||
#define SHELL_EXPORT_CMD(cmd, func, desc)
|
||||
#define SHELL_EXPORT_CMD_EX(cmd, func, desc, help)
|
||||
#define SHELL_EXPORT_VAR(var, variable, desc, type)
|
||||
#endif /** SHELL_USING_CMD_EXPORT == 1 */
|
||||
|
||||
#define SHELL_EXPORT_VAR_INT(var, variable, desc) \
|
||||
SHELL_EXPORT_VAR(var, &variable, desc, SHELL_VAR_INT)
|
||||
#define SHELL_EXPORT_VAR_SHORT(var, variable, desc) \
|
||||
SHELL_EXPORT_VAR(var, &variable, desc, SHELL_VAR_SHORT)
|
||||
#define SHELL_EXPORT_VAR_CHAR(var, variable, desc) \
|
||||
SHELL_EXPORT_VAR(var, &variable, desc, SHELL_VAR_CHAR)
|
||||
#define SHELL_EXPORT_VAR_POINTER(var, variable, desc) \
|
||||
SHELL_EXPORT_VAR(var, variable, desc, SHELL_VAR_POINTER)
|
||||
#define SHELL_EXPORT_VAL(val, value, desc) \
|
||||
SHELL_EXPORT_VAR(val, value, desc, SHELL_VAL)
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell命令条目
|
||||
*
|
||||
* @note 用于shell命令通过命令表的方式定义
|
||||
*/
|
||||
#if SHELL_USING_CMD_EXPORT == 0
|
||||
#if SHELL_LONG_HELP == 1
|
||||
#define SHELL_CMD_ITEM(cmd, func, desc) \
|
||||
{ \
|
||||
#cmd, \
|
||||
(int (*)())func, \
|
||||
#desc, \
|
||||
(void *)0 \
|
||||
}
|
||||
#define SHELL_CMD_ITEM_EX(cmd, func, desc, help) \
|
||||
{ \
|
||||
#cmd, \
|
||||
(int (*)())func, \
|
||||
#desc, \
|
||||
#help \
|
||||
}
|
||||
#else /** SHELL_LONG_HELP == 1 */
|
||||
#define SHELL_CMD_ITEM(cmd, func, desc) \
|
||||
{ \
|
||||
#cmd, \
|
||||
(int (*)())func, \
|
||||
#desc \
|
||||
}
|
||||
#define SHELL_CMD_ITEM_EX(cmd, func, desc, help) \
|
||||
{ \
|
||||
#cmd, \
|
||||
(int (*)())func, \
|
||||
#desc, \
|
||||
}
|
||||
#endif /** SHELL_LONG_HELP == 1 */
|
||||
|
||||
#define SHELL_VAR_ITEM(var, variable, desc, type) \
|
||||
{ \
|
||||
#var, \
|
||||
varialbe, \
|
||||
#desc, \
|
||||
type, \
|
||||
}
|
||||
#define SHELL_VAR_ITEM_INT(var, variable, desc) \
|
||||
SHELL_VAR_ITEM(var, &variable, desc, SHELL_VAR_INT)
|
||||
#define SHELL_VAR_ITEM_SHORT(var, variable, desc) \
|
||||
SHELL_VAR_ITEM(var, &variable, desc, SHELL_VAR_SHORT)
|
||||
#define SHELL_VAR_ITEM_CHAR(var, variable, desc) \
|
||||
SHELL_VAR_ITEM(var, &variable, desc, SHELL_VAR_CHAR)
|
||||
#define SHELL_VAR_ITEM_POINTER(var, variable, desc) \
|
||||
SHELL_VAR_ITEM(var, variable, desc, SHELL_VAR_POINTER)
|
||||
|
||||
#endif /** SHELL_USING_CMD_EXPORT == 0 */
|
||||
|
||||
/**
|
||||
* @brief shell读取数据函数原型
|
||||
*
|
||||
* @param char shell读取的字符
|
||||
*
|
||||
* @return char 0 读取数据成功
|
||||
* @return char -1 读取数据失败
|
||||
*/
|
||||
typedef signed char (*shellRead)(char *);
|
||||
|
||||
/**
|
||||
* @brief shell写数据函数原型
|
||||
*
|
||||
* @param const char 需写的字符
|
||||
*/
|
||||
typedef void (*shellWrite)(const char);
|
||||
|
||||
/**
|
||||
* @brief shell指令执行函数原型
|
||||
*
|
||||
*/
|
||||
typedef int (*shellFunction)();
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell输入状态
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SHELL_IN_NORMAL = 0,
|
||||
SHELL_ANSI_ESC,
|
||||
SHELL_ANSI_CSI,
|
||||
}SHELL_InputMode;
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell 命令定义
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char *name; /**< shell命令名称 */
|
||||
shellFunction function; /**< shell命令函数 */
|
||||
const char *desc; /**< shell命令描述 */
|
||||
#if SHELL_LONG_HELP == 1
|
||||
const char *help; /**< shell长帮助信息 */
|
||||
#endif
|
||||
}SHELL_CommandTypeDef;
|
||||
|
||||
|
||||
#if SHELL_USING_VAR == 1
|
||||
/**
|
||||
* @brief shell 变量定义
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char *name; /**< shell变量名称 */
|
||||
const void *value; /**< shell变量值 */
|
||||
const char *desc; /**< shell变量描述 */
|
||||
const int type; /**< shell变量类型 */
|
||||
} SHELL_VaribaleTypeDef;
|
||||
#endif /** SHELL_USING_VAR == 1 */
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell对象定义
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *command; /**< shell命令提示符 */
|
||||
char buffer[SHELL_COMMAND_MAX_LENGTH]; /**< shell命令缓冲 */
|
||||
unsigned short length; /**< shell命令长度 */
|
||||
unsigned short cursor; /**< shell光标位置 */
|
||||
char *param[SHELL_PARAMETER_MAX_NUMBER]; /**< shell参数 */
|
||||
char history[SHELL_HISTORY_MAX_NUMBER][SHELL_COMMAND_MAX_LENGTH]; /**< 历史记录 */
|
||||
unsigned short historyCount; /**< 历史记录数量 */
|
||||
short historyFlag; /**< 当前记录位置 */
|
||||
short historyOffset; /**< 历史记录偏移 */
|
||||
SHELL_CommandTypeDef *commandBase; /**< 命令表基址 */
|
||||
unsigned short commandNumber; /**< 命令数量 */
|
||||
#if SHELL_USING_VAR == 1
|
||||
SHELL_VaribaleTypeDef *variableBase; /**< 变量表基址 */
|
||||
unsigned short variableNumber; /**< 变量数量 */
|
||||
#endif
|
||||
int keyFuncBase; /**< 按键响应表基址 */
|
||||
unsigned short keyFuncNumber; /**< 按键响应数量 */
|
||||
struct
|
||||
{
|
||||
unsigned char inputMode : 2; /**< 输入模式 */
|
||||
unsigned char isActive: 1; /**< 是否是当前活动shell */
|
||||
unsigned char tabFlag : 1; /**< tab标志 */
|
||||
unsigned char authFlag : 1; /**< 密码标志 */
|
||||
} status; /**< shell状态 */
|
||||
shellRead read; /**< shell读字符 */
|
||||
shellWrite write; /**< shell写字符 */
|
||||
#if SHELL_LONG_HELP == 1 || (SHELL_USING_AUTH && SHELL_LOCK_TIMEOUT > 0)
|
||||
int activeTime; /**< shell激活时间戳 */
|
||||
#endif
|
||||
}SHELL_TypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell按键功能定义
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char keyCode; /**< shell按键键值 */
|
||||
void (*keyFunction)(SHELL_TypeDef *); /**< 按键响应函数 */
|
||||
} SHELL_KeyFunctionDef;
|
||||
|
||||
|
||||
void shellInit(SHELL_TypeDef *shell);
|
||||
void shellSetCommandList(SHELL_TypeDef *shell, SHELL_CommandTypeDef *base, unsigned short size);
|
||||
|
||||
#if SHELL_USING_VAR == 1
|
||||
void shellSetVariableList(SHELL_TypeDef *shell, SHELL_VaribaleTypeDef *base, unsigned short size);
|
||||
int shellGetVariable(SHELL_TypeDef *shell, char *var);
|
||||
#endif /** SHELL_USING_VAR == 1 */
|
||||
|
||||
void shellSetKeyFuncList(SHELL_TypeDef *shell, SHELL_KeyFunctionDef *base, unsigned short size);
|
||||
SHELL_TypeDef *shellGetCurrent(void);
|
||||
void shellPrint(SHELL_TypeDef *shell, char *fmt, ...);
|
||||
unsigned short shellDisplay(SHELL_TypeDef *shell, const char *string);
|
||||
void shellHandler(SHELL_TypeDef *shell, char data);
|
||||
#define shellInput shellHandler
|
||||
|
||||
void shellHelp(int argc, char *argv[]);
|
||||
void shellClear(void);
|
||||
|
||||
#if SHELL_USING_TASK == 1
|
||||
void shellTask(void *param);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
1653
src/shell.c
Normal file
1653
src/shell.c
Normal file
File diff suppressed because it is too large
Load Diff
327
src/shell.h
Normal file
327
src/shell.h
Normal file
@ -0,0 +1,327 @@
|
||||
/**
|
||||
* @file shell.h
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief letter shell
|
||||
* @version 3.0.0
|
||||
* @date 2019-12-30
|
||||
*
|
||||
* @Copyright (c) 2020 Letter
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHELL_H__
|
||||
#define __SHELL_H__
|
||||
|
||||
#include "shell_cfg.h"
|
||||
|
||||
#define SHELL_VERSION "3.0.0-beta1" /**< 版本号 */
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell 断言
|
||||
*
|
||||
* @param expr 表达式
|
||||
* @param action 断言失败操作
|
||||
*/
|
||||
#define SHELL_ASSERT(expr, action) \
|
||||
if (!(expr)) { \
|
||||
action; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 命令权限
|
||||
*
|
||||
* @param permission 权限级别
|
||||
*/
|
||||
#define SHELL_CMD_PERMISSION(permission) \
|
||||
(permission & 0x000000FF)
|
||||
|
||||
/**
|
||||
* @brief shell 命令类型
|
||||
*
|
||||
* @param type 类型
|
||||
*/
|
||||
#define SHELL_CMD_TYPE(type) \
|
||||
((type & 0x0000000F) << 8)
|
||||
|
||||
#define SHELL_CMD_ENABLE_UNCHECKED \
|
||||
(1 << 12)
|
||||
|
||||
#define SHELL_CMD_DISABLE_RETURN \
|
||||
(1 << 13)
|
||||
|
||||
|
||||
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000)
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#elif defined(__ICCARM__)
|
||||
#define SECTION(x) @ x
|
||||
#elif defined(__GNUC__)
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#else
|
||||
#define SECTION(x)
|
||||
#endif
|
||||
|
||||
#if SHELL_USING_CMD_EXPORT == 1
|
||||
|
||||
/**
|
||||
* @brief shell 命令定义
|
||||
*
|
||||
* @param _attr 命令属性
|
||||
* @param _name 命令名
|
||||
* @param _func 命令函数
|
||||
* @param _desc 命令描述
|
||||
*/
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellCommand##_name SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.cmd.name = shellCmd##_name, \
|
||||
.data.cmd.function = (int (*)())_func, \
|
||||
.data.cmd.desc = shellDesc##_name \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 变量定义
|
||||
*
|
||||
* @param _attr 变量属性
|
||||
* @param _name 变量名
|
||||
* @param _value 变量值
|
||||
* @param _desc 变量描述
|
||||
*/
|
||||
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellVar##_name SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.var.name = shellCmd##_name, \
|
||||
.data.var.value = (void *)_value, \
|
||||
.data.var.desc = shellDesc##_name \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 用户定义
|
||||
*
|
||||
* @param _attr 用户属性
|
||||
* @param _name 用户名
|
||||
* @param _password 用户密码
|
||||
* @param _desc 用户描述
|
||||
*/
|
||||
#define SHELL_EXPORT_USER(_attr, _name, _password, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellPassword##_name[] = #_password; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellUser##_name SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \
|
||||
.data.user.name = shellCmd##_name, \
|
||||
.data.user.password = shellPassword##_name, \
|
||||
.data.user.desc = shellDesc##_name \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 按键定义
|
||||
*
|
||||
* @param _attr 按键属性
|
||||
* @param _value 按键键值
|
||||
* @param _func 按键函数
|
||||
* @param _desc 按键描述
|
||||
*/
|
||||
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \
|
||||
const char shellDesc##_value[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellKey##_value SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
|
||||
.data.key.value = _value, \
|
||||
.data.key.function = (void (*)(Shell *))_func, \
|
||||
.data.key.desc = shellDesc##_value \
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* @brief shell 命令item定义
|
||||
*
|
||||
* @param _attr 命令属性
|
||||
* @param _name 命令名
|
||||
* @param _func 命令函数
|
||||
* @param _desc 命令描述
|
||||
*/
|
||||
#define SHELL_CMD_ITEM(_attr, _name, _func, _desc) \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.cmd.name = #_name, \
|
||||
.data.cmd.function = (int (*)())_func, \
|
||||
.data.cmd.desc = #_desc \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 变量item定义
|
||||
*
|
||||
* @param _attr 变量属性
|
||||
* @param _name 变量名
|
||||
* @param _value 变量值
|
||||
* @param _desc 变量描述
|
||||
*/
|
||||
#define SHELL_VAR_ITEM(_attr, _name, _value, _desc) \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.var.name = #_name, \
|
||||
.data.var.value = (void *)_value, \
|
||||
.data.var.desc = #_desc \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 用户item定义
|
||||
*
|
||||
* @param _attr 用户属性
|
||||
* @param _name 用户名
|
||||
* @param _password 用户密码
|
||||
* @param _desc 用户描述
|
||||
*/
|
||||
#define SHELL_USER_ITEM(_attr, _name, _password, _desc) \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \
|
||||
.data.user.name = #_name, \
|
||||
.data.user.password = #_password, \
|
||||
.data.user.desc = #_desc \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 按键item定义
|
||||
*
|
||||
* @param _attr 按键属性
|
||||
* @param _value 按键键值
|
||||
* @param _func 按键函数
|
||||
* @param _desc 按键描述
|
||||
*/
|
||||
#define SHELL_KEY_ITEM(_attr, _value, _func, _desc) \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
|
||||
.data.key.value = _value, \
|
||||
.data.key.function = (void (*)(Shell *))_func, \
|
||||
.data.key.desc = #_desc \
|
||||
}
|
||||
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc)
|
||||
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc)
|
||||
#define SHELL_EXPORT_USER(_attr, _name, _password, _desc)
|
||||
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc)
|
||||
#endif /** SHELL_USING_CMD_EXPORT == 1 */
|
||||
|
||||
/**
|
||||
* @brief shell command类型
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SHELL_TYPE_CMD_MAIN = 0, /**< main形式命令 */
|
||||
SHELL_TYPE_CMD_FUNC, /**< C函数形式命令 */
|
||||
SHELL_TYPE_VAR_INT, /**< int型变量 */
|
||||
SHELL_TYPE_VAR_SHORT, /**< short型变量 */
|
||||
SHELL_TYPE_VAR_CHAR, /**< char型变量 */
|
||||
SHELL_TYPE_VAR_POINT, /**< 指针型变量 */
|
||||
SHELL_TYPE_VAL, /**< 常量 */
|
||||
SHELL_TYPE_USER, /**< 用户 */
|
||||
SHELL_TYPE_KEY, /**< 按键 */
|
||||
} ShellCommandType;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Shell定义
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
const struct shell_command *user; /**< 当前用户 */
|
||||
int activeTime; /**< shell激活时间 */
|
||||
} info;
|
||||
struct
|
||||
{
|
||||
unsigned short length; /**< 输入数据长度 */
|
||||
unsigned short cursor; /**< 当前光标位置 */
|
||||
char *buffer; /**< 输入缓冲 */
|
||||
unsigned short bufferSize; /**< 输入缓冲大小 */
|
||||
char *param[SHELL_PARAMETER_MAX_NUMBER]; /**< 参数 */
|
||||
unsigned short paramCount; /**< 参数数量 */
|
||||
int keyValue; /**< 输入按键键值 */
|
||||
} parser;
|
||||
struct
|
||||
{
|
||||
char *item[SHELL_HISTORY_MAX_NUMBER]; /**< 历史记录 */
|
||||
unsigned short number; /**< 历史记录数 */
|
||||
unsigned short record; /**< 当前记录位置 */
|
||||
signed short offset; /**< 当前历史记录偏移 */
|
||||
} history;
|
||||
struct
|
||||
{
|
||||
void *base; /**< 命令表基址 */
|
||||
unsigned short count; /**< 命令数量 */
|
||||
} commandList;
|
||||
struct
|
||||
{
|
||||
unsigned char isChecked : 1; /**< 密码校验通过 */
|
||||
unsigned char isActive : 1; /**< 当前活动Shell */
|
||||
unsigned char tabFlag : 1; /**< tab标志 */
|
||||
} status;
|
||||
signed char (*read)(char *); /**< shell读函数 */
|
||||
void (*write)(const char); /**< shell写函数 */
|
||||
} Shell;
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell command定义
|
||||
*/
|
||||
typedef struct shell_command
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char permission : 8; /**< command权限 */
|
||||
ShellCommandType type : 4; /**< command类型 */
|
||||
unsigned char enableUnchecked : 1; /**< 在未校验密码的情况下可用 */
|
||||
unsigned char disableReturn : 1; /**< 禁用返回值输出 */
|
||||
} attrs;
|
||||
int value;
|
||||
} attr; /**< 属性 */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
const char *name; /**< 命令名 */
|
||||
int (*function)(); /**< 命令执行函数 */
|
||||
const char *desc; /**< 命令描述 */
|
||||
} cmd; /**< 命令定义 */
|
||||
struct
|
||||
{
|
||||
const char *name; /**< 变量名 */
|
||||
void *value; /**< 变量值 */
|
||||
const char *desc; /**< 变量描述 */
|
||||
} var; /**< 变量定义 */
|
||||
struct
|
||||
{
|
||||
const char *name; /**< 用户名 */
|
||||
const char *password; /**< 用户密码 */
|
||||
const char *desc; /**< 用户描述 */
|
||||
} user; /**< 用户定义 */
|
||||
struct
|
||||
{
|
||||
int value; /**< 按键键值 */
|
||||
void (*function)(Shell *); /**< 按键执行函数 */
|
||||
const char *desc; /**< 按键描述 */
|
||||
} key; /**< 按键定义 */
|
||||
} data;
|
||||
} ShellCommand;
|
||||
|
||||
|
||||
void shellInit(Shell *shell, char *buffer, unsigned short size);
|
||||
void shellHandler(Shell *shell, char data);
|
||||
void shellTask(void *param);
|
||||
|
||||
#endif
|
||||
|
@ -1,9 +1,9 @@
|
||||
/**
|
||||
* @file shell_cfg.h
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @author Letter (nevermindzzt@gmail.com)
|
||||
* @brief shell config
|
||||
* @version 0.1
|
||||
* @date 2019-04-11
|
||||
* @version 3.0.0
|
||||
* @date 2019-12-31
|
||||
*
|
||||
* @copyright (c) 2019 Letter
|
||||
*
|
||||
@ -12,11 +12,6 @@
|
||||
#ifndef __SHELL_CFG_H__
|
||||
#define __SHELL_CFG_H__
|
||||
|
||||
/**
|
||||
* @brief 是否使用默认shell任务
|
||||
* 使能之后可以使用`shellTask()`建立shell任务,或者使用`shellTask()`进行轮询
|
||||
*/
|
||||
#define SHELL_USING_TASK 0
|
||||
|
||||
/**
|
||||
* @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义
|
||||
@ -27,41 +22,43 @@
|
||||
|
||||
/**
|
||||
* @brief 是否使用命令导出方式
|
||||
* 使能此宏后,可以使用`SHELL_EXPORT_CMD()`或者`SHELL_EXPORT_CMD_EX()`
|
||||
* 使能此宏后,可以使用`SHELL_EXPORT_CMD()`等导出命令
|
||||
* 定义shell命令,关闭此宏的情况下,需要使用命令表的方式
|
||||
*/
|
||||
#define SHELL_USING_CMD_EXPORT 1
|
||||
|
||||
/**
|
||||
* @brief 是否使用变量功能
|
||||
*
|
||||
* @brief 是否在输入命令列表中列出用户
|
||||
*/
|
||||
#define SHELL_USING_VAR 0
|
||||
#define SHELL_HELP_LIST_USER 0
|
||||
|
||||
/**
|
||||
* @brief 是否显示命令调用函数返回值
|
||||
* 使能此宏,则每次调用shell命令之后会以整形和十六进制的方式打印函数的返回值
|
||||
* @brief 是否在输入命令列表中列出变量
|
||||
*/
|
||||
#define SHELL_DISPLAY_RETURN 1
|
||||
#define SHELL_HELP_LIST_VAR 0
|
||||
|
||||
/**
|
||||
* @brief 是否使用shell参数自动解析
|
||||
* 使能此宏以支持常规C函数形式的命令,shell会自动转换参数
|
||||
* 关闭此宏则支持main函数形式的命令,需要自行在函数中处理参数
|
||||
* @brief 是否在输入命令列表中列出按键
|
||||
*/
|
||||
#define SHELL_AUTO_PRASE 1
|
||||
#define SHELL_HELP_LIST_KEY 0
|
||||
|
||||
/**
|
||||
* @brief 是否使用shell长帮助
|
||||
* 使能此宏以支持命令的长帮助信息
|
||||
* @brief 使用LF作为命令行回车触发
|
||||
* 可以和SHELL_ENTER_CR同时开启
|
||||
*/
|
||||
#define SHELL_LONG_HELP 1
|
||||
#define SHELL_ENTER_LF 1
|
||||
|
||||
/**
|
||||
* @brief shell命令最大长度
|
||||
* 命令行可输入的最大字符长度
|
||||
* @brief 使用CR作为命令行回车触发
|
||||
* 可以和SHELL_ENTER_LF同时开启
|
||||
*/
|
||||
#define SHELL_COMMAND_MAX_LENGTH 50
|
||||
#define SHELL_ENTER_CR 1
|
||||
|
||||
/**
|
||||
* @brief 使用CRLF作为命令行回车触发
|
||||
* 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启
|
||||
*/
|
||||
#define SHELL_ENTER_CRLF 0
|
||||
|
||||
/**
|
||||
* @brief shell命令参数最大数量
|
||||
@ -99,19 +96,15 @@
|
||||
#define SHELL_GET_TICK() 0
|
||||
|
||||
/**
|
||||
* @brief shell默认提示符
|
||||
* @brief shell默认用户
|
||||
*/
|
||||
#define SHELL_DEFAULT_COMMAND "\r\nletter>>"
|
||||
#define SHELL_DEFAULT_USER "letter"
|
||||
|
||||
/**
|
||||
* @brief 是否使用密码功能
|
||||
* @brief shell默认用户密码
|
||||
* 若默认用户不需要密码,设为""
|
||||
*/
|
||||
#define SHELL_USING_AUTH 0
|
||||
|
||||
/**
|
||||
* @brief shell用户密码
|
||||
*/
|
||||
#define SHELL_USER_PASSWORD "letter"
|
||||
#define SHELL_DEFAULT_USER_PASSWORD ""
|
||||
|
||||
/**
|
||||
* @brief shell自动锁定超时
|
||||
@ -119,6 +112,6 @@
|
||||
* 设置为0时关闭自动锁定功能,时间单位为`SHELL_GET_TICK()`单位
|
||||
* @note 使用超时锁定必须保证`SHELL_GET_TICK()`有效
|
||||
*/
|
||||
#define SHELL_LOCK_TIMEOUT 5 * 60 * 1000
|
||||
#define SHELL_LOCK_TIMEOUT 0 * 60 * 1000
|
||||
|
||||
#endif
|
98
src/shell_cmd_list.c
Normal file
98
src/shell_cmd_list.c
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @file shell_cmd_list.c
|
||||
* @author Letter (zhengkeqiang@ut.cn)
|
||||
* @brief shell cmd list
|
||||
* @version 0.1
|
||||
* @date 2020-01-17
|
||||
*
|
||||
* @copyright (c) 2020 Unicook
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
#if SHELL_USING_CMD_EXPORT != 1
|
||||
|
||||
extern int shellSetVar(char *name, int value);
|
||||
extern void shellUp(Shell *shell);
|
||||
extern void shellDown(Shell *shell);
|
||||
extern void shellRight(Shell *shell);
|
||||
extern void shellLeft(Shell *shell);
|
||||
extern void shellTab(Shell *shell);
|
||||
extern void shellBackspace(Shell *shell);
|
||||
extern void shellDelete(Shell *shell);
|
||||
extern void shellEnter(Shell *shell);
|
||||
extern void shellHelp(int argc, char *argv[]);
|
||||
extern void shellUsers(void);
|
||||
extern void shellCmds(void);
|
||||
extern void shellVars(void);
|
||||
extern void shellKeys(void);
|
||||
extern void shellClear(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell命令表
|
||||
*
|
||||
*/
|
||||
const ShellCommand shellCommandList[] =
|
||||
{
|
||||
{.attr.value=SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_USER),
|
||||
.data.user.name = SHELL_DEFAULT_USER,
|
||||
.data.user.password = SHELL_DEFAULT_USER_PASSWORD,
|
||||
.data.user.desc = "defalut user"},
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
|
||||
setVar, shellSetVar, set var),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x1B5B4100, shellUp, up),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x1B5B4200, shellDown, down),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x1B5B4300, shellRight, right),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x1B5B4400, shellLeft, left),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0), 0x09000000, shellTab, tab),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x08000000, shellBackspace, backspace),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x7F000000, shellDelete, delete),
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x1B5B337E, shellDelete, delete),
|
||||
#if SHELL_ENTER_LF == 1
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x0A000000, shellEnter, enter),
|
||||
#endif
|
||||
#if SHELL_ENTER_CR == 1
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x0D000000, shellEnter, enter),
|
||||
#endif
|
||||
#if SHELL_ENTER_CRLF == 1
|
||||
SHELL_KEY_ITEM(SHELL_CMD_PERMISSION(0)|SHELL_CMD_ENABLE_UNCHECKED,
|
||||
0x0D0A0000, shellEnter, enter),
|
||||
#endif
|
||||
SHELL_CMD_ITEM(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN,
|
||||
help, shellHelp, show command info\r\nhelp [cmd]),
|
||||
SHELL_CMD_ITEM(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
|
||||
users, shellUsers, list all user),
|
||||
SHELL_CMD_ITEM(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
|
||||
cmds, shellCmds, list all cmd),
|
||||
SHELL_CMD_ITEM(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
|
||||
vars, shellVars, list all var),
|
||||
SHELL_CMD_ITEM(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
|
||||
keys, shellKeys, list all key),
|
||||
SHELL_CMD_ITEM(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
|
||||
clear, shellClear, clear console),
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief shell命令表大小
|
||||
*
|
||||
*/
|
||||
const unsigned short shellCommandCount
|
||||
= sizeof(shellCommandList) / sizeof(ShellCommand);
|
||||
|
||||
#endif
|
@ -2,8 +2,8 @@
|
||||
* @file shell_ext.c
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief shell extensions
|
||||
* @version 1.0.0
|
||||
* @date 2019-01-05
|
||||
* @version 3.0.0
|
||||
* @date 2019-12-31
|
||||
*
|
||||
* @Copyright (c) 2019 Letter
|
||||
*
|
||||
@ -14,6 +14,12 @@
|
||||
#include "shell_ext.h"
|
||||
|
||||
|
||||
extern ShellCommand* shellSeekCommand(Shell *shell,
|
||||
const char *cmd,
|
||||
ShellCommand *base,
|
||||
unsigned short compareLength);
|
||||
extern int shellGetVarValue(Shell *shell, ShellCommand *command);
|
||||
|
||||
/**
|
||||
* @brief 判断数字进制
|
||||
*
|
||||
@ -231,13 +237,38 @@ static unsigned int shellExtParseNumber(char *string)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 解析变量参数
|
||||
*
|
||||
* @param shell shell对象
|
||||
* @param var 变量
|
||||
* @return unsigned int 变量值
|
||||
*/
|
||||
static unsigned int shellExtParseVar(Shell *shell, char *var)
|
||||
{
|
||||
ShellCommand *command = shellSeekCommand(shell,
|
||||
var + 1,
|
||||
shell->commandList.base,
|
||||
0);
|
||||
if (command)
|
||||
{
|
||||
return shellGetVarValue(shell, command);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 解析参数
|
||||
*
|
||||
* @param shell shell对象
|
||||
* @param string 参数
|
||||
* @return unsigned int 解析结果
|
||||
*/
|
||||
unsigned int shellExtParsePara(char *string)
|
||||
unsigned int shellExtParsePara(Shell *shell, char *string)
|
||||
{
|
||||
if (*string == '\'' && *(string + 1))
|
||||
{
|
||||
@ -247,12 +278,10 @@ unsigned int shellExtParsePara(char *string)
|
||||
{
|
||||
return (unsigned int)shellExtParseNumber(string);
|
||||
}
|
||||
#if SHELL_USING_VAR == 1
|
||||
else if (*string == '$' && *(string + 1))
|
||||
{
|
||||
return (unsigned int )shellGetVariable(shellGetCurrent(), string);
|
||||
return shellExtParseVar(shell, string);
|
||||
}
|
||||
#endif /** SHELL_USING_VAR == 1 */
|
||||
else if (*string)
|
||||
{
|
||||
return (unsigned int)shellExtParseString(string);
|
||||
@ -264,12 +293,13 @@ unsigned int shellExtParsePara(char *string)
|
||||
/**
|
||||
* @brief 执行命令
|
||||
*
|
||||
* @param shell shell对象
|
||||
* @param function 执行命令的函数
|
||||
* @param argc 参数个数
|
||||
* @param argv 参数
|
||||
* @return int 返回值
|
||||
*/
|
||||
int shellExtRun(shellFunction function, int argc, char *argv[])
|
||||
int shellExtRun(Shell *shell, int (*function)(), int argc, char *argv[])
|
||||
{
|
||||
switch (argc)
|
||||
{
|
||||
@ -277,34 +307,34 @@ int shellExtRun(shellFunction function, int argc, char *argv[])
|
||||
return function();
|
||||
// break;
|
||||
case 2:
|
||||
return function(shellExtParsePara(argv[1]));
|
||||
return function(shellExtParsePara(shell, argv[1]));
|
||||
// break;
|
||||
case 3:
|
||||
return function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]));
|
||||
return function(shellExtParsePara(shell, argv[1]), shellExtParsePara(shell, argv[2]));
|
||||
// break;
|
||||
case 4:
|
||||
return function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
|
||||
shellExtParsePara(argv[3]));
|
||||
return function(shellExtParsePara(shell, argv[1]), shellExtParsePara(shell, argv[2]),
|
||||
shellExtParsePara(shell, argv[3]));
|
||||
// break;
|
||||
case 5:
|
||||
return function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
|
||||
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]));
|
||||
return function(shellExtParsePara(shell, argv[1]), shellExtParsePara(shell, argv[2]),
|
||||
shellExtParsePara(shell, argv[3]), shellExtParsePara(shell, argv[4]));
|
||||
// break;
|
||||
case 6:
|
||||
return function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
|
||||
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]),
|
||||
shellExtParsePara(argv[5]));
|
||||
return function(shellExtParsePara(shell, argv[1]), shellExtParsePara(shell, argv[2]),
|
||||
shellExtParsePara(shell, argv[3]), shellExtParsePara(shell, argv[4]),
|
||||
shellExtParsePara(shell, argv[5]));
|
||||
// break;
|
||||
case 7:
|
||||
return function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
|
||||
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]),
|
||||
shellExtParsePara(argv[5]), shellExtParsePara(argv[6]));
|
||||
return function(shellExtParsePara(shell, argv[1]), shellExtParsePara(shell, argv[2]),
|
||||
shellExtParsePara(shell, argv[3]), shellExtParsePara(shell, argv[4]),
|
||||
shellExtParsePara(shell, argv[5]), shellExtParsePara(shell, argv[6]));
|
||||
// break;
|
||||
case 8:
|
||||
return function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
|
||||
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]),
|
||||
shellExtParsePara(argv[5]), shellExtParsePara(argv[6]),
|
||||
shellExtParsePara(argv[7]));
|
||||
return function(shellExtParsePara(shell, argv[1]), shellExtParsePara(shell, argv[2]),
|
||||
shellExtParsePara(shell, argv[3]), shellExtParsePara(shell, argv[4]),
|
||||
shellExtParsePara(shell, argv[5]), shellExtParsePara(shell, argv[6]),
|
||||
shellExtParsePara(shell, argv[7]));
|
||||
// break;
|
||||
default:
|
||||
return -1;
|
@ -2,8 +2,8 @@
|
||||
* @file shell_ext.h
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief shell extensions
|
||||
* @version 1.0.0
|
||||
* @date 2019-01-05
|
||||
* @version 3.0.0
|
||||
* @date 2019-12-31
|
||||
*
|
||||
* @Copyright (c) 2019 Letter
|
||||
*
|
||||
@ -27,7 +27,7 @@ typedef enum
|
||||
NUM_TYPE_FLOAT /**< 浮点型 */
|
||||
} NUM_Type;
|
||||
|
||||
unsigned int shellExtParsePara(char *string);
|
||||
int shellExtRun(shellFunction function, int argc, char *argv[]);
|
||||
unsigned int shellExtParsePara(Shell *shell, char *string);
|
||||
int shellExtRun(Shell *shell, int (*function)(), int argc, char *argv[]);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user