码云地址
shell_cfg.h
中的 SHELL_USING_CMD_EXPORT
宏进行控制,如果 #define SHELL_USING_CMD_EXPORT 0
的话,则生成 shell 命令表。void shellInit(Shell *shell, char *buffer, unsigned short size)
{
// 初始化参数
shell->parser.length = 0;
shell->parser.cursor = 0;
......
// 设置 shell 所使用的 buffer 空间
shell->parser.buffer = buffer;
// 设置每个 buffer 空间大小,具体算法为 总大小 / (历史条数+1) 此处的1为当前使用的buffer大小
shell->parser.bufferSize = size / (SHELL_HISTORY_MAX_NUMBER + 1);
for (short i = 0; i < SHELL_HISTORY_MAX_NUMBER; i++)
{
// 设置每个历史buffer的位置,第一个buffer为当前使用位置,所以不设置
shell->history.item[i] = buffer + shell->parser.bufferSize * (i + 1);
}
......
// 设置命令列表基地址和命令列表大小
shell->commandList.base = (ShellCommand *)shellCommandList;
shell->commandList.count = shellCommandCount;
.......
// 创建shell
shellAdd(shell);
// 设置当前用户。当前用户为 SHELL_DEFAULT_USER 对应的用户名称
shellSetUser(shell, shellSeekCommand(shell,
SHELL_DEFAULT_USER,
shell->commandList.base,
0));
// 开启shell第一个输出
shellWriteCommandLine(shell);
}
void shellTask(void *param)
{
// 当前shell由形参传入,可以用于不同串口执行不同用户。
Shell *shell = (Shell *)param;
char data;
// 由 shell_cfg.h 中的 SHELL_TASK_WHILE 控制是否在 shellTask 中执行 while(1) 操作
#if SHELL_TASK_WHILE == 1
while(1)
{
#endif
if (shell->read && shell->read(&data) == 0)
{
// 如果有字符读取,则执行句柄函数。解析当前buffer区域的数据。
shellHandler(shell, data);
}
#if SHELL_TASK_WHILE == 1
}
#endif
}
void shellHandler(Shell *shell, char data)
{
SHELL_ASSERT(data, return);
#if SHELL_LOCK_TIMEOUT > 0
// 用户加锁的条件为 用户设置密码 且 设置有获取时间的借口 SHELL_GET_TICK() 如果和上次的字符输入时间相差超过 LOCK_TIMEOUT 时间,则认为用户被锁。
if (shell->info.user->data.user.password
&& strlen(shell->info.user->data.user.password) != 0
&& SHELL_GET_TICK())
{
if (SHELL_GET_TICK() - shell->info.activeTime > SHELL_LOCK_TIMEOUT)
{
shell->status.isChecked = 0;
}
}
#endif
/* 根据记录的按键键值计算当前字节在按键键值中的偏移 */
......
/* 遍历ShellCommand列表,尝试进行按键键值匹配 */
/* 匹配之后,执行所对应的函数 */
......
if (data != 0x00)
{
// 执行回显功能
shellNormalInput(shell, data);
}
if (SHELL_GET_TICK())
{
// 由于有字符输入,则需要更新时间
shell->info.activeTime = SHELL_GET_TICK();
}
}
SHELL_EXPORT_KEY
宏定义都可以看到按键所对应的键值和函数。