目錄
- 問題說明
- 解決步驟
- 驗證方案
- 總結
問題說明
STM32CUBE的freertos的任務創建十分簡單方便,但卻有一個麻煩:需要我們把要跑的任務具體代碼都寫進freertos.c的檔案里面,對于在對應檔案創建任務的伙伴來說,使用多執行緒任務時仍然比較麻煩,
問題舉例:原本有A,B,C三個任務,原來我們在各自A.c,B.c,C.c的檔案中寫好了A_task,B_task,C_task,只要在創多一個總任務檔案Start.c,里面創建好Star_task的freertos任務,然后在此任務內創建A_task,B_task,C_task的freertos任務,就可以實作總任務里面跑支線任務了,如下:
//void A_task(void * pvParameters);void B_task(void *pvParameters);void C_task(void * pvParameters);已經在A.c,B.c,C.c寫好
//Start.c里面的內容
#define A_TASK_PRO 19
#define A_STK_SIZE 512
TaskHandle_t A_Task_Handler;
void A_task(void * pvParameters);
#define B_TASK_PRO 18
#define B_STK_SIZE 256
TaskHandle_t B_Task_Handler;
void B_task(void * pvParameters);
#define C_TASK_PRO 17
#define C_STK_SIZE 256
TaskHandle_t C_Task_Handler;
void C_task(void * pvParameters);
#define START_TASK_PRO 1
#define START_STK_SIZE 256
TaskHandle_t Start_Task_Handler;
void start_task(void * pvParameters);
void start_task(void * pvParameters)
{
taskENTER_CRITICAL();
//create A_task
xTaskCreate((TaskFunction_t)A_task,
(char *)"A_task",
(uint16_t)A_STK_SIZE,
(void *)NULL,
(UBaseType_t)A_TASK_PRO,
(TaskHandle_t *)&A_Task_Handler);
//create B_task
xTaskCreate((TaskFunction_t)B_task,
(char *)"B_task",
(uint16_t)B_STK_SIZE,
(void *)NULL,
(UBaseType_t)B_TASK_PRO,
(TaskHandle_t *)&B_Task_Handler);
//create C_task
xTaskCreate((TaskFunction_t)C_task,
(char *)"C_task",
(uint16_t)C_STK_SIZE,
(void *)NULL,
(UBaseType_t)C_TASK_PRO,
(TaskHandle_t *)&C_Task_Handler);
vTaskDelete(Start_Task_Handler); //洗掉開始任務
taskEXIT_CRITICAL(); //退出臨界區
}
void create_start_task(void)
{
xTaskCreate((TaskFunction_t)start_task,
(char *)"start_task",
(uint16_t)START_STK_SIZE,
(void *)NULL,
(UBaseType_t)START_TASK_PRO,
(TaskHandle_t *)&Start_Task_Handler);
}
但在cube里面使用freertos創建任務時:

生成就會這樣,無法達到“嵌套”總任務跑支線任務效果,
void Start_Task(void const * argument)
{
/* USER CODE BEGIN Start_Task */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END Start_Task */
}
/* USER CODE BEGIN Header_A_Task */
/**
* @brief Function implementing the A thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_A_Task */
void A_Task(void const * argument)
{
/* USER CODE BEGIN A_Task */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END A_Task */
}
/* USER CODE BEGIN Header_B_Task */
/**
* @brief Function implementing the B thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_B_Task */
void B_Task(void const * argument)
{
/* USER CODE BEGIN B_Task */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END B_Task */
}
/* USER CODE BEGIN Header_C_Task */
/**
* @brief Function implementing the C thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_C_Task */
void C_Task(void const * argument)
{
/* USER CODE BEGIN C_Task */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END C_Task */
}
解決步驟
-
只在CUBE中創建一個Start_Task的任務并生成,

-
在USER下創建Start.c及Start.h檔案;

-
在Start_task.c檔案中的Start_task中創建A,B,C任務
osThreadId_t A_task_Handler;
const osThreadAttr_t A_task_attr = {
.name = "A_task",
.priority = (osPriority_t) osPriorityBelowNormal4,
.stack_size = 128 * 4
};
void A_task(void *argument);
osThreadId_t B_task_Handler;
const osThreadAttr_t B_task_attr = {
.name = "B_task",
.priority = (osPriority_t) osPriorityBelowNormal4,
.stack_size = 256 * 4
};
void B_task(void *argument);
osThreadId_t C_task_Handler;
const osThreadAttr_t C_task_attr = {
.name = "C_task",
.priority = (osPriority_t) osPriorityLow7,
.stack_size = 256 * 4
};
void C_task(void *argument);
4.在Core內freertos.c檔案內的start_task改
void Start_Task(void const * argument)
{
//create A_task
A_task_Handler = osThreadNew(A_task, NULL, &A_task_attr);
//create B_task
B_task_Handler = osThreadNew(B_task, NULL, &B_task_attr);
//create C_task
C_task_Handler = osThreadNew(C_task, NULL, &C_task_attr);
osThreadTerminate(osThreadGetId()); /* 結束自身 */
}
驗證方案
呼叫freertos的資訊狀態查詢和時間統計的api函式即可,
總結
只要創建一個Start.task任務就好,然后再創一個檔案里面放其他任務的創建,然后在官方生成的freertos.c里運行即可,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/261454.html
標籤:其他
