Support XiZi_AIoT
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
SRC_DIR := letter-shell
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Letter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,27 @@
|
||||
toolchain ?= arm-none-eabi-
|
||||
cc = ${toolchain}gcc
|
||||
ld = ${toolchain}g++
|
||||
objdump = ${toolchain}objdump
|
||||
# user_ldflags = -N -Ttext 0
|
||||
|
||||
cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie -no-pie
|
||||
c_useropts = -O0
|
||||
|
||||
INC_DIR = -I$(KERNEL_ROOT)/services/boards/imx6q-sabrelite -I$(KERNEL_ROOT)/services/lib/ipc -I$(KERNEL_ROOT)/services/fs/include
|
||||
|
||||
all: shell_cmd_list.o shell_ext.o shell.o
|
||||
@mv shell_cmd_list.o ../../boards/imx6q-sabrelite
|
||||
@mv shell_ext.o ../../boards/imx6q-sabrelite
|
||||
@mv shell.o ../../boards/imx6q-sabrelite
|
||||
|
||||
shell_cmd_list.o: shell_cmd_list.c
|
||||
@echo "cc shell_cmd_list"
|
||||
@${cc} ${cflags} ${c_useropts} -o $@ -c $<
|
||||
|
||||
shell_ext.o: shell_ext.c
|
||||
@echo "cc shell_ext"
|
||||
@${cc} ${cflags} ${c_useropts} -o $@ -c $<
|
||||
|
||||
shell.o: shell.c
|
||||
@echo "cc shell"
|
||||
@${cc} ${cflags} ${c_useropts} ${INC_DIR} -o $@ -c $<
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,558 @@
|
||||
/**
|
||||
* @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.2.3" /**< 版本号 */
|
||||
|
||||
/**
|
||||
* @brief data 断言
|
||||
*
|
||||
* @param data 接收数据
|
||||
* @param action 断言失败操作
|
||||
*/
|
||||
#define CHECK_DATA(data, action) \
|
||||
if (data == 0xFF) { \
|
||||
action; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 断言
|
||||
*
|
||||
* @param expr 表达式
|
||||
* @param action 断言失败操作
|
||||
*/
|
||||
#define SHELL_ASSERT(expr, action) \
|
||||
if (!(expr)) { \
|
||||
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 命令权限
|
||||
*
|
||||
* @param permission 权限级别
|
||||
*/
|
||||
#define SHELL_CMD_PERMISSION(permission) \
|
||||
(permission & 0x000000FF)
|
||||
|
||||
/**
|
||||
* @brief shell 命令类型
|
||||
*
|
||||
* @param type 类型
|
||||
*/
|
||||
#define SHELL_CMD_TYPE(type) \
|
||||
((type & 0x0000000F) << 8)
|
||||
|
||||
/**
|
||||
* @brief 使能命令在未校验密码的情况下使用
|
||||
*/
|
||||
#define SHELL_CMD_ENABLE_UNCHECKED \
|
||||
(1 << 12)
|
||||
|
||||
/**
|
||||
* @brief 禁用返回值打印
|
||||
*/
|
||||
#define SHELL_CMD_DISABLE_RETURN \
|
||||
(1 << 13)
|
||||
|
||||
/**
|
||||
* @brief 只读属性(仅对变量生效)
|
||||
*/
|
||||
#define SHELL_CMD_READ_ONLY \
|
||||
(1 << 14)
|
||||
|
||||
/**
|
||||
* @brief 命令参数数量
|
||||
*/
|
||||
#define SHELL_CMD_PARAM_NUM(num) \
|
||||
((num & 0x0000000F)) << 16
|
||||
|
||||
#ifndef SHELL_SECTION
|
||||
#if defined(__CC_ARM) || defined(__CLANG_ARM)
|
||||
#define SHELL_SECTION(x) __attribute__((section(x), aligned(1)))
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#define SHELL_SECTION(x) @x
|
||||
#elif defined(__GNUC__)
|
||||
#define SHELL_SECTION(x) __attribute__((section(x), aligned(1)))
|
||||
#else
|
||||
#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
|
||||
|
||||
/**
|
||||
* @brief shell float型参数转换
|
||||
*/
|
||||
#define SHELL_PARAM_FLOAT(x) (*(float*)(&x))
|
||||
|
||||
/**
|
||||
* @brief shell 代理函数名
|
||||
*/
|
||||
#define SHELL_AGENCY_FUNC_NAME(_func) agency##_func
|
||||
|
||||
/**
|
||||
* @brief shell代理函数定义
|
||||
*
|
||||
* @param _func 被代理的函数
|
||||
* @param ... 代理参数
|
||||
*/
|
||||
#define SHELL_AGENCY_FUNC(_func, ...) \
|
||||
void SHELL_AGENCY_FUNC_NAME(_func)(int p1, int p2, int p3, int p4, int p5, int p6, int p7) \
|
||||
{ \
|
||||
_func(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#if SHELL_USING_CMD_EXPORT == 1
|
||||
|
||||
/**
|
||||
* @brief shell 命令定义
|
||||
*
|
||||
* @param _attr 命令属性
|
||||
* @param _name 命令名
|
||||
* @param _func 命令函数
|
||||
* @param _desc 命令描述
|
||||
* @param ... 其他参数
|
||||
*/
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc, ...) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellCommand##_name SHELL_SECTION("shellCommand") \
|
||||
= { \
|
||||
.attr.value = _attr, \
|
||||
.data.cmd.name = shellCmd##_name, \
|
||||
.data.cmd.function = (int (*)())_func, \
|
||||
.data.cmd.desc = shellDesc##_name, \
|
||||
##__VA_ARGS__ \
|
||||
}
|
||||
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
/**
|
||||
* @brief shell 命令定义
|
||||
*
|
||||
* @param _attr 命令属性
|
||||
* @param _name 命令名
|
||||
* @param _func 命令函数
|
||||
* @param _desc 命令描述
|
||||
* @param _sign 命令签名
|
||||
*/
|
||||
#define SHELL_EXPORT_CMD_SIGN(_attr, _name, _func, _desc, _sign) \
|
||||
const char shellCmd##_name[] = #_name; \
|
||||
const char shellDesc##_name[] = #_desc; \
|
||||
const char shellSign##_name[] = #_sign; \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellCommand##_name SHELL_SECTION("shellCommand") \
|
||||
= { \
|
||||
.attr.value = _attr, \
|
||||
.data.cmd.name = shellCmd##_name, \
|
||||
.data.cmd.function = (int (*)())_func, \
|
||||
.data.cmd.desc = shellDesc##_name, \
|
||||
.data.cmd.signature = shellSign##_name \
|
||||
}
|
||||
#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */
|
||||
|
||||
/**
|
||||
* @brief shell 代理命令定义
|
||||
*
|
||||
* @param _attr 命令属性
|
||||
* @param _name 命令名
|
||||
* @param _func 命令函数
|
||||
* @param _desc 命令描述
|
||||
* @param ... 代理参数
|
||||
*/
|
||||
#define SHELL_EXPORT_CMD_AGENCY(_attr, _name, _func, _desc, ...) \
|
||||
SHELL_AGENCY_FUNC(_func, ##__VA_ARGS__) \
|
||||
SHELL_EXPORT_CMD(_attr, _name, SHELL_AGENCY_FUNC_NAME(_func), _desc)
|
||||
|
||||
/**
|
||||
* @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; \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellVar##_name SHELL_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; \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellUser##_name SHELL_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; \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellKey##_value SHELL_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 \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief shell 代理按键定义
|
||||
*
|
||||
* @param _attr 按键属性
|
||||
* @param _value 按键键值
|
||||
* @param _func 按键函数
|
||||
* @param _desc 按键描述
|
||||
* @param ... 代理参数
|
||||
*/
|
||||
#define SHELL_EXPORT_KEY_AGENCY(_attr, _value, _func, _desc, ...) \
|
||||
SHELL_AGENCY_FUNC(_func, ##__VA_ARGS__) \
|
||||
SHELL_EXPORT_KEY(_attr, _value, SHELL_AGENCY_FUNC_NAME(_func), _desc)
|
||||
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
/**
|
||||
* @brief shell 参数解析器定义
|
||||
*
|
||||
* @param _attr 参数解析器属性
|
||||
* @param _type 参数解析器类型
|
||||
* @param _parser 参数解析器函数
|
||||
* @param _cleaner 参数清理器
|
||||
*/
|
||||
#define SHELL_EXPORT_PARAM_PARSER(_attr, _type, _parser, _cleaner) \
|
||||
const char shellDesc##_parser[] = #_type; \
|
||||
SHELL_USED const ShellCommand \
|
||||
shellCommand##_parser SHELL_SECTION("shellCommand") \
|
||||
= { \
|
||||
.attr.value = _attr | SHELL_CMD_TYPE(SHELL_TYPE_PARAM_PARSER), \
|
||||
.data.paramParser.type = shellDesc##_parser, \
|
||||
.data.paramParser.parser = (int (*)(char*, void**))_parser, \
|
||||
.data.paramParser.cleaner = (int (*)(void*))_cleaner \
|
||||
}
|
||||
#endif
|
||||
|
||||
#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 \
|
||||
}
|
||||
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
/**
|
||||
* @brief shell 参数解析器item定义
|
||||
*
|
||||
* @param _attr 参数解析器属性
|
||||
* @param _type 参数解析器类型
|
||||
* @param _parser 参数解析器函数
|
||||
* @param _cleaner 参数清理器
|
||||
*/
|
||||
#define SHELL_PARAM_PARSER_ITEM(_attr, _type, _parser, _cleaner) \
|
||||
{ \
|
||||
.attr.value = _attr | SHELL_CMD_TYPE(SHELL_TYPE_PARAM_PARSER), \
|
||||
.data.paramParser.type = #_type, \
|
||||
.data.paramParser.parser = (int (*)(char*, void**))_parser, \
|
||||
.data.paramParser.cleaner = (int (*)(void*))_cleaner \
|
||||
}
|
||||
#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */
|
||||
|
||||
#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc)
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
#define SHELL_EXPORT_CMD_SIGN(_attr, _name, _func, _desc, _sign)
|
||||
#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */
|
||||
#define SHELL_EXPORT_CMD_AGENCY(_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)
|
||||
#define SHELL_EXPORT_KEY_AGENCY(_attr, _name, _func, _desc, ...)
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
#define SHELL_EXPORT_PARAM_PARSER(_attr, _type, _parser, _cleaner)
|
||||
#endif /** SHELL_USING_FUNC_SIGNATURE == 1 */
|
||||
#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_STRING, /**< string型变量 */
|
||||
SHELL_TYPE_VAR_POINT, /**< 指针型变量 */
|
||||
SHELL_TYPE_VAR_NODE, /**< 节点变量 */
|
||||
SHELL_TYPE_USER, /**< 用户 */
|
||||
SHELL_TYPE_KEY, /**< 按键 */
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
SHELL_TYPE_PARAM_PARSER, /**< 参数解析器 */
|
||||
#endif
|
||||
} ShellCommandType;
|
||||
|
||||
/**
|
||||
* @brief Shell定义
|
||||
*/
|
||||
typedef struct shell_def {
|
||||
struct
|
||||
{
|
||||
const struct shell_command* user; /**< 当前用户 */
|
||||
int activeTime; /**< shell激活时间 */
|
||||
char* path; /**< 当前shell路径 */
|
||||
#if SHELL_USING_COMPANION == 1
|
||||
struct shell_companion_object* companions; /**< 伴生对象 */
|
||||
#endif
|
||||
#if SHELL_KEEP_RETURN_VALUE == 1
|
||||
int retVal; /**< 返回值 */
|
||||
#endif
|
||||
} info;
|
||||
struct
|
||||
{
|
||||
unsigned short length; /**< 输入数据长度 */
|
||||
unsigned short cursor; /**< 当前光标位置 */
|
||||
char* buffer; /**< 输入缓冲 */
|
||||
char* param[SHELL_PARAMETER_MAX_NUMBER]; /**< 参数 */
|
||||
unsigned short bufferSize; /**< 输入缓冲大小 */
|
||||
unsigned short paramCount; /**< 参数数量 */
|
||||
int keyValue; /**< 输入按键键值 */
|
||||
} parser;
|
||||
#if SHELL_HISTORY_MAX_NUMBER > 0
|
||||
struct
|
||||
{
|
||||
char* item[SHELL_HISTORY_MAX_NUMBER]; /**< 历史记录 */
|
||||
unsigned short number; /**< 历史记录数 */
|
||||
unsigned short record; /**< 当前记录位置 */
|
||||
signed short offset; /**< 当前历史记录偏移 */
|
||||
} history;
|
||||
#endif /** SHELL_HISTORY_MAX_NUMBER > 0 */
|
||||
struct
|
||||
{
|
||||
void* base; /**< 命令表基址 */
|
||||
unsigned short count; /**< 命令数量 */
|
||||
} commandList;
|
||||
struct
|
||||
{
|
||||
unsigned char isChecked : 1; /**< 密码校验通过 */
|
||||
unsigned char isActive : 1; /**< 当前活动Shell */
|
||||
unsigned char tabFlag : 1; /**< tab标志 */
|
||||
} status;
|
||||
signed short (*read)(char*, unsigned short); /**< shell读函数 */
|
||||
signed short (*write)(char*, unsigned short); /**< shell写函数 */
|
||||
#if SHELL_USING_LOCK == 1
|
||||
int (*lock)(struct shell_def*); /**< shell 加锁 */
|
||||
int (*unlock)(struct shell_def*); /**< shell 解锁 */
|
||||
#endif
|
||||
} 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; /**< 禁用返回值输出 */
|
||||
unsigned char readOnly : 1; /**< 只读 */
|
||||
unsigned char reserve : 1; /**< 保留 */
|
||||
unsigned char paramNum : 4; /**< 参数数量 */
|
||||
} attrs;
|
||||
int value;
|
||||
} attr; /**< 属性 */
|
||||
union {
|
||||
struct
|
||||
{
|
||||
const char* name; /**< 命令名 */
|
||||
int (*function)(); /**< 命令执行函数 */
|
||||
const char* desc; /**< 命令描述 */
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
const char* signature; /**< 函数签名 */
|
||||
#endif
|
||||
} 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; /**< 按键定义 */
|
||||
#if SHELL_USING_FUNC_SIGNATURE == 1
|
||||
struct
|
||||
{
|
||||
const char* type; /**< 参数类型 */
|
||||
int (*parser)(char*, void**); /**< 解析函数 */
|
||||
int (*cleaner)(void*); /**< 清理器 */
|
||||
} paramParser; /**< 参数解析器 */
|
||||
#endif
|
||||
} data;
|
||||
} ShellCommand;
|
||||
|
||||
/**
|
||||
* @brief shell节点变量属性
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void* var; /**< 变量引用 */
|
||||
int (*get)(); /**< 变量get方法 */
|
||||
int (*set)(); /**< 变量set方法 */
|
||||
} ShellNodeVarAttr;
|
||||
|
||||
#define shellSetPath(_shell, _path) (_shell)->info.path = _path
|
||||
#define shellGetPath(_shell) ((_shell)->info.path)
|
||||
|
||||
#define shellDeInit(shell) shellRemove(shell)
|
||||
|
||||
void shellInit(Shell* shell, char* buffer, unsigned short size);
|
||||
void shellRemove(Shell* shell);
|
||||
unsigned short shellWriteString(Shell* shell, const char* string);
|
||||
void shellPrint(Shell* shell, const char* fmt, ...);
|
||||
void shellScan(Shell* shell, char* fmt, ...);
|
||||
Shell* shellGetCurrent(void);
|
||||
void shellHandler(Shell* shell, char data);
|
||||
void shellWriteEndLine(Shell* shell, char* buffer, int len);
|
||||
void shellTask(void* param);
|
||||
int shellRun(Shell* shell, const char* cmd);
|
||||
extern int test_syscall(int sysnum, char* path, char** argv);
|
||||
|
||||
#if SHELL_USING_COMPANION == 1
|
||||
/**
|
||||
* @brief shell伴生对象定义
|
||||
*/
|
||||
typedef struct shell_companion_object {
|
||||
int id; /**< 伴生对象ID */
|
||||
void* obj; /**< 伴生对象 */
|
||||
struct shell_companion_object* next; /**< 下一个伴生对象 */
|
||||
} ShellCompanionObj;
|
||||
|
||||
signed char shellCompanionAdd(Shell* shell, int id, void* object);
|
||||
signed char shellCompanionDel(Shell* shell, int id);
|
||||
void* shellCompanionGet(Shell* shell, int id);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* @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__
|
||||
|
||||
#ifdef SHELL_CFG_USER
|
||||
#include SHELL_CFG_USER
|
||||
#endif
|
||||
|
||||
#ifndef SHELL_TASK_WHILE
|
||||
/**
|
||||
* @brief 是否使用默认shell任务while循环
|
||||
* 使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell
|
||||
* 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()`
|
||||
*/
|
||||
#define SHELL_TASK_WHILE 1
|
||||
#endif /** SHELL_TASK_WHILE */
|
||||
|
||||
#ifndef SHELL_USING_CMD_EXPORT
|
||||
/**
|
||||
* @brief 是否使用命令导出方式
|
||||
* 使能此宏后,可以使用`SHELL_EXPORT_CMD()`等导出命令
|
||||
* 定义shell命令,关闭此宏的情况下,需要使用命令表的方式
|
||||
*/
|
||||
#define SHELL_USING_CMD_EXPORT 0
|
||||
#endif /** SHELL_USING_CMD_EXPORT */
|
||||
|
||||
#ifndef SHELL_USING_COMPANION
|
||||
/**
|
||||
* @brief 是否使用shell伴生对象
|
||||
* 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象
|
||||
*/
|
||||
#define SHELL_USING_COMPANION 0
|
||||
#endif /** SHELL_USING_COMPANION */
|
||||
|
||||
#ifndef SHELL_SUPPORT_END_LINE
|
||||
/**
|
||||
* @brief 支持shell尾行模式
|
||||
*/
|
||||
#define SHELL_SUPPORT_END_LINE 0
|
||||
#endif /** SHELL_SUPPORT_END_LINE */
|
||||
|
||||
#ifndef SHELL_HELP_LIST_USER
|
||||
/**
|
||||
* @brief 是否在输出命令列表中列出用户
|
||||
*/
|
||||
#define SHELL_HELP_LIST_USER 0
|
||||
#endif /** SHELL_HELP_LIST_USER */
|
||||
|
||||
#ifndef SHELL_HELP_LIST_VAR
|
||||
/**
|
||||
* @brief 是否在输出命令列表中列出变量
|
||||
*/
|
||||
#define SHELL_HELP_LIST_VAR 0
|
||||
#endif /** SHELL_HELP_LIST_VAR */
|
||||
|
||||
#ifndef SHELL_HELP_LIST_KEY
|
||||
/**
|
||||
* @brief 是否在输出命令列表中列出按键
|
||||
*/
|
||||
#define SHELL_HELP_LIST_KEY 0
|
||||
#endif /** SHELL_HELP_LIST_KEY */
|
||||
|
||||
#ifndef SHELL_HELP_SHOW_PERMISSION
|
||||
/**
|
||||
* @brief 是否在输出命令列表中展示命令权限
|
||||
*/
|
||||
#define SHELL_HELP_SHOW_PERMISSION 1
|
||||
#endif /** SHELL_HELP_SHOW_PERMISSION */
|
||||
|
||||
#ifndef SHELL_ENTER_LF
|
||||
/**
|
||||
* @brief 使用LF作为命令行回车触发
|
||||
* 可以和SHELL_ENTER_CR同时开启
|
||||
*/
|
||||
#define SHELL_ENTER_LF 1
|
||||
#endif /** SHELL_ENTER_LF */
|
||||
|
||||
#ifndef SHELL_ENTER_CR
|
||||
/**
|
||||
* @brief 使用CR作为命令行回车触发
|
||||
* 可以和SHELL_ENTER_LF同时开启
|
||||
*/
|
||||
#define SHELL_ENTER_CR 1
|
||||
#endif /** SHELL_ENTER_CR */
|
||||
|
||||
#ifndef SHELL_ENTER_CRLF
|
||||
/**
|
||||
* @brief 使用CRLF作为命令行回车触发
|
||||
* 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启
|
||||
*/
|
||||
#define SHELL_ENTER_CRLF 0
|
||||
#endif /** SHELL_ENTER_CRLF */
|
||||
|
||||
#ifndef SHELL_EXEC_UNDEF_FUNC
|
||||
/**
|
||||
* @brief 使用执行未导出函数的功能
|
||||
* 启用后,可以通过`exec [addr] [args]`直接执行对应地址的函数
|
||||
* @attention 如果地址错误,可能会直接引起程序崩溃
|
||||
*/
|
||||
#define SHELL_EXEC_UNDEF_FUNC 0
|
||||
#endif /** SHELL_EXEC_UNDEF_FUNC */
|
||||
|
||||
#ifndef SHELL_PARAMETER_MAX_NUMBER
|
||||
/**
|
||||
* @brief shell命令参数最大数量
|
||||
* 包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码
|
||||
*/
|
||||
#define SHELL_PARAMETER_MAX_NUMBER 8
|
||||
#endif /** SHELL_PARAMETER_MAX_NUMBER */
|
||||
|
||||
#ifndef SHELL_HISTORY_MAX_NUMBER
|
||||
/**
|
||||
* @brief 历史命令记录数量
|
||||
*/
|
||||
#define SHELL_HISTORY_MAX_NUMBER 5
|
||||
#endif /** SHELL_HISTORY_MAX_NUMBER */
|
||||
|
||||
#ifndef SHELL_DOUBLE_CLICK_TIME
|
||||
/**
|
||||
* @brief 双击间隔(ms)
|
||||
* 使能宏`SHELL_LONG_HELP`后此宏生效,定义双击tab补全help的时间间隔
|
||||
*/
|
||||
#define SHELL_DOUBLE_CLICK_TIME 200
|
||||
#endif /** SHELL_DOUBLE_CLICK_TIME */
|
||||
|
||||
#ifndef SHELL_QUICK_HELP
|
||||
/**
|
||||
* @brief 快速帮助
|
||||
* 作用于双击tab的场景,当使能此宏时,双击tab不会对命令进行help补全,而是直接显示对应命令的帮助信息
|
||||
*/
|
||||
#define SHELL_QUICK_HELP 1
|
||||
#endif /** SHELL_QUICK_HELP */
|
||||
|
||||
#ifndef SHELL_KEEP_RETURN_VALUE
|
||||
/**
|
||||
* @brief 保存命令返回值
|
||||
* 开启后会默认定义一个`RETVAL`变量,会保存上一次命令执行的返回值,可以在随后的命令中进行调用
|
||||
* 如果命令的`SHELL_CMD_DISABLE_RETURN`标志被设置,则该命令不会更新`RETVAL`
|
||||
*/
|
||||
#define SHELL_KEEP_RETURN_VALUE 0
|
||||
#endif /** SHELL_KEEP_RETURN_VALUE */
|
||||
|
||||
#ifndef SHELL_MAX_NUMBER
|
||||
/**
|
||||
* @brief 管理的最大shell数量
|
||||
*/
|
||||
#define SHELL_MAX_NUMBER 5
|
||||
#endif /** SHELL_MAX_NUMBER */
|
||||
|
||||
#ifndef SHELL_PRINT_BUFFER
|
||||
/**
|
||||
* @brief shell格式化输出的缓冲大小
|
||||
* 为0时不使用shell格式化输出
|
||||
*/
|
||||
#define SHELL_PRINT_BUFFER 0
|
||||
#endif /** SHELL_PRINT_BUFFER */
|
||||
|
||||
#ifndef SHELL_SCAN_BUFFER
|
||||
/**
|
||||
* @brief shell格式化输入的缓冲大小
|
||||
* 为0时不使用shell格式化输入
|
||||
* @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用
|
||||
*/
|
||||
#define SHELL_SCAN_BUFFER 0
|
||||
#endif /** SHELL_SCAN_BUFFER */
|
||||
|
||||
#ifndef SHELL_GET_TICK
|
||||
/**
|
||||
* @brief 获取系统时间(ms)
|
||||
* 定义此宏为获取系统Tick,如`HAL_GetTick()`
|
||||
* @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定
|
||||
*/
|
||||
#define SHELL_GET_TICK() 0
|
||||
#endif /** SHELL_GET_TICK */
|
||||
|
||||
#ifndef SHELL_USING_LOCK
|
||||
/**
|
||||
* @brief 使用锁
|
||||
* @note 使用shell锁时,需要对加锁和解锁进行实现
|
||||
*/
|
||||
#define SHELL_USING_LOCK 0
|
||||
#endif /** SHELL_USING_LOCK */
|
||||
|
||||
#ifndef SHELL_MALLOC
|
||||
/**
|
||||
* @brief shell内存分配
|
||||
* shell本身不需要此接口,若使用shell伴生对象,需要进行定义
|
||||
*/
|
||||
#define SHELL_MALLOC(size) 0
|
||||
#endif /** SHELL_MALLOC */
|
||||
|
||||
#ifndef SHELL_FREE
|
||||
/**
|
||||
* @brief shell内存释放
|
||||
* shell本身不需要此接口,若使用shell伴生对象,需要进行定义
|
||||
*/
|
||||
#define SHELL_FREE(obj) 0
|
||||
#endif /** SHELL_FREE */
|
||||
|
||||
#ifndef SHELL_SHOW_INFO
|
||||
/**
|
||||
* @brief 是否显示shell信息
|
||||
*/
|
||||
#define SHELL_SHOW_INFO 1
|
||||
#endif /** SHELL_SHOW_INFO */
|
||||
|
||||
#ifndef SHELL_CLS_WHEN_LOGIN
|
||||
/**
|
||||
* @brief 是否在登录后清除命令行
|
||||
*/
|
||||
#define SHELL_CLS_WHEN_LOGIN 0
|
||||
#endif /** SHELL_CLS_WHEN_LOGIN */
|
||||
|
||||
#ifndef SHELL_DEFAULT_USER
|
||||
/**
|
||||
* @brief shell默认用户
|
||||
*/
|
||||
#define SHELL_DEFAULT_USER "letter"
|
||||
#endif /** SHELL_DEFAULT_USER */
|
||||
|
||||
#ifndef SHELL_DEFAULT_USER_PASSWORD
|
||||
/**
|
||||
* @brief shell默认用户密码
|
||||
* 若默认用户不需要密码,设为""
|
||||
*/
|
||||
#define SHELL_DEFAULT_USER_PASSWORD ""
|
||||
#endif /** SHELL_DEFAULT_USER_PASSWORD */
|
||||
|
||||
#ifndef SHELL_LOCK_TIMEOUT
|
||||
/**
|
||||
* @brief shell自动锁定超时
|
||||
* shell当前用户密码有效的时候生效,超时后会自动重新锁定shell
|
||||
* 设置为0时关闭自动锁定功能,时间单位为`SHELL_GET_TICK()`单位
|
||||
* @note 使用超时锁定必须保证`SHELL_GET_TICK()`有效
|
||||
*/
|
||||
#define SHELL_LOCK_TIMEOUT 0 * 60 * 1000
|
||||
#endif /** SHELL_LOCK_TIMEOUT */
|
||||
|
||||
#ifndef SHELL_USING_FUNC_SIGNATURE
|
||||
/**
|
||||
* @brief 使用函数签名
|
||||
* 使能后,可以在声明命令时,指定函数的签名,shell 会根据函数签名进行参数转换,
|
||||
* 而不是自动判断参数的类型,如果参数和函数签名不匹配,会停止执行命令
|
||||
*/
|
||||
#define SHELL_USING_FUNC_SIGNATURE 0
|
||||
#endif /** SHELL_USING_FUNC_SIGNATURE */
|
||||
|
||||
#ifndef SHELL_SUPPORT_ARRAY_PARAM
|
||||
/**
|
||||
* @brief 支持数组参数
|
||||
* 使能后,可以在命令中使用数组参数,如`cmd [1,2,3]`
|
||||
* 需要使能 `SHELL_USING_FUNC_SIGNATURE` 宏,并且配置 `SHELL_MALLOC`, `SHELL_FREE`
|
||||
*/
|
||||
#define SHELL_SUPPORT_ARRAY_PARAM 0
|
||||
#endif /** SHELL_SUPPORT_ARRAY_PARAM */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @file shell_cmd_list.c
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief shell cmd list
|
||||
* @version 3.0.0
|
||||
* @date 2020-01-17
|
||||
*
|
||||
* @copyright (c) 2020 Letter
|
||||
*
|
||||
*/
|
||||
|
||||
#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);
|
||||
|
||||
// fs cmds
|
||||
extern void shellLs(const char* path, ...);
|
||||
extern void shellCd(const char* path);
|
||||
extern void shellMkdir(const char* path);
|
||||
extern void shellRm(const char* path);
|
||||
extern void shellCat(const char* path);
|
||||
|
||||
extern void shellShowTasks();
|
||||
extern void shellShowMemInfo();
|
||||
extern void shellShowCpusInfo();
|
||||
|
||||
#if SHELL_EXEC_UNDEF_FUNC == 1
|
||||
extern int shellExecute(int argc, char* argv[]);
|
||||
#endif
|
||||
|
||||
SHELL_AGENCY_FUNC(shellRun, shellGetCurrent(), (const char*)p1);
|
||||
|
||||
/**
|
||||
* @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 = "default 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, shellBackspace, 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),
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
sh, SHELL_AGENCY_FUNC_NAME(shellRun), run command directly),
|
||||
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
ls, shellLs, ls files),
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
cd, shellCd, go to target path),
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
mkdir, shellMkdir, create a new dir),
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
rm, shellRm, remove a file or a dir),
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
cat, shellCat, print the file content on the console),
|
||||
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
showTasks, shellShowTasks, display tasks info),
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
showMemInfo, shellShowMemInfo, display memory info),
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN,
|
||||
showCpusInfo, shellShowCpusInfo, display cpus info),
|
||||
|
||||
#if SHELL_EXEC_UNDEF_FUNC == 1
|
||||
SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_DISABLE_RETURN,
|
||||
exec, shellExecute, execute function undefined),
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief shell命令表大小
|
||||
*
|
||||
*/
|
||||
const unsigned short shellCommandCount
|
||||
= sizeof(shellCommandList) / sizeof(ShellCommand);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* @file shell_ext.c
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief shell extensions
|
||||
* @version 3.0.0
|
||||
* @date 2019-12-31
|
||||
*
|
||||
* @copyright (c) 2019 Letter
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shell_ext.h"
|
||||
#include "shell.h"
|
||||
|
||||
extern ShellCommand* shellSeekCommand(Shell* shell,
|
||||
const char* cmd,
|
||||
ShellCommand* base,
|
||||
unsigned short compareLength);
|
||||
extern int shellGetVarValue(Shell* shell, ShellCommand* command);
|
||||
|
||||
/**
|
||||
* @brief Judging the number base
|
||||
*
|
||||
* @param string Parameter string
|
||||
* @return NUM_Type Base
|
||||
*/
|
||||
static NUM_Type shellExtNumType(char* string)
|
||||
{
|
||||
char* p = string;
|
||||
NUM_Type type = NUM_TYPE_INT;
|
||||
|
||||
if ((*p == '0') && ((*(p + 1) == 'x') || (*(p + 1) == 'X'))) {
|
||||
type = NUM_TYPE_HEX;
|
||||
} else if ((*p == '0') && ((*(p + 1) == 'b') || (*(p + 1) == 'B'))) {
|
||||
type = NUM_TYPE_BIN;
|
||||
} else if (*p == '0') {
|
||||
type = NUM_TYPE_OCT;
|
||||
}
|
||||
|
||||
while (*p++) {
|
||||
if (*p == '.' && *(p + 1) != 0) {
|
||||
type = NUM_TYPE_FLOAT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief character to number
|
||||
*
|
||||
* @param code character
|
||||
* @return char number
|
||||
*/
|
||||
static char shellExtToNum(char code)
|
||||
{
|
||||
if ((code >= '0') && (code <= '9')) {
|
||||
return code - '0';
|
||||
} else if ((code >= 'a') && (code <= 'f')) {
|
||||
return code - 'a' + 10;
|
||||
} else if ((code >= 'A') && (code <= 'F')) {
|
||||
return code - 'A' + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse character parameters
|
||||
*
|
||||
* @param string String parameter
|
||||
* @return char Parsed character
|
||||
*/
|
||||
static char shellExtParseChar(char* string)
|
||||
{
|
||||
char* p = string + 1;
|
||||
char value = 0;
|
||||
|
||||
if (*p == '\\') {
|
||||
switch (*(p + 1)) {
|
||||
case 'b':
|
||||
value = '\b';
|
||||
break;
|
||||
case 'r':
|
||||
value = '\r';
|
||||
break;
|
||||
case 'n':
|
||||
value = '\n';
|
||||
break;
|
||||
case 't':
|
||||
value = '\t';
|
||||
break;
|
||||
case '0':
|
||||
value = 0;
|
||||
break;
|
||||
default:
|
||||
value = *(p + 1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
value = *p;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse string parameters
|
||||
*
|
||||
* @param string String parameter
|
||||
* @return char* Parsed string
|
||||
*/
|
||||
static char* shellExtParseString(char* string)
|
||||
{
|
||||
char* p = string;
|
||||
unsigned short index = 0;
|
||||
|
||||
if (*string == '\"') {
|
||||
p = ++string;
|
||||
}
|
||||
|
||||
while (*p) {
|
||||
if (*p == '\\') {
|
||||
*(string + index) = shellExtParseChar(p - 1);
|
||||
p++;
|
||||
} else if (*p == '\"') {
|
||||
*(string + index) = 0;
|
||||
} else {
|
||||
*(string + index) = *p;
|
||||
}
|
||||
p++;
|
||||
index++;
|
||||
}
|
||||
*(string + index) = 0;
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse numeric parameters
|
||||
*
|
||||
* @param string String parameter
|
||||
* @return unsigned int Parsed number
|
||||
*/
|
||||
static unsigned int shellExtParseNumber(char* string)
|
||||
{
|
||||
NUM_Type type = NUM_TYPE_INT;
|
||||
char radix = 10;
|
||||
char* p = string;
|
||||
char offset = 0;
|
||||
signed char sign = 1;
|
||||
unsigned int valueInt = 0;
|
||||
float valueFloat = 0.0;
|
||||
unsigned int devide = 0;
|
||||
|
||||
if (*string == '-') {
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
type = shellExtNumType(string + ((sign == -1) ? 1 : 0));
|
||||
|
||||
switch ((char)type) {
|
||||
case NUM_TYPE_HEX:
|
||||
radix = 16;
|
||||
offset = 2;
|
||||
break;
|
||||
|
||||
case NUM_TYPE_OCT:
|
||||
radix = 8;
|
||||
offset = 1;
|
||||
break;
|
||||
|
||||
case NUM_TYPE_BIN:
|
||||
radix = 2;
|
||||
offset = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p = string + offset + ((sign == -1) ? 1 : 0);
|
||||
|
||||
while (*p) {
|
||||
if (*p == '.') {
|
||||
devide = 1;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
valueInt = valueInt * radix + shellExtToNum(*p);
|
||||
devide *= 10;
|
||||
p++;
|
||||
}
|
||||
if (type == NUM_TYPE_FLOAT && devide != 0) {
|
||||
valueFloat = (float)valueInt / devide * sign;
|
||||
return *(unsigned int*)(&valueFloat);
|
||||
} else {
|
||||
return valueInt * sign;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Analyze variable parameters
|
||||
|
||||
*
|
||||
* @param shell shell object
|
||||
* @param var variable
|
||||
* @return unsigned int variable value
|
||||
*/
|
||||
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 Parsing parameters
|
||||
*
|
||||
* @param shell shell
|
||||
* @param string parameter
|
||||
* @return unsigned int Analysis result
|
||||
*/
|
||||
unsigned int shellExtParsePara(Shell* shell, char* string)
|
||||
{
|
||||
if (*string == '\'' && *(string + 1)) {
|
||||
return (unsigned int)shellExtParseChar(string);
|
||||
} else if (*string == '-' || (*string >= '0' && *string <= '9')) {
|
||||
return (unsigned int)shellExtParseNumber(string);
|
||||
} else if (*string == '$' && *(string + 1)) {
|
||||
return shellExtParseVar(shell, string);
|
||||
} else if (*string) {
|
||||
return (unsigned long)shellExtParseString(string);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Excuting function
|
||||
*
|
||||
* @param shell shell
|
||||
* @param command command
|
||||
* @param argc Number of parameters
|
||||
* @param argv parameter
|
||||
* @return int return value
|
||||
*/
|
||||
int shellExtRun(Shell* shell, ShellCommand* command, int argc, char* argv[])
|
||||
{
|
||||
unsigned int params[8] = { 0 };
|
||||
int paramNum = command->attr.attrs.paramNum > (argc - 1) ? command->attr.attrs.paramNum : (argc - 1);
|
||||
for (int i = 0; i < argc - 1; i++) {
|
||||
params[i] = shellExtParsePara(shell, argv[i + 1]);
|
||||
}
|
||||
switch (paramNum) {
|
||||
case 0:
|
||||
return command->data.cmd.function();
|
||||
// break;
|
||||
case 1:
|
||||
return command->data.cmd.function(params[0]);
|
||||
// break;
|
||||
case 2:
|
||||
return command->data.cmd.function(params[0], params[1]);
|
||||
// break;
|
||||
case 3:
|
||||
return command->data.cmd.function(params[0], params[1],
|
||||
params[2]);
|
||||
// break;
|
||||
case 4:
|
||||
return command->data.cmd.function(params[0], params[1],
|
||||
params[2], params[3]);
|
||||
// break;
|
||||
case 5:
|
||||
return command->data.cmd.function(params[0], params[1],
|
||||
params[2], params[3],
|
||||
params[4]);
|
||||
// break;
|
||||
case 6:
|
||||
return command->data.cmd.function(params[0], params[1],
|
||||
params[2], params[3],
|
||||
params[4], params[5]);
|
||||
// break;
|
||||
case 7:
|
||||
return command->data.cmd.function(params[0], params[1],
|
||||
params[2], params[3],
|
||||
params[4], params[5],
|
||||
params[6]);
|
||||
// break;
|
||||
default:
|
||||
return -1;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @file shell_ext.h
|
||||
* @author Letter (NevermindZZT@gmail.com)
|
||||
* @brief shell extensions
|
||||
* @version 3.0.0
|
||||
* @date 2019-12-31
|
||||
*
|
||||
* @copyright (c) 2019 Letter
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHELL_EXT_H__
|
||||
#define __SHELL_EXT_H__
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
/**
|
||||
* @brief type of number
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
NUM_TYPE_INT, /**< Decimal integer */
|
||||
NUM_TYPE_BIN, /**< Binary integer */
|
||||
NUM_TYPE_OCT, /**< Octal integer */
|
||||
NUM_TYPE_HEX, /**< Hexadecimal integer */
|
||||
NUM_TYPE_FLOAT /**< Floating point */
|
||||
} NUM_Type;
|
||||
|
||||
unsigned int shellExtParsePara(Shell* shell, char* string);
|
||||
int shellExtRun(Shell* shell, ShellCommand* command, int argc, char* argv[]);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user