diff --git a/.gitignore b/.gitignore index 016358f..392f5b2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ CMakeFiles cmake_install.cmake CMakeCache.txt demo/x86-gcc/Makefile -demo/x86-gcc/LetterShell \ No newline at end of file +demo/x86-gcc/LetterShell diff --git a/README.md b/README.md index 2792037..d7550c4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![version](https://img.shields.io/badge/version-3.1.0-brightgreen.svg) ![standard](https://img.shields.io/badge/standard-c99-brightgreen.svg) -![build](https://img.shields.io/badge/build-2021.05.09-brightgreen.svg) +![build](https://img.shields.io/badge/build-2021.05.24-brightgreen.svg) ![license](https://img.shields.io/badge/license-MIT-brightgreen.svg) 一个功能强大的嵌入式shell @@ -108,7 +108,7 @@ * * @return unsigned short 实际写入的字符数量 */ - typedef unsigned short (*shellWrite)(const char *data, unsigned short len); + typedef unsigned short (*shellWrite)(char *data, unsigned short len); ``` 3. 申请一片缓冲区 diff --git a/demo/stm32-freertos/shell_cfg.h b/demo/stm32-freertos/shell_cfg.h index ae01e0d..7961fcf 100644 --- a/demo/stm32-freertos/shell_cfg.h +++ b/demo/stm32-freertos/shell_cfg.h @@ -13,6 +13,8 @@ #define __SHELL_CFG_H__ #include "stm32f4xx_hal.h" +#include "FreeRTOS.h" +#include "portable.h" /** @@ -33,12 +35,13 @@ * @brief 是否使用shell伴生对象 * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 */ -#define SHELL_USING_COMPANION 0 +#define SHELL_USING_COMPANION 1 + /** * @brief 支持shell尾行模式 */ -#define SHELL_SUPPORT_END_LINE 0 +#define SHELL_SUPPORT_END_LINE 1 /** * @brief 是否在输出命令列表中列出用户 @@ -64,7 +67,7 @@ * @brief 使用LF作为命令行回车触发 * 可以和SHELL_ENTER_CR同时开启 */ -#define SHELL_ENTER_LF 0 +#define SHELL_ENTER_LF 1 /** * @brief 使用CR作为命令行回车触发 @@ -113,6 +116,13 @@ */ #define SHELL_PRINT_BUFFER 128 +/** + * @brief shell格式化输入的缓冲大小 + * 为0时不使用shell格式化输入 + * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用 + */ +#define SHELL_SCAN_BUFFER 128 + /** * @brief 获取系统时间(ms) * 定义此宏为获取系统Tick,如`HAL_GetTick()` @@ -120,17 +130,23 @@ */ #define SHELL_GET_TICK() HAL_GetTick() +/** + * @brief 使用锁 + * @note 使用shell锁时,需要对加锁和解锁进行实现 + */ +#define SHELL_USING_LOCK 1 + /** * @brief shell内存分配 * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 */ -#define SHELL_MALLOC(size) 0 +#define SHELL_MALLOC(size) pvPortMalloc(size) /** * @brief shell内存释放 * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 */ -#define SHELL_FREE(obj) 0 +#define SHELL_FREE(obj) vPortFree(obj) /** * @brief 是否显示shell信息 @@ -162,3 +178,4 @@ #define SHELL_LOCK_TIMEOUT 0 * 60 * 1000 #endif + diff --git a/demo/stm32-freertos/shell_port.c b/demo/stm32-freertos/shell_port.c index 916469c..7369c97 100644 --- a/demo/stm32-freertos/shell_port.c +++ b/demo/stm32-freertos/shell_port.c @@ -9,23 +9,33 @@ * */ +#include "FreeRTOS.h" +#include "task.h" #include "shell.h" #include "serial.h" #include "stm32f4xx_hal.h" #include "usart.h" +#include "cevent.h" +#include "log.h" Shell shell; char shellBuffer[512]; +static SemaphoreHandle_t shellMutex; + /** * @brief 用户shell写 * * @param data 数据 + * @param len 数据长度 + * + * @return short 实际写入的数据长度 */ -void userShellWrite(char data) +short userShellWrite(char *data, unsigned short len) { - serialTransmit(&debugSerial, (uint8_t *)&data, 1, 0xFF); + serialTransmit(&debugSerial, (uint8_t *)data, len, 0x1FF); + return len; } @@ -33,21 +43,40 @@ void userShellWrite(char data) * @brief 用户shell读 * * @param data 数据 - * @return char 状态 + * @param len 数据长度 + * + * @return short 实际读取到 */ -signed char userShellRead(char *data) +short userShellRead(char *data, unsigned short len) { - if (serialReceive(&debugSerial, (uint8_t *)data, 1, 0) == 1) - { - return 0; - } - else - { - return -1; - } - + return serialReceive(&debugSerial, (uint8_t *)data, len, 0); } +/** + * @brief 用户shell上锁 + * + * @param shell shell + * + * @return int 0 + */ +int userShellLock(Shell *shell) +{ + xSemaphoreTakeRecursive(shellMutex, portMAX_DELAY); + return 0; +} + +/** + * @brief 用户shell解锁 + * + * @param shell shell + * + * @return int 0 + */ +int userShellUnlock(Shell *shell) +{ + xSemaphoreGiveRecursive(shellMutex); + return 0; +} /** * @brief 用户shell初始化 @@ -55,8 +84,17 @@ signed char userShellRead(char *data) */ void userShellInit(void) { + shellMutex = xSemaphoreCreateMutex(); + shell.write = userShellWrite; shell.read = userShellRead; + shell.lock = userShellLock; + shell.unlock = userShellUnlock; shellInit(&shell, shellBuffer, 512); + if (xTaskCreate(shellTask, "shell", 256, &shell, 5, NULL) != pdPASS) + { + logError("shell task creat failed"); + } } +CEVENT_EXPORT(EVENT_INIT_STAGE2, userShellInit); diff --git a/extensions/cpp_support/shell_cpp.h b/extensions/cpp_support/shell_cpp.h index 2ae951d..946d83f 100644 --- a/extensions/cpp_support/shell_cpp.h +++ b/extensions/cpp_support/shell_cpp.h @@ -139,7 +139,7 @@ typedef struct shell_command_cpp_key const char shellDesc##_value[] = #_desc; \ extern "C" SHELL_USED const ShellCommandCppKey \ shellKey##_value SHELL_SECTION("shellCommand") = \ - { \ + { \ _attr|SHELL_CMD_TYPE(SHELL_TYPE_KEY), \ _value, \ (void (*)(Shell *))_func, \ @@ -152,3 +152,4 @@ typedef struct shell_command_cpp_key #endif /**< __SHELL_CPP_H__ */ + diff --git a/src/shell.c b/src/shell.c index 803616d..a5daebc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -258,7 +258,7 @@ Shell* shellGetCurrent(void) * @param shell shell对象 * @param data 字符数据 */ -static void shellWriteByte(Shell *shell, const char data) +static void shellWriteByte(Shell *shell, char data) { shell->write(&data, 1); } @@ -275,13 +275,13 @@ static void shellWriteByte(Shell *shell, const char data) unsigned short shellWriteString(Shell *shell, const char *string) { unsigned short count = 0; - char *p = string; + const char *p = string; SHELL_ASSERT(shell->write, return 0); while(*p++) { count ++; } - return shell->write(string, count); + return shell->write((char *)string, count); } @@ -296,7 +296,7 @@ unsigned short shellWriteString(Shell *shell, const char *string) static unsigned short shellWriteCommandDesc(Shell *shell, const char *string) { unsigned short count = 0; - char *p = string; + const char *p = string; SHELL_ASSERT(shell->write, return 0); while (*p && *p != '\r' && *p != '\n') { @@ -306,12 +306,12 @@ static unsigned short shellWriteCommandDesc(Shell *shell, const char *string) if (count > 36) { - shell->write(string, 36); + shell->write((char *)string, 36); shell->write("...", 3); } else { - shell->write(string, count); + shell->write((char *)string, count); } return count > 36 ? 36 : 39; } @@ -389,7 +389,7 @@ void shellScan(Shell *shell, char *fmt, ...) do { if (shell->read(&buffer[index], 1) == 1) { - shell->write(buffer[index], 1); + shell->write(&buffer[index], 1); index++; } } while (buffer[index -1] != '\r' && buffer[index -1] != '\n' && index < SHELL_SCAN_BUFFER); @@ -1757,7 +1757,7 @@ void shellWriteEndLine(Shell *shell, char *buffer, int len) shellWriteString(shell, shell->parser.buffer); for (short i = 0; i < shell->parser.length - shell->parser.cursor; i++) { - shell->write('\b', 1); + shellWriteByte(shell, '\b'); } } } @@ -1927,3 +1927,4 @@ SHELL_EXPORT_CMD( SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN, exec, shellExecute, execute function undefined); #endif + diff --git a/src/shell.h b/src/shell.h index fad42a9..5f2aa56 100644 --- a/src/shell.h +++ b/src/shell.h @@ -360,7 +360,7 @@ typedef struct shell_def unsigned char tabFlag : 1; /**< tab标志 */ } status; signed short (*read)(char *, unsigned short); /**< shell读函数 */ - signed short (*write)(const 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 解锁 */ @@ -461,3 +461,4 @@ void *shellCompanionGet(Shell *shell, int id); #endif +