Pull to refresh

Comments 4

"Поместить туда код не так то просто. Я сделал файл обертку TaskWrapper.cpp + TaskWrapper.hpp, куда в хедер копирую прототип функции, а в cpp вырезаю с freertos.c саму функцию. И в файл прокладку подключаю файлы на C++. "
А я думал получится CMSIS-RTOS2 использовать в C++ проекте?

Таким же макаром создал проект с CMSIS_RTOS_V2, проект собирается и работает, пока разницы не заметил, только разница в именах функций RTOS обертки в отличии от первой версии, буду ковырять дальше.

ОС и C++ в Keil

В main.c можно экспортировать функции из .cpp:
extern void TempTask(void *pvParameters);
Задачи раскидать по соответствующим файлам и уже в них использовать c++

Можно и без extern, просто прототип прописывать. А тут получается наоборот, проект C++( main.cpp), а операционка на СИ. Я по сути так и сделал, задачи объявлены в одном месте куда куб их и проинициализировал. В этом файле куб сразу и объявит сверху прототипы обработчиков задач, т.к. сами функции обработчиков описаны ниже функций задачи, куда в качестве аргумента передается указатель на обработчик. Я создаю два файла TaskWrapper.hpp и TaskWrapper.cpp. В заголовочный прописываю прототипы обработчиков в вставке __cplusplus. Подключаю этот хедер в cpp и переношу туда сами обработчики из freertos.c. В этот файл подключаю с++-шные файлы.

Hidden text
#ifndef TASK_WRAPPER_H_
#define TASK_WRAPPER_H_


#ifdef __cplusplus
extern "C" {
#endif

void StartSensorTask(void const * argument);
void StartMainTask(void const * argument);
void StartCAN_RxTx_Task(void const * argument);

#ifdef __cplusplus
}
#endif

#endif
#include "TaskWrapper.hpp"
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"
#include "struct_init.hpp"

//extern osMessageQId MT6701_Data_Send_Queue;
//extern osMessageQId CANbus_Send_Queue;

//extern osThreadId Sensor_Processing_Task;
/* USER CODE BEGIN Header_StartDefaultTask */
/**
 * @brief  Function implementing the defaultTask thread.
 * @param  argument: Not used
 * @retval None
 */
//void Start_Sensor_Processing_Task(void const *argument)
//{
///  portBASE_TYPE xStatus;
 // MathAlgs::MovingAverageFilter <uint16_t, 8> s_data_average;
 // uint16_t s_data;
 // for (;;)
 // {
 //  xStatus = xQueueReceive(MT6701_Data_Send_Queue, &s_data, 0);//забираем данные из очереди
//   s_data = s_data_average.MAF_Handler(s_data);//фильтруем
 //  MathAlgs::Decreasing_digits_with_rounding(MT6701_Encoder.ConvertToDegrees_x1000(s_data), 2);//конвертируем угол
  // если прошло столько-то тиков, отправляем в очередь отправки кан
//    osDelay(1);
    //taskYIELD();
// }
//}

/**
 * @brief Function implementing the myTask02 thread.
 * @param argument: Not used
 * @retval None
 */
//void Start_MT6701_Get_Data_Task(void const *argument)
//{
  //for (;;)
  //{
    //забираем данные с датчика и суем в очередь
 //   xQueueSend(MT6701_Data_Send_Queue, MT6701_Encoder.Get_DataPoint(), 0);
 //   osDelay(4);

 // }
//}


/* USER CODE BEGIN Header_StartDefaultTask */
/**
 * @brief  Function implementing the defaultTask thread.
 * @param  argument: Not used
 * @retval None
 */
//void StartCAN_TxRx_Task(void const *argument)
//{
//  for (;;)
 // {
 //   osDelay(1);
 // }
//}


/*
* Сделать задачу периодической
void StartCAN_TxRx_Task(void const *argument)
{
  TickType_t xLastWakeTime;
  const TickType_t xDelay3ms = pdMS_TO_TICKS(3); //pdMS_TO_TICKS(3); /переводит миллисекунды в тики, можно обойтись без него, т.к. 1 тик равен одной мс
  for (;;)
  {
    vTaskDelayUntil(&xLastWakeTime, xDelay3ms);
  }
}
*/
/* USER CODE BEGIN Header_StartSensorTask */
/**
  * @brief  Function implementing the SensorTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartSensorTask */
void StartSensorTask(void const * argument)
{
  /* USER CODE BEGIN StartSensorTask */
  /* Infinite loop */
  for(;;)
  {

   gyro_ICM20600.readZaxisAcc(&anglezA);	
	 gyro_ICM20600.readXaxisAcc(&anglexA);
	 gyro_ICM20600.readYaxisAcc(&angleyA);
	 gyro_ICM20600.readZaxisGyro(&anglezG);
	 gyro_ICM20600.readXaxisGyro(&anglexG);
	 gyro_ICM20600.readYaxisGyro(&angleyG);
    CAN_LED.Toggle();
    osDelay(1);
  }
  /* USER CODE END StartSensorTask */
}

/* USER CODE BEGIN Header_StartMainTask */
/**
* @brief Function implementing the MainTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartMainTask */
void StartMainTask(void const * argument)
{
  /* USER CODE BEGIN StartMainTask */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartMainTask */
}

/* USER CODE BEGIN Header_StartCAN_RxTx_Task */
/**
* @brief Function implementing the CAN_RxTx_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartCAN_RxTx_Task */
void StartCAN_RxTx_Task(void const * argument)
{
  /* USER CODE BEGIN StartCAN_RxTx_Task */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartCAN_RxTx_Task */
}

Сгенерированный файл с задачами freertos.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 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 <main.hpp>
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId SensorTaskHandle;
osThreadId MainTaskHandle;
osThreadId CAN_RxTx_TaskHandle;
osMessageQId SensorQueueHandle;
osMessageQId CAN_Rx_QueueHandle;
osMessageQId CAN_Tx_QueueHandle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartSensorTask(void const * argument);
void StartMainTask(void const * argument);
void StartCAN_RxTx_Task(void const * argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
  *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
  *ppxIdleTaskStackBuffer = &xIdleStack[0];
  *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
  /* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */

/**
  * @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) */
  /* definition and creation of SensorQueue */
  osMessageQDef(SensorQueue, 16, uint16_t);
  SensorQueueHandle = osMessageCreate(osMessageQ(SensorQueue), NULL);

  /* definition and creation of CAN_Rx_Queue */
  osMessageQDef(CAN_Rx_Queue, 16, uint16_t);
  CAN_Rx_QueueHandle = osMessageCreate(osMessageQ(CAN_Rx_Queue), NULL);

  /* definition and creation of CAN_Tx_Queue */
  osMessageQDef(CAN_Tx_Queue, 4, uint16_t);
  CAN_Tx_QueueHandle = osMessageCreate(osMessageQ(CAN_Tx_Queue), NULL);

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* definition and creation of SensorTask */
  osThreadDef(SensorTask, StartSensorTask, osPriorityNormal, 0, 128);
  SensorTaskHandle = osThreadCreate(osThread(SensorTask), NULL);

  /* definition and creation of MainTask */
  osThreadDef(MainTask, StartMainTask, osPriorityNormal, 0, 128);
  MainTaskHandle = osThreadCreate(osThread(MainTask), NULL);

  /* definition and creation of CAN_RxTx_Task */
  osThreadDef(CAN_RxTx_Task, StartCAN_RxTx_Task, osPriorityIdle, 0, 128);
  CAN_RxTx_TaskHandle = osThreadCreate(osThread(CAN_RxTx_Task), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

}



/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

Если после сборки проекта не удалять файлы cubeIDE, то можно работать и в ней и в vscode. Только в cubeIDE нужно прописать путь к заголовкам и исходным "базовым" каталогам. Все ни как не могу узнать можно ли видеть глобальные переменные в риалтайме, а не по точке останова, в cubeIDE и в Keil с этим проблем нет. Здесь даже вопрос задал.

Hidden text

Sign up to leave a comment.

Articles