上一期配置完FreeRTOS的環(huán)境后,這一期記錄自己關(guān)于任務(wù)創(chuàng)建的學習過程。
官方的API手冊中有這些函數(shù),xTaskCreate和xTaskCreateStatic分別是利用動態(tài)方法和靜態(tài)方法創(chuàng)建任務(wù)。(動態(tài)和靜態(tài)的區(qū)別之后再研究)vTaskDelete是刪除任務(wù),因為freeRTOS的任務(wù)內(nèi)存空間存儲在堆區(qū),所以很像C語言的動態(tài)內(nèi)存分配,任務(wù)使用和結(jié)束我們都應(yīng)該創(chuàng)建和刪除這些任務(wù)防止占用過多空間。
xTaskCreate的函數(shù)模型如下,參數(shù)內(nèi)容總共有六項:任務(wù)函數(shù)的函數(shù)指針,任務(wù)函數(shù)的名稱,任務(wù)函數(shù)所需堆??臻g,任務(wù)函數(shù)的類型,任務(wù)函數(shù)的優(yōu)先級,以及任務(wù)函數(shù)的函數(shù)句柄
vTaskDelete的函數(shù)模型如下,參數(shù)內(nèi)容為函數(shù)句柄,如果為NULL則刪除該任務(wù)本身。
因此我們創(chuàng)建任務(wù)的步驟是:首先定義一個啟動任務(wù),該任務(wù)是為了啟動我們的真正任務(wù),因此在調(diào)用完一遍后要用vTaskDelete 中輸入NULL刪除啟動函數(shù)本身。
任務(wù)函數(shù)編寫
/*
LED1翻轉(zhuǎn)
*/
void LED_TOG(void * pvParameters)//參數(shù)為 void * pvParameters
{
while(1)
{
printf("LED_TOG runningrn");//串口打印運行信息
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);//LED1翻轉(zhuǎn)
vTaskDelay(500);//延遲500ms
}
}
要注意的是vTaskDelay是FreeRTOS用來延時的函數(shù)。
之后我們要創(chuàng)建任務(wù)函數(shù)的啟動函數(shù)
TaskHandle_t Start_LED_Handler;
void Start_LED(void * pvParameters)
{
xTaskCreate((TaskFunction_t )LED_TOG,//任務(wù)函數(shù)
(char * )"LED_TOG",//任務(wù)名稱
(configSTACK_DEPTH_TYPE) 128,//堆棧空間128Byte
(void* ) NULL,//無返回
(UBaseType_t ) 1,//優(yōu)先級1
(TaskHandle_t * )LED_TOG_Handler);//任務(wù)函數(shù)句柄
vTaskDelete(NULL);
}
我們創(chuàng)建啟動任務(wù)的函數(shù),將 任務(wù)函數(shù)的函數(shù)指針,任務(wù)函數(shù)的名稱,任務(wù)函數(shù)所需堆??臻g,任務(wù)函數(shù)的類型,任務(wù)函數(shù)的優(yōu)先級,以及任務(wù)函數(shù)的函數(shù)句柄 ,填入vTaskCreate函數(shù)中,其中每個參數(shù)都使用了強制類型轉(zhuǎn)換防止出現(xiàn)錯誤。
同樣的方法,我們創(chuàng)建啟動 啟動函數(shù)的任務(wù)(有點繞口因為啟動函數(shù)本身是一個任務(wù))
void FreeRTOS_Init()
{
xTaskCreate((TaskFunction_t )Start_LED,
(char * )"Start_LED",
(configSTACK_DEPTH_TYPE) 128,
(void* ) NULL,
(UBaseType_t ) 0,
(TaskHandle_t * )Start_LED_Handler);
vTaskStartScheduler();//啟動運行函數(shù)
}
這樣子我們在主函數(shù)中添加剛剛定義的啟動啟動函數(shù)
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
KEY_Init();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
FreeRTOS_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
我們的代碼就可以正常運行啦!
我們在用上述的方法實現(xiàn)兩個燈一起翻轉(zhuǎn)
還是先編輯任務(wù)函數(shù)如下,并且定義其相關(guān)句柄
TaskHandle_t LED_TOG2_Handler;
void LED_TOG2(void * pvParameters)//參數(shù)為 void * pvParameters
{
while(1)
{
printf("LED_TOG runningrn");//串口打印運行信息
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);//LED0翻轉(zhuǎn)
vTaskDelay(500);//延遲500ms
}
}
在任務(wù)啟動函數(shù)中加入我們新建的任務(wù)。
void Start_LED(void * pvParameters)
{
xTaskCreate((TaskFunction_t )LED_TOG,//任務(wù)函數(shù)
(char * )"LED_TOG",//任務(wù)名稱
(configSTACK_DEPTH_TYPE) 128,//堆棧空間128Byte
(void* ) NULL,//無返回
(UBaseType_t ) 1,//優(yōu)先級1
(TaskHandle_t * )LED_TOG_Handler);//任務(wù)函數(shù)句柄
xTaskCreate((TaskFunction_t )LED_TOG2,//任務(wù)函數(shù)
(char * )"LED_TOG2",//任務(wù)名稱
(configSTACK_DEPTH_TYPE) 128,//堆??臻g128Byte
(void* ) NULL,//無返回
(UBaseType_t ) 2,//優(yōu)先級2
(TaskHandle_t * )LED_TOG2_Handler);//任務(wù)函數(shù)句柄
vTaskDelete(NULL);
}
再次運行我們的代碼。
麥克阿瑟將軍曾說過:點燈對于嵌入式來說,就像Hello World對于程序員一樣重要。我們不能不去點燈,就像西方不能失去耶路撒冷。
-
C語言
+關(guān)注
關(guān)注
180文章
7581瀏覽量
135544 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4256瀏覽量
62223 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
483瀏覽量
61849 -
STM32F407
+關(guān)注
關(guān)注
15文章
187瀏覽量
29288
發(fā)布評論請先 登錄
相關(guān)推薦
評論