98 lines
2.6 KiB
C
98 lines
2.6 KiB
C
/**
|
||
* @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);
|