mirror of
https://github.com/NevermindZZT/letter-shell.git
synced 2025-01-21 10:02:54 +08:00
commit
8c87c8cd22
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
CMakeFiles
|
||||
cmake_install.cmake
|
||||
CMakeCache.txt
|
||||
demo/x86-gcc/Makefile
|
139
README.md
139
README.md
@ -1,15 +1,15 @@
|
||||
# letter shell 3.0
|
||||
# letter shell 3.x
|
||||
|
||||
![version](https://img.shields.io/badge/version-3.0.6-brightgreen.svg)
|
||||
![version](https://img.shields.io/badge/version-3.1.0-brightgreen.svg)
|
||||
![standard](https://img.shields.io/badge/standard-c99-brightgreen.svg)
|
||||
![build](https://img.shields.io/badge/build-2020.11.29-brightgreen.svg)
|
||||
![build](https://img.shields.io/badge/build-2021.05.09-brightgreen.svg)
|
||||
![license](https://img.shields.io/badge/license-MIT-brightgreen.svg)
|
||||
|
||||
一个功能强大的嵌入式shell
|
||||
|
||||
![shell_info.png](doc/img/shell_info.png)
|
||||
|
||||
- [letter shell 3.0](#letter-shell-30)
|
||||
- [letter shell 3.x](#letter-shell-3x)
|
||||
- [简介](#简介)
|
||||
- [功能](#功能)
|
||||
- [移植说明](#移植说明)
|
||||
@ -26,23 +26,27 @@
|
||||
- [命令属性字段说明](#命令属性字段说明)
|
||||
- [代理函数和代理参数解析](#代理函数和代理参数解析)
|
||||
- [权限系统说明](#权限系统说明)
|
||||
- [锁说明](#锁说明)
|
||||
- [伴生对象](#伴生对象)
|
||||
- [尾行模式](#尾行模式)
|
||||
- [建议终端软件](#建议终端软件)
|
||||
- [命令遍历工具](#命令遍历工具)
|
||||
- [x86 demo](#x86-demo)
|
||||
|
||||
## 简介
|
||||
|
||||
[letter shell 3.0](https://github.com/NevermindZZT/letter-shell/tree/shell3.0)是一个C语言编写的,可以嵌入在程序中的嵌入式shell,主要面向嵌入式设备,以C语言函数为运行单位,可以通过命令行调用,运行程序中的函数
|
||||
[letter shell](https://github.com/NevermindZZT/letter-shell)是一个C语言编写的,可以嵌入在程序中的嵌入式shell,主要面向嵌入式设备,以C语言函数为运行单位,可以通过命令行调用,运行程序中的函数
|
||||
|
||||
相对2.x版本,letter shell 3.0增加了用户管理,权限管理,后续会增加对文件系统的支持
|
||||
相对2.x版本,letter shell 3.x增加了用户管理,权限管理,以及对文件系统的初步支持
|
||||
|
||||
此外3.0版本修改了命令格式和定义,2.x版本的工程需要经过简单的修改才能完成迁移
|
||||
此外3.x版本修改了命令格式和定义,2.x版本的工程需要经过简单的修改才能完成迁移
|
||||
|
||||
若只需要使用基础功能,可以使用[letter shell 2.x](https://github.com/NevermindZZT/letter-shell/tree/shell2.x)版本
|
||||
|
||||
使用说明可参考[Letter shell 3.0 全新出发](https://nevermindzzt.github.io/2020/01/19/Letter%20shell%203.0%E5%85%A8%E6%96%B0%E5%87%BA%E5%8F%91/)
|
||||
|
||||
如果从3.0版本迁移到3.1以上版本,请注意3.1版本对读写函数原型的修改
|
||||
|
||||
## 功能
|
||||
|
||||
- 命令自动补全
|
||||
@ -60,7 +64,9 @@
|
||||
Shell shell;
|
||||
```
|
||||
|
||||
2. 定义shell读,写函数,函数原型如下
|
||||
2. 定义shell读,写函数
|
||||
|
||||
对于使用letter shell 3.0版本,读写函数原型如下:
|
||||
|
||||
```C
|
||||
/**
|
||||
@ -81,6 +87,30 @@
|
||||
typedef void (*shellWrite)(const char);
|
||||
```
|
||||
|
||||
对于使用letter shell 3.1版本,为了优化效率,修改了读写函数原型,如下:
|
||||
|
||||
```C
|
||||
/**
|
||||
* @brief shell读取数据函数原型
|
||||
*
|
||||
* @param data shell读取的字符
|
||||
* @param len 请求读取的字符数量
|
||||
*
|
||||
* @return unsigned short 实际读取到的字符数量
|
||||
*/
|
||||
typedef unsigned short (*shellRead)(char *data, unsigned short len);
|
||||
|
||||
/**
|
||||
* @brief shell写数据函数原型
|
||||
*
|
||||
* @param data 需写的字符数据
|
||||
* @param len 需要写入的字符数
|
||||
*
|
||||
* @return unsigned short 实际写入的字符数量
|
||||
*/
|
||||
typedef unsigned short (*shellWrite)(const char *data, unsigned short len);
|
||||
```
|
||||
|
||||
3. 申请一片缓冲区
|
||||
|
||||
```C
|
||||
@ -108,7 +138,7 @@
|
||||
6. 说明
|
||||
|
||||
- 对于中断方式使用shell,不用定义`shell->read`,但需要在中断中调用`shellHandler`
|
||||
- 对于使用操作系统的情况,使能```SHEHLL_TASK_WHILE```宏,然后创建shellTask任务
|
||||
- 对于使用操作系统的情况,使能`SHEHLL_TASK_WHILE`宏,然后创建shellTask任务
|
||||
|
||||
7. 其他配置
|
||||
|
||||
@ -137,6 +167,7 @@
|
||||
| SHELL_DOUBLE_CLICK_TIME | 双击间隔(ms) |
|
||||
| SHELL_MAX_NUMBER | 管理的最大shell数量 |
|
||||
| SHELL_GET_TICK() | 获取系统时间(ms) |
|
||||
| SHELL_USING_LOCK | 是否使用锁 |
|
||||
| SHELL_MALLOC(size) | 内存分配函数(shell本身不需要) |
|
||||
| SHELL_FREE(obj) | 内存释放函数(shell本身不需要) |
|
||||
| SHELL_SHOW_INFO | 是否显示shell信息 |
|
||||
@ -149,7 +180,7 @@
|
||||
|
||||
### 函数定义
|
||||
|
||||
letter shell 3.0同时支持两种形式的函数定义方式,形如main函数定义的`func(int argc, char *agrv[])`以及形如普通C函数的定义`func(int i, char *str, ...)`,两种函数定义方式适用于不同的场景
|
||||
letter shell 3.x同时支持两种形式的函数定义方式,形如main函数定义的`func(int argc, char *agrv[])`以及形如普通C函数的定义`func(int i, char *str, ...)`,两种函数定义方式适用于不同的场景
|
||||
|
||||
#### main函数形式
|
||||
|
||||
@ -196,7 +227,7 @@ input int: 666, char: A, string: hello world
|
||||
|
||||
### 变量使用
|
||||
|
||||
letter shell 3.0支持导出变量,通过命令行查看,设置以及使用变量的值
|
||||
letter shell 3.x支持导出变量,通过命令行查看,设置以及使用变量的值
|
||||
|
||||
- 导出变量
|
||||
|
||||
@ -239,7 +270,7 @@ letter shell 3.0支持导出变量,通过命令行查看,设置以及使用
|
||||
|
||||
- 使用变量
|
||||
|
||||
letter shell 3.0的变量可以在命令中作为参数传递,对于需要传递结构体引用到命令中的场景特别适用,使用`$`+变量名的方式传递
|
||||
letter shell 3.x的变量可以在命令中作为参数传递,对于需要传递结构体引用到命令中的场景特别适用,使用`$`+变量名的方式传递
|
||||
|
||||
```sh
|
||||
letter:/$ shellPrint $shell "hello world\r\n"
|
||||
@ -260,7 +291,7 @@ letter shell支持通过函数地址直接执行函数,可以方便执行那
|
||||
|
||||
## 命令定义
|
||||
|
||||
letter shell 3.0将可执行的函数命令定义,用户定义,按键定义以及变量定义统一归为命令定义,使用相同的结构储存,查找和执行
|
||||
letter shell 3.x将可执行的函数命令定义,用户定义,按键定义以及变量定义统一归为命令定义,使用相同的结构储存,查找和执行
|
||||
|
||||
### 定义方式
|
||||
|
||||
@ -297,7 +328,7 @@ letter shell 支持使用命令导出方式和命令表方式进行命令的添
|
||||
|
||||
### 定义宏说明
|
||||
|
||||
letter shell 3.0对可执行命令,按键,用户以及变量分别提供了一个宏,用于进行命令定义
|
||||
letter shell 3.x对可执行命令,按键,用户以及变量分别提供了一个宏,用于进行命令定义
|
||||
|
||||
1. 可执行命令定义
|
||||
|
||||
@ -315,8 +346,8 @@ letter shell 3.0对可执行命令,按键,用户以及变量分别提供了
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellCommand##_name SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellCommand##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.cmd.name = shellCmd##_name, \
|
||||
@ -341,8 +372,8 @@ letter shell 3.0对可执行命令,按键,用户以及变量分别提供了
|
||||
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellVar##_name SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellVar##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.var.name = shellCmd##_name, \
|
||||
@ -370,8 +401,8 @@ letter shell 3.0对可执行命令,按键,用户以及变量分别提供了
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellPassword##_name[] = #_password; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellUser##_name SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellUser##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \
|
||||
.data.user.name = shellCmd##_name, \
|
||||
@ -395,8 +426,8 @@ letter shell 3.0对可执行命令,按键,用户以及变量分别提供了
|
||||
*/
|
||||
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \
|
||||
const char shellDesc##_value[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellKey##_value SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellKey##_value SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
|
||||
.data.key.value = _value, \
|
||||
@ -431,7 +462,7 @@ union
|
||||
|
||||
## 代理函数和代理参数解析
|
||||
|
||||
letter shell 3.0原生支持将整数,字符,字符串参数,以及在某些情况下的浮点参数直接传递给执行命令的函数,一般情况下,这几种参数类型完全可以满足调试需要,然而在某些情况下,用户确实需要传递其他类型的参数,此时,可以选择将命令定义成main函数形式,使用字符串传递参数,然后自行对参数进行解析,除此之外,letter shell还提供了代理函数的机制,可以对任意类型的参数进行自定义解析
|
||||
letter shell 3.x原生支持将整数,字符,字符串参数,以及在某些情况下的浮点参数直接传递给执行命令的函数,一般情况下,这几种参数类型完全可以满足调试需要,然而在某些情况下,用户确实需要传递其他类型的参数,此时,可以选择将命令定义成main函数形式,使用字符串传递参数,然后自行对参数进行解析,除此之外,letter shell还提供了代理函数的机制,可以对任意类型的参数进行自定义解析
|
||||
|
||||
关于代理函数的实现原理和具体使用示例,可以参考[letter-shell代理函数解析](https://nevermindzzt.github.io/2020/04/17/letter-shell%E4%BB%A3%E7%90%86%E5%87%BD%E6%95%B0%E8%A7%A3%E6%9E%90/)
|
||||
|
||||
@ -453,7 +484,51 @@ p1, SHELL_PARAM_FLOAT(p2), p3, SHELL_PARAM_FLOAT(p4));
|
||||
|
||||
## 权限系统说明
|
||||
|
||||
letter shell 3.0的权限管理同用户定义紧密相关,letter shell 3.0使用8个bit位表示命令权限,当用户和命令的权限按位与为真,或者命令权限为0时,表示该用户拥有此命令的权限,可以调用改命令
|
||||
letter shell 3.x的权限管理同用户定义紧密相关,letter shell 3.x使用8个bit位表示命令权限,当用户和命令的权限按位与为真,或者命令权限为0时,表示该用户拥有此命令的权限,可以调用该命令
|
||||
|
||||
## 锁说明
|
||||
|
||||
letter shell 3.1增加了shell锁,主要目的是为了防止shell输出和其他输入(比如说日志)对终端的竞争,导致输出混乱的现象,如果使用场景中没有出现终端输出混乱的情况,可以不使用shell锁
|
||||
|
||||
注意: 请使用支持嵌套的锁
|
||||
|
||||
1. 使能宏并实现锁
|
||||
|
||||
使能`SHELL_USING_LOCK`宏,实现shell上锁和解锁函数,函数原型如下:
|
||||
|
||||
```c
|
||||
/**
|
||||
* @brief shell上锁
|
||||
*
|
||||
* @param struct shell_def shell对象
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
typedef int (*shellLock)(struct shell_def *);
|
||||
|
||||
/**
|
||||
* @brief shell解锁
|
||||
*
|
||||
* @param struct shell_def shell对象
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
typedef int (*shellLock)(struct shell_def *);
|
||||
```
|
||||
|
||||
2. 使用锁
|
||||
|
||||
在可能产生终端竞争的地方,加上shell锁,比如如果调用`shellPrint`进行格式化输出
|
||||
|
||||
```C
|
||||
SHELL_LOCK(shell);
|
||||
shellPrint(shell, ...);
|
||||
SHELL_UNLOCK(shell);
|
||||
```
|
||||
|
||||
3. 注意
|
||||
|
||||
- 不要在shell命令中调用shell锁,除非实现的shell锁为可嵌套的锁
|
||||
|
||||
## 伴生对象
|
||||
|
||||
@ -467,7 +542,7 @@ letter shell 3.0.4版本新增了尾行模式,适用于需要在shell所使用
|
||||
|
||||
使用letter shell尾行模式结合[log](./extensions/log/readme.md)日志输出的效果如下:
|
||||
|
||||
![end lin mode](doc/img/shell_end_line_mode.gif)
|
||||
![end line mode](doc/img/shell_end_line_mode.gif)
|
||||
|
||||
## 建议终端软件
|
||||
|
||||
@ -475,10 +550,22 @@ letter shell 3.0.4版本新增了尾行模式,适用于需要在shell所使用
|
||||
|
||||
## 命令遍历工具
|
||||
|
||||
letter shell 3.0提供了一个用于遍历工程中命令导出的工具,位于tools/shellTools.py,需要python3环境运行,可以列出工程中,所有使用`SHELL_EXPORT_XXX`导出的命令名,以及位置,结合VS Code可以直接进行跳转
|
||||
letter shell 3.x提供了一个用于遍历工程中命令导出的工具,位于tools/shellTools.py,需要python3环境运行,可以列出工程中,所有使用`SHELL_EXPORT_XXX`导出的命令名,以及位置,结合VS Code可以直接进行跳转
|
||||
|
||||
```sh
|
||||
python shellTools.py project
|
||||
```
|
||||
|
||||
注意:shellTools会遍历指定目录中所有文件,所以当工程中文件较多时,速度会比较慢,建议只用于遍历用户模块的目录
|
||||
|
||||
## x86 demo
|
||||
|
||||
letter shell 3.x提供了一个x86的demo,可以直接编译运行,其中包含了一条按键键值测试命令,可以测试按键键值,用于快捷键的定义,编译运行方法如下:
|
||||
|
||||
```sh
|
||||
mv src/shell_cfg.h src/shell_cfg.h.bak
|
||||
cd demo/x86-gcc/
|
||||
cmake .
|
||||
make
|
||||
./LetterShell
|
||||
```
|
||||
|
@ -87,7 +87,7 @@
|
||||
|
||||
/**
|
||||
* @brief shell命令参数最大数量
|
||||
* 包含命令名在内,超过8个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
* 包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
*/
|
||||
#define SHELL_PARAMETER_MAX_NUMBER 8
|
||||
|
||||
|
@ -87,7 +87,7 @@
|
||||
|
||||
/**
|
||||
* @brief shell命令参数最大数量
|
||||
* 包含命令名在内,超过8个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
* 包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
*/
|
||||
#define SHELL_PARAMETER_MAX_NUMBER 8
|
||||
|
||||
|
25
demo/x86-gcc/CmakeLists.txt
Normal file
25
demo/x86-gcc/CmakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
project(LetterShell VERSION 0.1.0)
|
||||
|
||||
add_executable(LetterShell
|
||||
main.c
|
||||
shell_port.c
|
||||
shell_cpp.cpp
|
||||
../../src/shell.c
|
||||
../../src/shell_companion.c
|
||||
../../src/shell_ext.c
|
||||
../../extensions/fs_support/shell_fs.c
|
||||
../../extensions/log/log.c
|
||||
)
|
||||
|
||||
target_include_directories(LetterShell PUBLIC
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
../../src
|
||||
../../extensions/fs_support
|
||||
../../extensions/cpp_support
|
||||
../../extensions/log
|
||||
)
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T shell.lds")
|
@ -1,41 +0,0 @@
|
||||
all : mkdir out
|
||||
|
||||
out : main.o shell_port.o shell.o shell_ext.o shell_cmd_list.o shell_companion.o shell_fs.o shell_cmd_group.o shell_cpp.o
|
||||
gcc -o build/out -T shell.lds build/main.o build/shell_port.o \
|
||||
build/shell.o build/shell_ext.o build/shell_cmd_list.o \
|
||||
build/shell_companion.o build/shell_fs.o build/shell_cmd_group.o \
|
||||
build/shell_cpp.o
|
||||
|
||||
main.o : main.c shell_port.h
|
||||
gcc -c main.c -I ./ -I ../../src -o build/main.o
|
||||
|
||||
shell_port.o : shell_port.c ../../src/shell.h ../../extensions/fs_support/shell_fs.h
|
||||
gcc -c shell_port.c -I ./ -I ../../src -I ../../extensions/fs_support -o build/shell_port.o
|
||||
|
||||
shell.o : ../../src/shell.c ../../src/shell.h shell_cfg.h
|
||||
gcc -c ../../src/shell.c -I ./ -I ../../src -o build/shell.o
|
||||
|
||||
shell_ext.o : ../../src/shell_ext.c ../../src/shell_ext.h ../../src/shell.h shell_cfg.h
|
||||
gcc -c ../../src/shell_ext.c -I ./ -I ../../src -o build/shell_ext.o
|
||||
|
||||
shell_cmd_list.o : ../../src/shell_cmd_list.c ../../src/shell.h shell_cfg.h
|
||||
gcc -c ../../src/shell_cmd_list.c -I ./ -I ../../src -o build/shell_cmd_list.o
|
||||
|
||||
shell_companion.o : ../../src/shell_companion.c ../../src/shell.h shell_cfg.h
|
||||
gcc -c ../../src/shell_companion.c -I ./ -I ../../src -o build/shell_companion.o
|
||||
|
||||
shell_fs.o : ../../extensions/fs_support/shell_fs.c ../../extensions/fs_support/shell_fs.h shell_cfg.h ../../src/shell.h
|
||||
gcc -c ../../extensions/fs_support/shell_fs.c -I ./ -I ../../src -I ../../extensions/fs_support -o build/shell_fs.o
|
||||
|
||||
shell_cmd_group.o : ../../extensions/shell_enhance/shell_cmd_group.c ../../extensions/shell_enhance/shell_cmd_group.h shell_cfg.h ../../src/shell.h
|
||||
gcc -c ../../extensions/shell_enhance/shell_cmd_group.c -I ./ -I ../../src -I ../../extensions/shell_enhance -o build/shell_cmd_group.o
|
||||
|
||||
shell_cpp.o : shell_cpp.cpp ../../extensions/cpp_support/shell_cpp.h
|
||||
g++ -c shell_cpp.cpp -I ./ -I ../../src -I ../../extensions/cpp_support -o build/shell_cpp.o
|
||||
|
||||
.PHONY : all clean mkdir
|
||||
clean :
|
||||
-rm -r build
|
||||
|
||||
mkdir :
|
||||
if [ ! -d "build" ]; then (mkdir build) fi
|
@ -126,6 +126,12 @@
|
||||
*/
|
||||
#define SHELL_GET_TICK() 0
|
||||
|
||||
/**
|
||||
* @brief 使用锁
|
||||
* @note 使用shell锁时,需要对加锁和解锁进行实现
|
||||
*/
|
||||
#define SHELL_USING_LOCK 0
|
||||
|
||||
/**
|
||||
* @brief shell内存分配
|
||||
* shell本身不需要此接口,若使用shell伴生对象,需要进行定义
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "shell.h"
|
||||
#include "shell_fs.h"
|
||||
#include "log.h"
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
@ -21,15 +22,39 @@ Shell shell;
|
||||
char shellBuffer[512];
|
||||
ShellFs shellFs;
|
||||
char shellPathBuffer[512] = "/";
|
||||
Log log = {
|
||||
.active = 1,
|
||||
.level = LOG_DEBUG
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 日志写函数实现
|
||||
*
|
||||
* @param buffer 数据
|
||||
* @param len 数据长度
|
||||
*
|
||||
*/
|
||||
void terminalLogWrite(char *buffer, short len)
|
||||
{
|
||||
if (log.shell)
|
||||
{
|
||||
shellWriteEndLine(log.shell, buffer, len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 用户shell写
|
||||
*
|
||||
* @param data 数据
|
||||
*/
|
||||
void userShellWrite(char data)
|
||||
unsigned short userShellWrite(char *data, unsigned short len)
|
||||
{
|
||||
putchar(data);
|
||||
unsigned short length = len;
|
||||
while (length--)
|
||||
{
|
||||
putchar(*data++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,16 +63,36 @@ void userShellWrite(char data)
|
||||
* @param data 数据
|
||||
* @return char 状态
|
||||
*/
|
||||
signed char userShellRead(char *data)
|
||||
unsigned short userShellRead(char *data, unsigned short len)
|
||||
{
|
||||
unsigned short length = len;
|
||||
system("stty -echo");
|
||||
system("stty -icanon");
|
||||
*data = getchar();
|
||||
while (length--)
|
||||
{
|
||||
*data++ = getchar();
|
||||
}
|
||||
system("stty icanon");
|
||||
system("stty echo");
|
||||
return len;
|
||||
}
|
||||
|
||||
#if SHELL_USING_LOCK == 1
|
||||
static int lockCount = 0;
|
||||
int userShellLock(struct shell_def *shell)
|
||||
{
|
||||
printf("lock: %d\r\n", lockCount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int userShellUnlock(struct shell_def *shell)
|
||||
{
|
||||
printf("unlock: %d\r\n", lockCount);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 列出文件
|
||||
*
|
||||
@ -85,9 +130,19 @@ void userShellInit(void)
|
||||
|
||||
shell.write = userShellWrite;
|
||||
shell.read = userShellRead;
|
||||
#if SHELL_USING_LOCK == 1
|
||||
shell.lock = userShellLock;
|
||||
shell.unlock = userShellUnlock;
|
||||
#endif
|
||||
shellSetPath(&shell, shellPathBuffer);
|
||||
shellInit(&shell, shellBuffer, 512);
|
||||
shellCompanionAdd(&shell, SHELL_COMPANION_ID_FS, &shellFs);
|
||||
|
||||
log.write = terminalLogWrite;
|
||||
logRegister(&log, &shell);
|
||||
|
||||
logDebug("hello world");
|
||||
logHexDump(LOG_ALL_OBJ, LOG_DEBUG, (void *)&shell, sizeof(shell));
|
||||
}
|
||||
|
||||
|
||||
@ -138,7 +193,7 @@ void shellKeyTest(void)
|
||||
SHELL_ASSERT(shell && shell->read, return);
|
||||
while (1)
|
||||
{
|
||||
if (shell->read(&data) == 0)
|
||||
if (shell->read(&data, 1) == 1)
|
||||
{
|
||||
if (data == '\n' || data == '\r')
|
||||
{
|
||||
|
@ -74,8 +74,8 @@ typedef struct shell_command_cpp_key
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
extern "C" const ShellCommandCppCmd \
|
||||
shellCommand##_name SECTION("shellCommand") = \
|
||||
extern "C" SHELL_USED const ShellCommandCppCmd \
|
||||
shellCommand##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
_attr, \
|
||||
shellCmd##_name, \
|
||||
@ -95,8 +95,8 @@ typedef struct shell_command_cpp_key
|
||||
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
extern "C" const ShellCommandCppVar \
|
||||
shellVar##_name SECTION("shellCommand") = \
|
||||
extern "C" SHELL_USED const ShellCommandCppVar \
|
||||
shellVar##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
_attr, \
|
||||
shellCmd##_name, \
|
||||
@ -117,8 +117,8 @@ typedef struct shell_command_cpp_key
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellPassword##_name[] = #_password; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
extern "C" const ShellCommandCppUser \
|
||||
shellUser##_name SECTION("shellCommand") = \
|
||||
extern "C" SHELL_USED const ShellCommandCppUser \
|
||||
shellUser##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
_attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \
|
||||
shellCmd##_name, \
|
||||
@ -137,9 +137,9 @@ typedef struct shell_command_cpp_key
|
||||
*/
|
||||
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \
|
||||
const char shellDesc##_value[] = #_desc; \
|
||||
extern "C" const ShellCommandCppKey \
|
||||
shellKey##_value SECTION("shellCommand") = \
|
||||
{ \
|
||||
extern "C" SHELL_USED const ShellCommandCppKey \
|
||||
shellKey##_value SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
_attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
|
||||
_value, \
|
||||
(void (*)(Shell *))_func, \
|
||||
|
@ -16,10 +16,11 @@
|
||||
#if LOG_USING_COLOR == 1
|
||||
#define memPrintHead CSI(31) \
|
||||
" Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" \
|
||||
CSI(39)
|
||||
CSI(39) \
|
||||
"\r\n"
|
||||
#define memPrintAddr CSI(31)"0x%08x: "CSI(39)
|
||||
#else
|
||||
#define memPrintHead " Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"
|
||||
#define memPrintHead " Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n"
|
||||
#define memPrintAddr "0x%08x: "
|
||||
#endif
|
||||
|
||||
@ -92,7 +93,7 @@ logSetLevel, logSetLevel, set log level);
|
||||
* @param buffer buffer
|
||||
* @param len buffer长度
|
||||
*/
|
||||
void logWriteBuffer(Log *log, LogLevel level, char *buffer, short len)
|
||||
static void logWriteBuffer(Log *log, LogLevel level, char *buffer, short len)
|
||||
{
|
||||
if (log == LOG_ALL_OBJ)
|
||||
{
|
||||
@ -137,27 +138,30 @@ void logWrite(Log *log, LogLevel level, char *fmt, ...)
|
||||
* @brief 16进制输出
|
||||
*
|
||||
* @param log log对象
|
||||
* @param level 日志级别
|
||||
* @param base 内存基址
|
||||
* @param length 长度
|
||||
*/
|
||||
void logHexDump(Log *log, void *base, unsigned int length)
|
||||
void logHexDump(Log *log, LogLevel level, void *base, unsigned int length)
|
||||
{
|
||||
unsigned char *address;
|
||||
unsigned int len = length;
|
||||
unsigned int len;
|
||||
unsigned int printLen = 0;
|
||||
|
||||
if (length == 0)
|
||||
if (length == 0 || (log != LOG_ALL_OBJ && log->level < level))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
logWrite(log, LOG_NONE, "memory of 0x%08x, size: %d:\r\n", (unsigned int)base, length);
|
||||
len = snprintf(logBuffer, LOG_BUFFER_SIZE - 1, "memory of 0x%08x, size: %d:\r\n%s",
|
||||
(unsigned int)base, length, memPrintHead);
|
||||
logWriteBuffer(log, level, logBuffer, len);
|
||||
|
||||
address = (unsigned char *)((unsigned int)base & (~0x0000000F));
|
||||
length += (unsigned int)base - (unsigned int)address;
|
||||
length = (length + 15) & (~0x0000000F);
|
||||
|
||||
logWrite(log, LOG_NONE, memPrintHead"\r\n");
|
||||
len = length;
|
||||
|
||||
while (length)
|
||||
{
|
||||
@ -200,15 +204,22 @@ void logHexDump(Log *log, void *base, unsigned int length)
|
||||
logBuffer[printLen ++] = '|';
|
||||
logBuffer[printLen ++] = '\r';
|
||||
logBuffer[printLen ++] = '\n';
|
||||
logWriteBuffer(log, LOG_NONE, logBuffer, printLen);
|
||||
logWriteBuffer(log, level, logBuffer, printLen);
|
||||
address += 16;
|
||||
length -= 16;
|
||||
printLen = 0;
|
||||
}
|
||||
}
|
||||
#if SHELL_USING_COMPANION == 1
|
||||
SHELL_EXPORT_CMD_AGENCY(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
|
||||
hexdump, logHexDump, hex dump\r\n hexdump [base] [len],
|
||||
(void *)shellCompanionGet(shellGetCurrent(), SHELL_COMPANION_ID_LOG), LOG_NONE, p1, p2);
|
||||
#else
|
||||
SHELL_EXPORT_CMD(
|
||||
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
|
||||
hexdump, logHexDump, hex dump\r\n hexdump [log] [base] [len]);
|
||||
hexdump, logHexDump, hex dump\r\n hexdump [log] [level] [base] [len]);
|
||||
#endif /** SHELL_USING_COMPANION == 1 */
|
||||
|
||||
#if SHELL_USING_COMPANION == 1
|
||||
void logSwitchLevel(Shell *shell)
|
||||
@ -219,5 +230,4 @@ void logSwitchLevel(Shell *shell)
|
||||
logPrintln("set log level: %d", log->level);
|
||||
}
|
||||
SHELL_EXPORT_KEY(SHELL_CMD_PERMISSION(0), 0x04000000, logSwitchLevel, switch log level);
|
||||
|
||||
#endif /** SHELL_USING_COMPANION == 1 */
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
#define LOG_VERSION "1.0.0"
|
||||
#define LOG_VERSION "1.0.1"
|
||||
|
||||
#define SHELL_COMPANION_ID_LOG -2
|
||||
|
||||
@ -182,10 +182,19 @@ typedef struct
|
||||
action; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 16进制输出到所有终端
|
||||
*
|
||||
* @param base 内存基址
|
||||
* @param length 长度
|
||||
*/
|
||||
#define logHexDumpAll(base, length) \
|
||||
logHexDump(LOG_ALL_OBJ, LOG_ALL, base, length)
|
||||
|
||||
void logRegister(Log *log, Shell *shell);
|
||||
void logUnRegister(Log *log);
|
||||
void logSetLevel(Log *log, LogLevel level);
|
||||
void logWrite(Log *log, LogLevel level, char *fmt, ...);
|
||||
void logHexDump(Log *log, void *base, unsigned int length);
|
||||
void logHexDump(Log *log, LogLevel level, void *base, unsigned int length);
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
# log
|
||||
|
||||
![version](https://img.shields.io/badge/version-1.0.0-brightgreen.svg)
|
||||
![version](https://img.shields.io/badge/version-1.0.1-brightgreen.svg)
|
||||
![standard](https://img.shields.io/badge/standard-c99-brightgreen.svg)
|
||||
![build](https://img.shields.io/badge/build-2020.08.02-brightgreen.svg)
|
||||
![license](https://img.shields.io/badge/license-MIT-brightgreen.svg)
|
||||
@ -160,11 +160,12 @@ void logSetLevel(Log *log, LogLevel level)
|
||||
数据16进制打印
|
||||
|
||||
```C
|
||||
void logHexDump(Log *log, void *base, unsigned int length)
|
||||
void logHexDump(Log *log, LogLevel level, void *base, unsigned int length)
|
||||
```
|
||||
|
||||
- 参数
|
||||
- `log` log对象
|
||||
- `level` 日志级别
|
||||
- `base` 数据基址
|
||||
- `length` 数据长度
|
||||
|
||||
|
57
src/shell.c
57
src/shell.c
@ -22,7 +22,7 @@
|
||||
const char shellCmdDefaultUser[] = SHELL_DEFAULT_USER;
|
||||
const char shellPasswordDefaultUser[] = SHELL_DEFAULT_USER_PASSWORD;
|
||||
const char shellDesDefaultUser[] = "default user";
|
||||
const ShellCommand shellUserDefault SECTION("shellCommand") =
|
||||
SHELL_USED const ShellCommand shellUserDefault SHELL_SECTION("shellCommand") =
|
||||
{
|
||||
.attr.value = SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_USER),
|
||||
.data.user.name = shellCmdDefaultUser,
|
||||
@ -260,7 +260,7 @@ Shell* shellGetCurrent(void)
|
||||
*/
|
||||
static void shellWriteByte(Shell *shell, const char data)
|
||||
{
|
||||
shell->write(data);
|
||||
shell->write(&data, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -275,13 +275,13 @@ static void shellWriteByte(Shell *shell, const char data)
|
||||
unsigned short shellWriteString(Shell *shell, const char *string)
|
||||
{
|
||||
unsigned short count = 0;
|
||||
char *p = string;
|
||||
SHELL_ASSERT(shell->write, return 0);
|
||||
while(*string)
|
||||
while(*p++)
|
||||
{
|
||||
shell->write(*string ++);
|
||||
count ++;
|
||||
}
|
||||
return count;
|
||||
return shell->write(string, count);
|
||||
}
|
||||
|
||||
|
||||
@ -296,22 +296,24 @@ unsigned short shellWriteString(Shell *shell, const char *string)
|
||||
static unsigned short shellWriteCommandDesc(Shell *shell, const char *string)
|
||||
{
|
||||
unsigned short count = 0;
|
||||
char *p = string;
|
||||
SHELL_ASSERT(shell->write, return 0);
|
||||
while(*string
|
||||
&& *string != '\r'
|
||||
&& *string != '\n'
|
||||
&& count < 36)
|
||||
while (*p && *p != '\r' && *p != '\n')
|
||||
{
|
||||
shell->write(*string ++);
|
||||
count ++;
|
||||
if (count >= 36 && *(string + 1))
|
||||
{
|
||||
shell->write('.');
|
||||
shell->write('.');
|
||||
shell->write('.');
|
||||
}
|
||||
p++;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
|
||||
if (count > 36)
|
||||
{
|
||||
shell->write(string, 36);
|
||||
shell->write("...", 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
shell->write(string, count);
|
||||
}
|
||||
return count > 36 ? 36 : 39;
|
||||
}
|
||||
|
||||
|
||||
@ -385,9 +387,9 @@ void shellScan(Shell *shell, char *fmt, ...)
|
||||
if (shell->read)
|
||||
{
|
||||
do {
|
||||
if (shell->read(&buffer[index]) == 0)
|
||||
if (shell->read(&buffer[index], 1) == 1)
|
||||
{
|
||||
shell->write(buffer[index]);
|
||||
shell->write(buffer[index], 1);
|
||||
index++;
|
||||
}
|
||||
} while (buffer[index -1] != '\r' && buffer[index -1] != '\n' && index < SHELL_SCAN_BUFFER);
|
||||
@ -1660,6 +1662,7 @@ help, shellHelp, show command info\r\nhelp [cmd]);
|
||||
void shellHandler(Shell *shell, char data)
|
||||
{
|
||||
SHELL_ASSERT(data, return);
|
||||
SHELL_LOCK(shell);
|
||||
|
||||
#if SHELL_LOCK_TIMEOUT > 0
|
||||
if (shell->info.user->data.user.password
|
||||
@ -1732,20 +1735,20 @@ void shellHandler(Shell *shell, char data)
|
||||
{
|
||||
shell->info.activeTime = SHELL_GET_TICK();
|
||||
}
|
||||
SHELL_UNLOCK(shell);
|
||||
}
|
||||
|
||||
|
||||
#if SHELL_SUPPORT_END_LINE == 1
|
||||
void shellWriteEndLine(Shell *shell, char *buffer, int len)
|
||||
{
|
||||
SHELL_LOCK(shell);
|
||||
if (!shell->status.isActive)
|
||||
{
|
||||
shellWriteString(shell, shellText[SHELL_TEXT_CLEAR_LINE]);
|
||||
}
|
||||
while (len --)
|
||||
{
|
||||
shell->write(*buffer++);
|
||||
}
|
||||
shell->write(buffer, len);
|
||||
|
||||
if (!shell->status.isActive)
|
||||
{
|
||||
shellWriteCommandLine(shell, 0);
|
||||
@ -1754,10 +1757,11 @@ void shellWriteEndLine(Shell *shell, char *buffer, int len)
|
||||
shellWriteString(shell, shell->parser.buffer);
|
||||
for (short i = 0; i < shell->parser.length - shell->parser.cursor; i++)
|
||||
{
|
||||
shell->write('\b');
|
||||
shell->write('\b', 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
SHELL_UNLOCK(shell);
|
||||
}
|
||||
#endif /** SHELL_SUPPORT_END_LINE == 1 */
|
||||
|
||||
@ -1776,7 +1780,7 @@ void shellTask(void *param)
|
||||
while(1)
|
||||
{
|
||||
#endif
|
||||
if (shell->read && shell->read(&data) == 0)
|
||||
if (shell->read && shell->read(&data, 1) == 1)
|
||||
{
|
||||
shellHandler(shell, data);
|
||||
}
|
||||
@ -1906,7 +1910,6 @@ int shellExecute(int argc, char *argv[])
|
||||
if (shell && argc >= 2)
|
||||
{
|
||||
int (*func)() = (int (*)())shellExtParsePara(shell, argv[1]);
|
||||
shellPrint(shell, "%08x\r\n", func);
|
||||
ShellCommand command = {
|
||||
.attr.value = SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)
|
||||
|SHELL_CMD_DISABLE_RETURN,
|
||||
|
59
src/shell.h
59
src/shell.h
@ -14,7 +14,7 @@
|
||||
|
||||
#include "shell_cfg.h"
|
||||
|
||||
#define SHELL_VERSION "3.0.6" /**< 版本号 */
|
||||
#define SHELL_VERSION "3.1.0" /**< 版本号 */
|
||||
|
||||
|
||||
/**
|
||||
@ -28,6 +28,13 @@
|
||||
action; \
|
||||
}
|
||||
|
||||
#if SHELL_USING_LOCK == 1
|
||||
#define SHELL_LOCK(shell) shell->lock(shell)
|
||||
#define SHELL_UNLOCK(shell) shell->unlock(shell)
|
||||
#else
|
||||
#define SHELL_LOCK(shell)
|
||||
#define SHELL_UNLOCK(shell)
|
||||
#endif /** SHELL_USING_LOCK == 1 */
|
||||
/**
|
||||
* @brief shell 命令权限
|
||||
*
|
||||
@ -68,15 +75,27 @@
|
||||
#define SHELL_CMD_PARAM_NUM(num) \
|
||||
((num & 0x0000000F)) << 16
|
||||
|
||||
#ifndef SECTION
|
||||
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000)
|
||||
#define SECTION(x) __attribute__((used, section(x)))
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__)
|
||||
#define SECTION(x) @ x
|
||||
#ifndef SHELL_SECTION
|
||||
#if defined(__CC_ARM) || defined(__CLANG_ARM)
|
||||
#define SHELL_SECTION(x) __attribute__((section(x)))
|
||||
#elif defined (__IAR_SYSTEMS_ICC__)
|
||||
#define SHELL_SECTION(x) @ x
|
||||
#elif defined(__GNUC__)
|
||||
#define SECTION(x) __attribute__((section(x)))
|
||||
#define SHELL_SECTION(x) __attribute__((section(x)))
|
||||
#else
|
||||
#define SECTION(x)
|
||||
#define SHELL_SECTION(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SHELL_USED
|
||||
#if defined(__CC_ARM) || defined(__CLANG_ARM)
|
||||
#define SHELL_USED __attribute__((used))
|
||||
#elif defined (__IAR_SYSTEMS_ICC__)
|
||||
#define SHELL_USED __root
|
||||
#elif defined(__GNUC__)
|
||||
#define SHELL_USED __attribute__((used))
|
||||
#else
|
||||
#define SHELL_USED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -113,8 +132,8 @@
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellCommand##_name SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellCommand##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.cmd.name = shellCmd##_name, \
|
||||
@ -146,8 +165,8 @@
|
||||
#define SHELL_EXPORT_VAR(_attr, _name, _value, _desc) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellVar##_name SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellVar##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr, \
|
||||
.data.var.name = shellCmd##_name, \
|
||||
@ -167,8 +186,8 @@
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellPassword##_name[] = #_password; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellUser##_name SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellUser##_name SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_USER), \
|
||||
.data.user.name = shellCmd##_name, \
|
||||
@ -186,8 +205,8 @@
|
||||
*/
|
||||
#define SHELL_EXPORT_KEY(_attr, _value, _func, _desc) \
|
||||
const char shellDesc##_value[] = #_desc; \
|
||||
const ShellCommand \
|
||||
shellKey##_value SECTION("shellCommand") = \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellKey##_value SHELL_SECTION("shellCommand") = \
|
||||
{ \
|
||||
.attr.value = _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \
|
||||
.data.key.value = _value, \
|
||||
@ -340,8 +359,12 @@ typedef struct shell_def
|
||||
unsigned char isActive : 1; /**< 当前活动Shell */
|
||||
unsigned char tabFlag : 1; /**< tab标志 */
|
||||
} status;
|
||||
signed char (*read)(char *); /**< shell读函数 */
|
||||
void (*write)(const char); /**< shell写函数 */
|
||||
signed short (*read)(char *, unsigned short); /**< shell读函数 */
|
||||
signed short (*write)(const char *, unsigned short); /**< shell写函数 */
|
||||
#if SHELL_USING_LOCK == 1
|
||||
int (*lock)(struct shell_def *); /**< shell 加锁 */
|
||||
int (*unlock)(struct shell_def *); /**< shell 解锁 */
|
||||
#endif
|
||||
} Shell;
|
||||
|
||||
|
||||
|
@ -85,7 +85,7 @@
|
||||
|
||||
/**
|
||||
* @brief shell命令参数最大数量
|
||||
* 包含命令名在内,超过8个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
* 包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
*/
|
||||
#define SHELL_PARAMETER_MAX_NUMBER 8
|
||||
|
||||
@ -125,6 +125,12 @@
|
||||
*/
|
||||
#define SHELL_GET_TICK() 0
|
||||
|
||||
/**
|
||||
* @brief 使用锁
|
||||
* @note 使用shell锁时,需要对加锁和解锁进行实现
|
||||
*/
|
||||
#define SHELL_USING_LOCK 0
|
||||
|
||||
/**
|
||||
* @brief shell内存分配
|
||||
* shell本身不需要此接口,若使用shell伴生对象,需要进行定义
|
||||
|
Loading…
x
Reference in New Issue
Block a user