diff --git a/demo/stm32-hal/shell_port.c b/demo/stm32-hal/shell_port.c new file mode 100644 index 0000000..5185a31 --- /dev/null +++ b/demo/stm32-hal/shell_port.c @@ -0,0 +1,69 @@ +/** + * @file shell_port.c + * @author Shellever (shellever@163.com) + * @brief + * @version 0.1 + * @date 2024-06-20 + * + * @copyright (c) 2019 Letter + * + */ + +#include "main.h" +#include "usart.h" + +#include "shell.h" +#include "shell_port.h" + + +Shell shell; +char shellBuffer[512]; + + +/** + * @brief 用户shell写 + * + * @param data 数据 + * @param len 数据长度 + * + * @return short 实际写入的数据长度 + */ +short userShellWrite(char *data, unsigned short len) +{ + HAL_UART_Transmit(&huart1, (uint8_t *)data, len, 200); // 太小的话会导致超时,只有前面部分显示,显示不全 + + return len; +} + + +/** + * @brief 用户shell读 + * + * @param data 数据 + * @param len 数据长度 + * + * @return short 实际读取到 + */ +short userShellRead(char *data, unsigned short len) +{ + if (HAL_UART_Receive(&huart1, (uint8_t *)data, len, 200) == HAL_OK) { + return len; + } + + return 0; +} + + +/** + * @brief 用户shell初始化 + * + */ +void userShellInit(void) +{ + shell.write = userShellWrite; + shell.read = userShellRead; + + shellInit(&shell, shellBuffer, sizeof(shellBuffer)); +} + + diff --git a/demo/stm32-hal/shell_port.h b/demo/stm32-hal/shell_port.h new file mode 100644 index 0000000..ce29031 --- /dev/null +++ b/demo/stm32-hal/shell_port.h @@ -0,0 +1,21 @@ +/** + * @file shell_port.h + * @author Shellever (shellever@163.com) + * @brief + * @version 0.1 + * @date 2024-06-20 + * + * @copyright (c) 2019 Letter + * + */ + +#ifndef __SHELL_PORT_H__ +#define __SHELL_PORT_H__ + + +#include "shell.h" + +extern Shell shell; + +void userShellInit(void); +#endif diff --git a/src/shell.c b/src/shell.c index f956266..49ba6cd 100644 --- a/src/shell.c +++ b/src/shell.c @@ -173,6 +173,7 @@ ShellCommand* shellSeekCommand(Shell *shell, ShellCommand *base, unsigned short compareLength); static void shellWriteCommandHelp(Shell *shell, char *cmd); +static char shellInterceptKey(Shell *shell, char data); /** * @brief shell 初始化 @@ -1759,48 +1760,40 @@ SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RE help, shellHelp, show command info\r\nhelp [cmd]); /** - * @brief shell 输入处理 - * - * @param shell shell对象 - * @param data 输入数据 + * @brief shell 按键拦截 + * parser.keyValue 保存上一次已经匹配的数值位 + * keyFilter 保存之前匹配过的掩码值 + * keyByteOffset 当前需要匹配的字节偏移位置 + * keyName keyValue parser.keyValue keyByteOffset keyFilter + * backspace 0x08000000 0x00000000 24 0x00000000 + * CRLF 0x0D0A0000 0x0D000000 16 0xFF000000 + * up 0x1B5B4100 0x1B5B0000 8 0xFFFF0000 + * delete 0x1B5B337E 0x1B5B3300 0 0xFFFFFF00 + * + * @param shell shell 对象 + * @param data 输入字符 */ -void shellHandler(Shell *shell, char data) +static char shellInterceptKey(Shell *shell, char data) { - SHELL_ASSERT(data, return); - SHELL_LOCK(shell); + char keyByteOffset; + int keyFilter; + char keyHit = 0; // 按键匹配标志 -#if SHELL_LOCK_TIMEOUT > 0 - 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 /* 根据记录的按键键值计算当前字节在按键键值中的偏移 */ - char keyByteOffset = 24; - int keyFilter = 0x00000000; - if ((shell->parser.keyValue & 0x0000FF00) != 0x00000000) - { - keyByteOffset = 0; - keyFilter = 0xFFFFFF00; - } - else if ((shell->parser.keyValue & 0x00FF0000) != 0x00000000) - { - keyByteOffset = 8; - keyFilter = 0xFFFF0000; - } - else if ((shell->parser.keyValue & 0xFF000000) != 0x00000000) + char *pkey = (char *)&shell->parser.keyValue; + char i = sizeof(shell->parser.keyValue); + + while(pkey[--i] != 0) { - keyByteOffset = 16; - keyFilter = 0xFF000000; + ; } - /* 遍历ShellCommand列表,尝试进行按键键值匹配 */ + keyFilter = 0xFFFFFFFF << ((i + 1) * 8); + keyByteOffset = i * 8; + + + /* 遍历 ShellCommand 列表,尝试进行按键键值匹配 */ ShellCommand *base = (ShellCommand *)shell->commandList.base; for (short i = 0; i < shell->commandList.count; i++) { @@ -1810,29 +1803,62 @@ void shellHandler(Shell *shell, char data) { /* 对输入的字节同按键键值进行匹配 */ if ((base[i].data.key.value & keyFilter) == shell->parser.keyValue - && (base[i].data.key.value & (0xFF << keyByteOffset)) - == (data << keyByteOffset)) + && ((base[i].data.key.value >> keyByteOffset) & 0xFF) == data) { - shell->parser.keyValue |= data << keyByteOffset; - data = 0x00; - if (keyByteOffset == 0 - || (base[i].data.key.value & (0xFF << (keyByteOffset - 8))) - == 0x00000000) + keyHit = 1; + + /* 测试按键键值匹配位置的后一个字节是否为 0x00,用于表示匹配是否完成 */ + if (keyByteOffset == 0 + || ((base[i].data.key.value >> (keyByteOffset - 8)) & 0xFF) == 0x00) { if (base[i].data.key.function) { base[i].data.key.function(shell); } - shell->parser.keyValue = 0x00000000; + shell->parser.keyValue = 0; break; } + else + { + shell->parser.keyValue |= data << keyByteOffset; + } } } } - if (data != 0x00) + if (!keyHit) + { + shell->parser.keyValue = 0; + } + + return keyHit; +} + +/** + * @brief shell 输入处理 + * + * @param shell shell对象 + * @param data 输入数据 + */ +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 + && 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 + + if (!shellInterceptKey(shell, data)) { - shell->parser.keyValue = 0x00000000; shellNormalInput(shell, data); }