/** * @file shell_port.c * @author Letter (NevermindZZT@gmail.com) * @brief * @version 0.1 * @date 2019-02-22 * * @copyright (c) 2019 Letter * */ #include "publicdata/public_define.h" #if (MY_SHELL_EN) #include "shell.h" #include #include #include "FreeRTOS.h" #include "semphr.h" #include "task.h" #include "usart.h" #include "wdt_task/wdt_task.h" #include "app_init/app_init.h" Shell shell; char shellBuffer[512]; #define SHELL_USART_ID ((E_USART_ID)DEBUG_SHELL_USART_ID) static SemaphoreHandle_t shellMutex; /** * @brief 用户shell写 * * @param data 数据 * @param len 数据长度 * * @return short 实际写入的数据长度 */ short userShellWrite(char *data, unsigned short len) { if ((uint8_t)DEBUG_SHELL_USART_ID == (uint8_t)DEBUG_SHELL_USART_NULL) { return 0; } u16_usart_send(SHELL_USART_ID,(uint8_t *)data,len); return len; } /** * @brief 用户shell读 * * @param data 数据 * @param len 数据长度 * * @return short 实际读取到 */ short userShellRead(char *data, unsigned short len) { short recv_len; if ((uint8_t)DEBUG_SHELL_USART_ID == (uint8_t)DEBUG_SHELL_USART_NULL) { return 0; } recv_len = u16_usart_recv(SHELL_USART_ID,(uint8_t *)data,len); return recv_len; } /** * @brief 用户shell上锁 * * @param shell shell * * @return int 0 */ int userShellLock(Shell *shell) { (void)shell; if (shellMutex != NULL) { (void)xSemaphoreTakeRecursive(shellMutex, portMAX_DELAY); } return 0; } /** * @brief 用户shell解锁 * * @param shell shell * * @return int 0 */ int userShellUnlock(Shell *shell) { (void)shell; if (shellMutex != NULL) { (void)xSemaphoreGiveRecursive(shellMutex); } return 0; } /** * @brief 用户shell初始化 * */ void userShellInit(void) { if ((uint8_t)DEBUG_SHELL_USART_ID == (uint8_t)DEBUG_SHELL_USART_NULL) { return; } shellMutex = xSemaphoreCreateRecursiveMutex(); shell.write = userShellWrite; shell.read = userShellRead; shell.lock = userShellLock; shell.unlock = userShellUnlock; shellInit(&shell, shellBuffer, 512); } //CEVENT_EXPORT(EVENT_INIT_STAGE2, userShellInit); void v_myshell_task(void *argument) { for (;;) { v_wdt_setFlag(TASK_ID_MyShell); shellTask(argument); /* shellTask 内部有 while(1) + vTaskDelay(10ms), * 正常情况下不会执行到这里;若返回则重新进入 */ mSleep(10U); } } #else /* MY_SHELL_EN */ /* 关闭 Shell 时,该文件不产生任何可执行代码 */ #endif /* MY_SHELL_EN */ /************************************************************************************* */ #if (MY_SHELL_EN) unsigned short shell_send_String(const char *string) { unsigned short count = 0; const char *p = string; SHELL_ASSERT(shell.write, return 0); while(*p++) { count ++; } return shell.write((char *)string, count); } #define SHELL_PRINT_BUFFER_SIZE 256 // 可调整缓冲区大小 // 类似printf的格式化输出函数 void v_shell_print(const char *format, ...) { va_list args; char buffer[SHELL_PRINT_BUFFER_SIZE]; int len; // 1. 处理可变参数 va_start(args, format); // 2. 安全格式化字符串 len = vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); // 3. 校验长度有效性 if(len <= 0) return; // 格式化失败 if(len >= (int)sizeof(buffer)) { // 截断到最大长度 buffer[sizeof(buffer) - 1] = '\0'; len = sizeof(buffer) - 1; } // 4. 发送数据到串口 if(len > 0) { if ((uint8_t)DEBUG_SHELL_USART_ID == (uint8_t)DEBUG_SHELL_USART_NULL) { return; } u16_usart_send(SHELL_USART_ID, (uint8_t *)buffer, (uint16_t)len); } } #endif /* MY_SHELL_EN */