/** * @file shell_port.c */ #include "shell.h" #include "stm32f4xx_hal.h" #include "usart.h" #include "shell_port.h" Shell shell; char shellBuffer[512]; // 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初始化 * */ void userShellInit(void) { shell.write = userShellWrite; shell.read = userShellRead; shell.lock = NULL; shell.unlock = NULL; 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); } // 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);