372 lines
11 KiB
C
372 lines
11 KiB
C
/* USER CODE BEGIN Header */
|
|
/**
|
|
******************************************************************************
|
|
* File Name : freertos.c
|
|
* Description : Code for freertos applications
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2025 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
/* USER CODE END Header */
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "main.h"
|
|
#include "cmsis_os.h"
|
|
|
|
/* Private includes ----------------------------------------------------------*/
|
|
/* USER CODE BEGIN Includes */
|
|
#include "stdio.h"
|
|
#include "stdlib.h"
|
|
#include "string.h"
|
|
|
|
// #include "usart.h"
|
|
|
|
#include "remote_control.h"
|
|
#include "CToC.h"
|
|
/* USER CODE END Includes */
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* USER CODE BEGIN PTD */
|
|
extern CAN_HandleTypeDef hcan1;
|
|
extern CAN_HandleTypeDef hcan2;
|
|
extern DMA_HandleTypeDef hdma_usart1_tx;
|
|
extern DMA_HandleTypeDef hdma_usart3_rx;
|
|
extern UART_HandleTypeDef huart1;
|
|
extern UART_HandleTypeDef huart3;
|
|
/* USER CODE END PTD */
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
/* USER CODE BEGIN PD */
|
|
uint8_t receiveData[18];
|
|
|
|
// RC_ctrl_t rc_control = {0};
|
|
|
|
uint8_t num = 0;
|
|
|
|
/* USER CODE END PD */
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* USER CODE BEGIN PM */
|
|
|
|
/* USER CODE END PM */
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
/* USER CODE BEGIN Variables */
|
|
|
|
/* USER CODE END Variables */
|
|
/* Definitions for DebugTask */
|
|
osThreadId_t DebugTaskHandle;
|
|
const osThreadAttr_t DebugTask_attributes = {
|
|
.name = "DebugTask",
|
|
.stack_size = 128 * 4,
|
|
.priority = (osPriority_t) osPriorityNormal,
|
|
};
|
|
/* Definitions for MoveTask */
|
|
osThreadId_t MoveTaskHandle;
|
|
const osThreadAttr_t MoveTask_attributes = {
|
|
.name = "MoveTask",
|
|
.stack_size = 128 * 4,
|
|
.priority = (osPriority_t) osPriorityHigh,
|
|
};
|
|
/* Definitions for TurnTask */
|
|
osThreadId_t TurnTaskHandle;
|
|
const osThreadAttr_t TurnTask_attributes = {
|
|
.name = "TurnTask",
|
|
.stack_size = 128 * 4,
|
|
.priority = (osPriority_t) osPriorityLow,
|
|
};
|
|
/* Definitions for StatuTask */
|
|
osThreadId_t StatuTaskHandle;
|
|
const osThreadAttr_t StatuTask_attributes = {
|
|
.name = "StatuTask",
|
|
.stack_size = 128 * 4,
|
|
.priority = (osPriority_t) osPriorityLow,
|
|
};
|
|
/* Definitions for Move_R_Queue */
|
|
osMessageQueueId_t Move_R_QueueHandle;
|
|
const osMessageQueueAttr_t Move_R_Queue_attributes = {
|
|
.name = "Move_R_Queue"
|
|
};
|
|
/* Definitions for Turn_Queue */
|
|
osMessageQueueId_t Turn_QueueHandle;
|
|
const osMessageQueueAttr_t Turn_Queue_attributes = {
|
|
.name = "Turn_Queue"
|
|
};
|
|
/* Definitions for Statu_Queue */
|
|
osMessageQueueId_t Statu_QueueHandle;
|
|
const osMessageQueueAttr_t Statu_Queue_attributes = {
|
|
.name = "Statu_Queue"
|
|
};
|
|
/* Definitions for Move_L_Queue */
|
|
osMessageQueueId_t Move_L_QueueHandle;
|
|
const osMessageQueueAttr_t Move_L_Queue_attributes = {
|
|
.name = "Move_L_Queue"
|
|
};
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
/* USER CODE BEGIN FunctionPrototypes */
|
|
|
|
/* USER CODE END FunctionPrototypes */
|
|
|
|
void StartDebugTask(void *argument);
|
|
void StartMoveTask(void *argument);
|
|
void StartTurnTask(void *argument);
|
|
void StartStatuTask(void *argument);
|
|
|
|
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
|
|
|
/**
|
|
* @brief FreeRTOS initialization
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void MX_FREERTOS_Init(void) {
|
|
/* USER CODE BEGIN Init */
|
|
|
|
/* USER CODE END Init */
|
|
|
|
/* USER CODE BEGIN RTOS_MUTEX */
|
|
/* add mutexes, ... */
|
|
/* USER CODE END RTOS_MUTEX */
|
|
|
|
/* USER CODE BEGIN RTOS_SEMAPHORES */
|
|
/* add semaphores, ... */
|
|
/* USER CODE END RTOS_SEMAPHORES */
|
|
|
|
/* USER CODE BEGIN RTOS_TIMERS */
|
|
/* start timers, add new ones, ... */
|
|
/* USER CODE END RTOS_TIMERS */
|
|
|
|
/* Create the queue(s) */
|
|
/* creation of Move_R_Queue */
|
|
Move_R_QueueHandle = osMessageQueueNew (16, sizeof(MOVE_BUFFER_SIZE), &Move_R_Queue_attributes);
|
|
|
|
/* creation of Turn_Queue */
|
|
Turn_QueueHandle = osMessageQueueNew (16, sizeof(TURN_BUFFER_SIZE), &Turn_Queue_attributes);
|
|
|
|
/* creation of Statu_Queue */
|
|
Statu_QueueHandle = osMessageQueueNew (16, sizeof(STATUS_BUFFER_SIZE), &Statu_Queue_attributes);
|
|
|
|
/* creation of Move_L_Queue */
|
|
Move_L_QueueHandle = osMessageQueueNew (16, sizeof(uint16_t), &Move_L_Queue_attributes);
|
|
|
|
/* USER CODE BEGIN RTOS_QUEUES */
|
|
/* add queues, ... */
|
|
/* USER CODE END RTOS_QUEUES */
|
|
|
|
/* Create the thread(s) */
|
|
/* creation of DebugTask */
|
|
DebugTaskHandle = osThreadNew(StartDebugTask, NULL, &DebugTask_attributes);
|
|
|
|
/* creation of MoveTask */
|
|
MoveTaskHandle = osThreadNew(StartMoveTask, NULL, &MoveTask_attributes);
|
|
|
|
/* creation of TurnTask */
|
|
TurnTaskHandle = osThreadNew(StartTurnTask, NULL, &TurnTask_attributes);
|
|
|
|
/* creation of StatuTask */
|
|
StatuTaskHandle = osThreadNew(StartStatuTask, NULL, &StatuTask_attributes);
|
|
|
|
/* USER CODE BEGIN RTOS_THREADS */
|
|
/* add threads, ... */
|
|
/* USER CODE END RTOS_THREADS */
|
|
|
|
/* USER CODE BEGIN RTOS_EVENTS */
|
|
/* add events, ... */
|
|
/* USER CODE END RTOS_EVENTS */
|
|
|
|
}
|
|
|
|
/* USER CODE BEGIN Header_StartDebugTask */
|
|
/**
|
|
* @brief Function implementing the DebugTask thread.
|
|
* @param argument: Not used
|
|
* @retval None
|
|
*/
|
|
/* USER CODE END Header_StartDebugTask */
|
|
void StartDebugTask(void *argument)
|
|
{
|
|
/* USER CODE BEGIN StartDebugTask */
|
|
osDelay(10);
|
|
printf("Start Remote Task\r\n");
|
|
HAL_UARTEx_ReceiveToIdle_DMA(&huart3, receiveData, sizeof(receiveData));
|
|
/* Infinite loop */
|
|
for (;;)
|
|
{
|
|
printf("hello world\r\n");
|
|
HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);
|
|
osDelay(750);
|
|
HAL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin);
|
|
osDelay(750);
|
|
HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
|
|
osDelay(750);
|
|
}
|
|
/* USER CODE END StartDebugTask */
|
|
}
|
|
|
|
/* USER CODE BEGIN Header_StartMoveTask */
|
|
/**
|
|
* @brief Function implementing the MoveTask thread.
|
|
* @param argument: Not used
|
|
* @retval None
|
|
*/
|
|
/* USER CODE END Header_StartMoveTask */
|
|
__weak void StartMoveTask(void *argument)
|
|
{
|
|
/* USER CODE BEGIN StartMoveTask */
|
|
uint8_t moveBuffer[MOVE_BUFFER_SIZE];
|
|
uint8_t turnBuffer[TURN_BUFFER_SIZE];
|
|
int16_t moveData[4];
|
|
|
|
/* Infinite loop */
|
|
for (;;)
|
|
{
|
|
if (osMessageQueueGet(Move_R_QueueHandle, moveBuffer, NULL, osWaitForever) == osOK)
|
|
{
|
|
memcpy(&moveData[0], moveBuffer, sizeof(int16_t));
|
|
memcpy(&moveData[1], moveBuffer + sizeof(int16_t), sizeof(int16_t));
|
|
|
|
};
|
|
if (osMessageQueueGet(Move_L_QueueHandle, turnBuffer, NULL, osWaitForever) == osOK)
|
|
{
|
|
memcpy(&moveData[2], turnBuffer, sizeof(int16_t));
|
|
memcpy(&moveData[3], turnBuffer + sizeof(int16_t), sizeof(int16_t));
|
|
|
|
};
|
|
CToC_MasterSendData(moveData[0], moveData[1], moveData[2], moveData[3]);
|
|
}
|
|
/* USER CODE END StartMoveTask */
|
|
}
|
|
|
|
/* USER CODE BEGIN Header_StartTurnTask */
|
|
/**
|
|
* @brief Function implementing the TurnTask thread.
|
|
* @param argument: Not used
|
|
* @retval None
|
|
*/
|
|
/* USER CODE END Header_StartTurnTask */
|
|
__weak void StartTurnTask(void *argument)
|
|
{
|
|
/* USER CODE BEGIN StartTurnTask */
|
|
uint8_t turnBuffer[TURN_BUFFER_SIZE];
|
|
int16_t turnData[2];
|
|
/* Infinite loop */
|
|
for (;;)
|
|
{
|
|
if (osMessageQueueGet(Turn_QueueHandle, turnBuffer, NULL, osWaitForever) == osOK)
|
|
{
|
|
memcpy(&turnData[0], turnBuffer, sizeof(int16_t));
|
|
memcpy(&turnData[1], turnBuffer + sizeof(int16_t), sizeof(int16_t));
|
|
// 处理转向数据
|
|
// printf("Turn Data: %d, %d\r\n", turnData[0], turnData[1]);
|
|
};
|
|
osDelay(10);
|
|
}
|
|
/* USER CODE END StartTurnTask */
|
|
}
|
|
|
|
/* USER CODE BEGIN Header_StartStatuTask */
|
|
/**
|
|
* @brief Function implementing the StatuTask thread.
|
|
* @param argument: Not used
|
|
* @retval None
|
|
*/
|
|
/* USER CODE END Header_StartStatuTask */
|
|
__weak void StartStatuTask(void *argument)
|
|
{
|
|
/* USER CODE BEGIN StartStatuTask */
|
|
uint8_t statusBuffer[STATUS_BUFFER_SIZE];
|
|
uint8_t statusData[2];
|
|
/* Infinite loop */
|
|
for (;;)
|
|
{
|
|
if (osMessageQueueGet(Statu_QueueHandle, statusBuffer, NULL, osWaitForever) == osOK)
|
|
{
|
|
memcpy(&statusData[0], statusBuffer, sizeof(uint8_t));
|
|
memcpy(&statusData[1], statusBuffer + sizeof(uint8_t), sizeof(uint8_t));
|
|
// 处理状态数据
|
|
// printf("Status Data: %d, %d\r\n", statusData[0], statusData[1]);
|
|
};
|
|
}
|
|
/* USER CODE END StartStatuTask */
|
|
}
|
|
|
|
/* Private application code --------------------------------------------------*/
|
|
/* USER CODE BEGIN Application */
|
|
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
|
|
{
|
|
uint8_t Message_Remote[18] = {0};
|
|
RC_ctrl_t rc_control = {0};
|
|
if (huart->Instance == USART3 && Size > 0 && Size <= sizeof(receiveData))
|
|
{
|
|
memcpy(Message_Remote, receiveData, Size);
|
|
Message_Remote_to_rc(Message_Remote, &rc_control);
|
|
|
|
// 调试显示
|
|
// num++;
|
|
// if (num >= 25)
|
|
// {
|
|
// printf("Raw data: ");
|
|
// for (int i = 0; i < Size; i++)
|
|
// {
|
|
// printf("%02X ", receiveData[i]);
|
|
// }
|
|
// printf("\r\n");
|
|
// printf("RC Channels: %d,%d,%d,%d,%d\n",
|
|
// rc_control.rc.ch[0], rc_control.rc.ch[1],
|
|
// rc_control.rc.ch[2], rc_control.rc.ch[3], rc_control.rc.ch[4]);
|
|
// printf("Switch: %d,%d\n",
|
|
// rc_control.rc.s[0], rc_control.rc.s[1]);
|
|
// num = 0;
|
|
// }
|
|
|
|
// 创建三个独立的缓冲区
|
|
uint8_t moveBuffer[MOVE_BUFFER_SIZE];
|
|
uint8_t turnBuffer[TURN_BUFFER_SIZE];
|
|
uint8_t statusBuffer[STATUS_BUFFER_SIZE];
|
|
|
|
// 移动数据
|
|
memcpy(moveBuffer, &rc_control.rc.ch[0], sizeof(int16_t));
|
|
memcpy(moveBuffer + sizeof(int16_t), &rc_control.rc.ch[1], sizeof(int16_t));
|
|
osMessageQueuePut(Move_R_QueueHandle, moveBuffer, 0, 0);
|
|
|
|
// 转向数据
|
|
memcpy(turnBuffer, &rc_control.rc.ch[2], sizeof(int16_t));
|
|
memcpy(turnBuffer + sizeof(int16_t), &rc_control.rc.ch[3], sizeof(int16_t));
|
|
osMessageQueuePut(Turn_QueueHandle, turnBuffer, 0, 0);
|
|
osMessageQueuePut(Move_L_QueueHandle, turnBuffer, 0, 0);
|
|
|
|
// 状态数据
|
|
memcpy(statusBuffer, &rc_control.rc.s[0], sizeof(uint8_t));
|
|
memcpy(statusBuffer + sizeof(uint8_t), &rc_control.rc.s[1], sizeof(uint8_t));
|
|
osMessageQueuePut(Statu_QueueHandle, statusBuffer, 0, 0);
|
|
|
|
// 清除 IDLE 中断标志
|
|
__HAL_UART_CLEAR_IDLEFLAG(huart);
|
|
|
|
// 重新启动IT接收
|
|
HAL_UARTEx_ReceiveToIdle_DMA(&huart3, receiveData, sizeof(receiveData));
|
|
|
|
// 禁止半传送中断
|
|
__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);
|
|
}
|
|
}
|
|
|
|
int _write(int fd, char *ptr, int len)
|
|
{
|
|
HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY);
|
|
return len;
|
|
}
|
|
/* USER CODE END Application */
|
|
|