/** * @file shell_port.c */ #include "FreeRTOS.h" #include "task.h" #include "shell.h" #include "stm32f4xx_hal.h" #include "usart.h" #include "shell_port.h" #include "semphr.h" Shell shell; char shellBuffer[512]; static SemaphoreHandle_t shellMutex; // DMA接收缓冲区和shell环形缓冲区 #define SHELL_UART_DMA_BUF_SIZE 256 #define SHELL_UART_RX_BUF_SIZE 128 static uint8_t shell_uart_dma_buf[SHELL_UART_DMA_BUF_SIZE]; static uint8_t shell_uart_rx_buf[SHELL_UART_RX_BUF_SIZE]; static volatile uint16_t shell_uart_rx_head = 0; static volatile uint16_t shell_uart_rx_tail = 0; static volatile uint16_t shell_uart_dma_last_pos = 0; /** * @brief 用户shell写 * * @param data 数据 * @param len 数据长度 * * @return short 实际写入的数据长度 */ short userShellWrite(char *data, unsigned short len) { HAL_UART_Transmit(&huart1, (uint8_t *)data, len, 0x1FF); return len; } /** * @brief 用户shell读 * * @param data 数据 * @param len 数据长度 * * @return short 实际读取到 */ // 从环形缓冲区读取数据 short userShellRead(char *data, unsigned short len) { unsigned short count = 0; while (count < len) { if (shell_uart_rx_head == shell_uart_rx_tail) { // 缓冲区无数据 break; } data[count++] = shell_uart_rx_buf[shell_uart_rx_tail]; shell_uart_rx_tail = (shell_uart_rx_tail + 1) % SHELL_UART_RX_BUF_SIZE; } return count; } /** * @brief 用户shell上锁 * * @param shell shell * * @return int 0 */ int userShellLock(Shell *shell) { // xSemaphoreTakeRecursive(shellMutex, portMAX_DELAY); xSemaphoreTake(shellMutex, portMAX_DELAY); return 0; } /** * @brief 用户shell解锁 * * @param shell shell * * @return int 0 */ int userShellUnlock(Shell *shell) { // xSemaphoreGiveRecursive(shellMutex); xSemaphoreGive(shellMutex); return 0; } /** * @brief 用户shell初始化 * */ void userShellInit(void) { shellMutex = xSemaphoreCreateMutex(); shell.write = userShellWrite; shell.read = userShellRead; shell.lock = userShellLock; shell.unlock = userShellUnlock; shellInit(&shell, shellBuffer, 512); // 启动DMA接收 HAL_UART_Receive_DMA(&huart1, shell_uart_dma_buf, SHELL_UART_DMA_BUF_SIZE); // 使能空闲中断 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); xTaskCreate((TaskFunction_t)shellTask, // 任务入口函数 (const char *)"shell_task", // 任务名字 (uint16_t)1024, // 任务栈大小 (void *)&shell, // 任务入口函数参数(传递 shell 对象指针) (UBaseType_t)1, // 任务优先级 NULL); // 任务句柄 } // USART1 空闲中断处理(DMA新数据转入shell缓冲区) void shell_uart_rx_idle_callback(void) { uint16_t dma_pos = SHELL_UART_DMA_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx); uint16_t data_len = (dma_pos >= shell_uart_dma_last_pos) ? (dma_pos - shell_uart_dma_last_pos) : (SHELL_UART_DMA_BUF_SIZE - shell_uart_dma_last_pos + dma_pos); for (uint16_t i = 0; i < data_len; i++) { uint8_t ch = shell_uart_dma_buf[(shell_uart_dma_last_pos + i) % SHELL_UART_DMA_BUF_SIZE]; uint16_t next = (shell_uart_rx_head + 1) % SHELL_UART_RX_BUF_SIZE; if (next != shell_uart_rx_tail) { shell_uart_rx_buf[shell_uart_rx_head] = ch; shell_uart_rx_head = next; } } shell_uart_dma_last_pos = dma_pos; } // CEVENT_EXPORT(EVENT_INIT_STAGE2, userShellInit);