freertos_f407/User/system/letter_shell/shell_port.c

142 lines
3.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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);