代码拉取完成,页面将自动刷新
#include <shell.h>
#include <u_syscall.h>
#include <memory.h>
#include <string.h>
#include <version.h>
#define CMDLINE_POS_X 0 // 命令行横坐标
#define CMDLINE_POS_Y 8 // 命令行纵坐标
#define CMDLINE "Enter command:" // 命令行提示
#define CMD_MAX 64 // 命令行最多支持输入 64 个字符
#define CMD_UNKNOWN "Unknown command:" // 未知的命令行提示
#define IS_KEYDOWN(key) (!!(key & 0xFF000000)) // 判断是否是按键按下
#define GET_CHAR(key) ({U08 retval = ((key) & 0xFF); retval;}) // 获取键值中的 ASCII
#define GET_VCODE(key) ({U08 retval = (((key) >> 8) & 0xFF); retval;}) // 获取键值中的虚拟键码
#define VCODE_ENTER 0x0D // "Enter" 键的虚拟键码
#define VCODE_BACKSPACE 0x08 // "BackSpace" 键的虚拟键码
U08 ShellStack[256] = {0xFF}; // shell 任务私有栈
static U08 cmd_buf[CMD_MAX] = {0}; // 全局命令行输入字符数组
static U32 cmd_index = 0; // 全局命令行输入字符数组下标
static LIST CMD_LIST_HEAD = {0}; // shell 命令链表头
/******************************************************************************
* 函数名称: E_RET CmdRegister(const U08* cmd, CmdFunc func)
* 功能说明: 命令注册
* 输入参数: const U08* cmd --命令
CmdFunc func --命令对应的执行函数
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
E_RET CmdRegister(const U08* cmd, CmdFunc func)
{
// 检查参数合法性
if(NULL == cmd || NULL == func)
return E_ERR;
// 申请一个命令节点的内存空间
SHELL_CMD* shell_cmd = (SHELL_CMD *)Malloc(sizeof(SHELL_CMD));
if(NULL == shell_cmd)
return E_ERR;
shell_cmd->cmd = (U08 *)cmd;
shell_cmd->func = func;
ListAddHead(&CMD_LIST_HEAD, &(shell_cmd->node)); // 将命令节点插入命令链表中
return E_OK;
}
/******************************************************************************
* 函数名称: static void BackSpaceHandle(void)
* 功能说明: 按下 "BackSpace" 键后处理函数
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 删除最后一个字符
******************************************************************************/
static void BackSpaceHandle(void)
{
if(cmd_index)
{
// 首先将光标位置前移一个位置,打印 " " 空格字符,打印完成后光标位置又向后偏移了一个位置,需要重新设置回来
cmd_index--;
SetCursorPos(sizeof(CMDLINE) -1 + cmd_index, CMDLINE_POS_Y);
print(" ");
SetCursorPos(sizeof(CMDLINE) -1 + cmd_index, CMDLINE_POS_Y);
}
}
/******************************************************************************
* 函数名称: static void ResetCmdLine(void)
* 功能说明: 复位命令行
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 无
******************************************************************************/
static void ResetCmdLine(void)
{
U32 i = 0;
cmd_index = 0;
SetCursorPos(sizeof(CMDLINE) -1, CMDLINE_POS_Y);
for(i = 0; i < CMD_MAX; i++)
print(" ");
SetCursorPos(sizeof(CMDLINE) -1, CMDLINE_POS_Y);
}
/******************************************************************************
* 函数名称: static E_RET DoCmd(U08* cmd)
* 功能说明: 查找并执行命令
* 输入参数: U08* cmd --命令
* 输出参数: 无
* 函数返回: E_OK:成功; E_ERR:失败
* 其它说明: 无
******************************************************************************/
static E_RET DoCmd(U08* cmd)
{
LIST_NODE* pListNode = NULL;
SHELL_CMD* nodeTmp = NULL;
// 遍历命令链表
LIST_FOR_EACH(&CMD_LIST_HEAD, pListNode)
{
nodeTmp = (SHELL_CMD *)LIST_NODE(pListNode, SHELL_CMD, node);
if(StrCmp(nodeTmp->cmd, cmd, -1)) // 找到命令
{
nodeTmp->func();
ResetCmdLine();
return E_OK;
}
}
return E_ERR;
}
/******************************************************************************
* 函数名称: static void BackSpaceHandle(void)
* 功能说明: 按下 "Enter" 键后处理函数
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 无
******************************************************************************/
static void EnterHandle(void)
{
U32 i = 0;
// 输入的命令行字符为空,则直接退出
if(0 == cmd_index)
return;
cmd_buf[cmd_index] = 0; // 先在输入的字符串最后添加字符串结束标志 '\0'
// 在开始解析命令之前,先将命令行的下一行清空,用于接下来的命令提示
SetCursorPos(CMDLINE_POS_X, CMDLINE_POS_Y+1);
for(i = 0; i < sizeof(CMD_UNKNOWN) -1 + CMD_MAX; i++)
print(" ");
SetCursorPos(CMDLINE_POS_X, CMDLINE_POS_Y+1);
// 如果命令执行失败,则打印 "Unknown command:xxx"
if(E_ERR == DoCmd(cmd_buf))
{
print(CMD_UNKNOWN);
print("%s", cmd_buf);
ResetCmdLine(); // 复位命令行
}
}
/******************************************************************************
* 函数名称: static void CmdLineHandle(U08 ascii, U08 vcode)
* 功能说明: 命令行处理
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 无
******************************************************************************/
static void CmdLineHandle(U08 ascii, U08 vcode)
{
// 命令行输入显示
if(ascii)
{
if(cmd_index < CMD_MAX)
{
cmd_buf[cmd_index++] = ascii;
print("%c", ascii);
}
}
switch(vcode)
{
case VCODE_BACKSPACE: // 按下 "BackSpace" 键
BackSpaceHandle();
break;
case VCODE_ENTER: // 按下 "Enter" 键
EnterHandle();
break;
default:
break;
}
}
/******************************************************************************
* 函数名称: void ShellTask(void)
* 功能说明: shell 任务
* 输入参数: 无
* 输出参数: 无
* 函数返回: 无
* 其它说明: 无
******************************************************************************/
void ShellTask(void)
{
U32 key = 0;
U08 ascii = 0;
U08 vcode = 0;
// 固定命令行的显示位置,并打印提示字符 "Enter command:"
SetCursorPos(CMDLINE_POS_X, CMDLINE_POS_Y);
print(CMDLINE);
ListInit(&CMD_LIST_HEAD); // 初始化 shell 命令链表
CmdRegister(CMD_VERSION, (CmdFunc)KernelVersion); // 注册命令
while (1)
{
key = ReadKey();
if(IS_KEYDOWN(key)) // 如果是按键按下
{
ascii = GET_CHAR(key); // 获取键值中的 ASCII
vcode = GET_VCODE(key); // 获取键值中的虚拟键码
CmdLineHandle(ascii, vcode); // 命令行处理
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。