Support XiZi_AIoT

This commit is contained in:
TXuian
2024-01-31 10:30:34 +08:00
parent f6cf46027d
commit 494312183b
351 changed files with 46408 additions and 450091 deletions
@@ -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