freertos_f407/User/system/letter_shell/shell_port.c

136 lines
3.1 KiB
C

/**
* @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;
// 串口接收缓冲区(环形队列)
#define SHELL_UART_RX_BUF_SIZE 128
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 uint8_t shell_uart_rx_temp;
/**
* @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);
// 启动串口中断接收
HAL_UART_Receive_IT(&huart1, &shell_uart_rx_temp, 1);
xTaskCreate((TaskFunction_t)shellTask, // 任务入口函数
(const char *)"shell_task", // 任务名字
(uint16_t)1024, // 任务栈大小
(void *)&shell, // 任务入口函数参数(传递 shell 对象指针)
(UBaseType_t)1, // 任务优先级
NULL); // 任务句柄
}
// 串口接收完成回调(在 usart.c 里实现也可)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
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] = shell_uart_rx_temp;
shell_uart_rx_head = next;
}
// 继续接收下一个字节
HAL_UART_Receive_IT(&huart1, &shell_uart_rx_temp, 1);
}
}
// CEVENT_EXPORT(EVENT_INIT_STAGE2, userShellInit);