FreeRTOS基础教程第一章创建任务
1.硬件初始化
本章創(chuàng)建的任務(wù)需要用到開(kāi)發(fā)板上的 LED,所以先要將 LED 相關(guān)的函數(shù)初始化好, 為了方便以后統(tǒng)一管理板級(jí)外設(shè)的初始化,我們?cè)?main.c 文件中創(chuàng)建一個(gè) BSP_Init()函數(shù), 專(zhuān)門(mén)用于存放板級(jí)外設(shè)初始化函數(shù),
/************************************************************************ @ 函數(shù)名 : BSP_Init* @ 功能說(shuō)明: 板級(jí)外設(shè)初始化,所有板子上的初始化均可放在這個(gè)函數(shù)里面* @ 參數(shù) : * @ 返回值 : 無(wú)*********************************************************************/ static void BSP_Init(void) {/** STM32中斷優(yōu)先級(jí)分組為4,即4bit都用來(lái)表示搶占優(yōu)先級(jí),范圍為:0~15* 優(yōu)先級(jí)分組只需要分組一次即可,以后如果有其他的任務(wù)需要用到中斷,* 都統(tǒng)一用這個(gè)優(yōu)先級(jí)分組,千萬(wàn)不要再分組,切忌。*/NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );/* LED 初始化 */LED_GPIO_Config();/* 串口初始化 */USART_Config();}? ? ?執(zhí)行到 BSP_Init()函數(shù)的時(shí)候,操作系統(tǒng)完全都還沒(méi)有涉及到,即 BSP_Init()函數(shù)所做 的工作跟我們以前編寫(xiě)的裸機(jī)工程里面的硬件初始化工作是一模一樣的。運(yùn)行完 BSP_Init () 函數(shù),接下來(lái)才慢慢啟動(dòng)操作系統(tǒng),最后運(yùn)行創(chuàng)建好的任務(wù)。有時(shí)候任務(wù)創(chuàng)建好,整個(gè)系 統(tǒng)跑起來(lái)了,可想要的實(shí)驗(yàn)現(xiàn)象就是出不來(lái),比如 LED 不會(huì)亮,串口沒(méi)有輸出,LCD 沒(méi) 有顯示等等。如果是初學(xué)者,這個(gè)時(shí)候就會(huì)心急如焚,四處求救,那怎么辦?這個(gè)時(shí)候如 何排除是硬件的問(wèn)題還是系統(tǒng)的問(wèn)題,這里面有個(gè)小小的技巧,即在硬件初始化好之后, 順便測(cè)試下硬件,測(cè)試方法跟裸機(jī)編程一樣,
/************************************************************************ @ 函數(shù)名 : BSP_Init* @ 功能說(shuō)明: 板級(jí)外設(shè)初始化,所有板子上的初始化均可放在這個(gè)函數(shù)里面* @ 參數(shù) : * @ 返回值 : 無(wú)*********************************************************************/ static void BSP_Init(void) {/** STM32中斷優(yōu)先級(jí)分組為4,即4bit都用來(lái)表示搶占優(yōu)先級(jí),范圍為:0~15* 優(yōu)先級(jí)分組只需要分組一次即可,以后如果有其他的任務(wù)需要用到中斷,* 都統(tǒng)一用這個(gè)優(yōu)先級(jí)分組,千萬(wàn)不要再分組,切忌。*/NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );/* LED 初始化 */LED_GPIO_Config();/* 測(cè)試硬件是否正常工作 */ LED1_ON;/* 讓程序停在這里,不再繼續(xù)往下執(zhí)行 */while(1);/* 串口初始化 */USART_Config();}2.創(chuàng)建單任務(wù)—SRAM靜態(tài)內(nèi)存
這里,我們創(chuàng)建一個(gè)單任務(wù),任務(wù)使用的棧和任務(wù)控制塊都使用靜態(tài)內(nèi)存,即預(yù)先定 義好的全局變量,這些預(yù)先定義好的全局變量都存在內(nèi)部的 SRAM 中。
2.1定義任務(wù)函數(shù)
任務(wù)實(shí)際上就是一個(gè)無(wú)限循環(huán)且不帶返回值的 C 函數(shù)。目前,我們創(chuàng)建一個(gè)這樣的任 務(wù),讓開(kāi)發(fā)板上面的 LED 燈以 500ms 的頻率閃爍,
/*********************************************************************** @ 函數(shù)名 : LED_Task* @ 功能說(shuō)明: LED_Task任務(wù)主體* @ 參數(shù) : * @ 返回值 : 無(wú)********************************************************************/ static void LED_Task(void* parameter) { while (1){LED1_ON;vTaskDelay(500); /* 延時(shí)500個(gè)tick */printf("LED_Task Running,LED1_ON\r\n");LED1_OFF; vTaskDelay(500); /* 延時(shí)500個(gè)tick */ printf("LED_Task Running,LED1_OFF\r\n");} }2.2空閑任務(wù)與定時(shí)器任務(wù)堆棧函數(shù)實(shí)現(xiàn)
當(dāng)我們使用了靜態(tài)創(chuàng)建任務(wù)的時(shí)候,configSUPPORT_STATIC_ALLOCATION 這個(gè)宏 定 義 必 須為 1 (在 FreeRTOSConfig.h 文 件 中 ) , 并且 我 們需 要 實(shí) 現(xiàn)兩 個(gè) 函數(shù) : vApplicationGetIdleTaskMemory()與 vApplicationGetTimerTaskMemory(),這兩個(gè)函數(shù)是用 戶(hù)設(shè)定的空閑(Idle)任務(wù)與定時(shí)器(Timer)任務(wù)的堆棧大小,必須由用戶(hù)自己分配,而 不能是動(dòng)態(tài)分配,
/* 空閑任務(wù)任務(wù)堆棧 */ static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE]; /* 定時(shí)器任務(wù)堆棧 */ static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];/* 空閑任務(wù)控制塊 */ static StaticTask_t Idle_Task_TCB; /* 定時(shí)器任務(wù)控制塊 */ static StaticTask_t Timer_Task_TCB;/************************************************************************* @brief 獲取空閑任務(wù)的任務(wù)堆棧和任務(wù)控制塊內(nèi)存* ppxTimerTaskTCBBuffer : 任務(wù)控制塊內(nèi)存* ppxTimerTaskStackBuffer : 任務(wù)堆棧內(nèi)存* pulTimerTaskStackSize : 任務(wù)堆棧大小* @date 2018-xx-xx***********************************************************************/ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {*ppxIdleTaskTCBBuffer=&Idle_Task_TCB;/* 任務(wù)控制塊內(nèi)存 */*ppxIdleTaskStackBuffer=Idle_Task_Stack;/* 任務(wù)堆棧內(nèi)存 */*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;/* 任務(wù)堆棧大小 */ }/************************************************************************ @brief 獲取定時(shí)器任務(wù)的任務(wù)堆棧和任務(wù)控制塊內(nèi)存* ppxTimerTaskTCBBuffer : 任務(wù)控制塊內(nèi)存* ppxTimerTaskStackBuffer : 任務(wù)堆棧內(nèi)存* pulTimerTaskStackSize : 任務(wù)堆棧大小***********************************************************************/ void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {*ppxTimerTaskTCBBuffer=&Timer_Task_TCB;/* 任務(wù)控制塊內(nèi)存 */*ppxTimerTaskStackBuffer=Timer_Task_Stack;/* 任務(wù)堆棧內(nèi)存 */*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;/* 任務(wù)堆棧大小 */ }2.3 定義任務(wù)棧
目前我們只創(chuàng)建了一個(gè)任務(wù),當(dāng)任務(wù)進(jìn)入延時(shí)的時(shí)候,因?yàn)闆](méi)有另外就緒的用戶(hù)任務(wù), 那么系統(tǒng)就會(huì)進(jìn)入空閑任務(wù),空閑任務(wù)是 FreeRTOS 系統(tǒng)自己?jiǎn)?dòng)的一個(gè)任務(wù),優(yōu)先級(jí)最 低。當(dāng)整個(gè)系統(tǒng)都沒(méi)有就緒任務(wù)的時(shí)候,系統(tǒng)必須保證有一個(gè)任務(wù)在運(yùn)行,空閑任務(wù)就是 為這個(gè)設(shè)計(jì)的。當(dāng)用戶(hù)任務(wù)延時(shí)到期,又會(huì)從空閑任務(wù)切換回用戶(hù)任務(wù)。 在 FreeRTOS 系統(tǒng)中,每一個(gè)任務(wù)都是獨(dú)立的,他們的運(yùn)行環(huán)境都單獨(dú)的保存在他們 的棧空間當(dāng)中。那么在定義好任務(wù)函數(shù)之后,我們還要為任務(wù)定義一個(gè)棧,目前我們使用 的是靜態(tài)內(nèi)存,所以任務(wù)棧是一個(gè)獨(dú)立的全局變量,具體見(jiàn)代碼清單 14-5。任務(wù)的棧占用 的是 MCU 內(nèi)部的 RAM,當(dāng)任務(wù)越多的時(shí)候,需要使用的棧空間就越大,即需要使用的 RAM 空間就越多。一個(gè) MCU 能夠支持多少任務(wù),就得看你的 RAM 空間有多少。
/* AppTaskCreate任務(wù)任務(wù)堆棧 */ static StackType_t AppTaskCreate_Stack[128]; /* LED任務(wù)堆棧 */ static StackType_t LED_Task_Stack[128];2.4定義任務(wù)控制塊
定義好任務(wù)函數(shù)和任務(wù)棧之后,我們還需要為任務(wù)定義一個(gè)任務(wù)控制塊,通常我們稱(chēng) 這個(gè)任務(wù)控制塊為任務(wù)的身份證。在 C代碼上,任務(wù)控制塊就是一個(gè)結(jié)構(gòu)體,里面有非常 多的成員,這些成員共同描述了任務(wù)的全部信息,
/* AppTaskCreate 任務(wù)控制塊 */ static StaticTask_t AppTaskCreate_TCB; /* AppTaskCreate 任務(wù)控制塊 */ static StaticTask_t LED_Task_TCB;2.5 靜態(tài)創(chuàng)建任務(wù)
一個(gè)任務(wù)的三要素是任務(wù)主體函數(shù),任務(wù)棧,任務(wù)控制塊,那么怎么樣把這三個(gè)要素 聯(lián)合在一起?FreeRTOS 里面有一個(gè)叫靜態(tài)任務(wù)創(chuàng)建函數(shù) xTaskCreateStatic(),它就是干這 個(gè)活的。它將任務(wù)主體函數(shù),任務(wù)棧(靜態(tài)的)和任務(wù)控制塊(靜態(tài)的)這三者聯(lián)系在一 起,讓任務(wù)可以隨時(shí)被系統(tǒng)啟動(dòng),
/* 創(chuàng)建 AppTaskCreate 任務(wù) */AppTaskCreate_Handle = xTaskCreateStatic((TaskFunction_t )AppTaskCreate, //任務(wù)函數(shù)(const char* )"AppTaskCreate", //任務(wù)名稱(chēng)(uint32_t )128, //任務(wù)堆棧大小(void* )NULL, //傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )3, //任務(wù)優(yōu)先級(jí)(StackType_t* )AppTaskCreate_Stack, //任務(wù)堆棧(StaticTask_t* )&AppTaskCreate_TCB); //任務(wù)控制塊 if(NULL != AppTaskCreate_Handle)/* 創(chuàng)建成功 */vTaskStartScheduler(); /* 啟動(dòng)任務(wù),開(kāi)啟調(diào)度 */2.6 啟動(dòng)任務(wù)
當(dāng)任務(wù)創(chuàng)建好后,是處于任務(wù)就緒(Ready),在就緒態(tài)的任務(wù)可以參與操作系統(tǒng)的調(diào)度。 但是此時(shí)任務(wù)僅僅是創(chuàng)建了,還未開(kāi)啟任務(wù)調(diào)度器,也沒(méi)創(chuàng)建空閑任務(wù)與定時(shí)器任務(wù)(如果使 能了 configUSE_TIMERS 這個(gè)宏定義),那這兩個(gè)任務(wù)就是在啟動(dòng)任務(wù)調(diào)度器中實(shí)現(xiàn),每個(gè)操 作系統(tǒng),任務(wù)調(diào)度器只啟動(dòng)一次,之后就不會(huì)再次執(zhí)行了,FreeRTOS 中啟動(dòng)任務(wù)調(diào)度器的函 數(shù)是 vTaskStartScheduler(),并且啟動(dòng)任務(wù)調(diào)度器的時(shí)候就不會(huì)返回,從此任務(wù)管理都由 FreeRTOS管理,此時(shí)才是真正進(jìn)入實(shí)時(shí)操作系統(tǒng)中的第一步,
? vTaskStartScheduler(); ? /* 啟動(dòng)任務(wù),開(kāi)啟調(diào)度 */
2.7 main.c文件內(nèi)容全貌
現(xiàn)在我們把任務(wù)主體,任務(wù)棧,任務(wù)控制塊這三部分代碼統(tǒng)一放到 main.c 中,我們?cè)?main.c 文件中創(chuàng)建一個(gè) AppTaskCreate 任務(wù),這個(gè)任務(wù)是用于創(chuàng)建用戶(hù)任務(wù),為了方便管 理,我們的所有的任務(wù)創(chuàng)建都統(tǒng)一放在這個(gè)函數(shù)中,在這個(gè)函數(shù)中創(chuàng)建成功的任務(wù)就可以 直接參與任務(wù)調(diào)度了,
/* FreeRTOS頭文件 */ #include "FreeRTOS.h" #include "task.h" /* 開(kāi)發(fā)板硬件bsp頭文件 */ #include "bsp_led.h" #include "bsp_usart.h" static void AppTaskCreate(void);/* 用于創(chuàng)建任務(wù) */static void LED_Task(void* pvParameters);/* LED_Task任務(wù)實(shí)現(xiàn) */static void BSP_Init(void);/* 用于初始化板載相關(guān)資源 */ /**************************** 任務(wù)句柄 ********************************/ /* * 任務(wù)句柄是一個(gè)指針,用于指向一個(gè)任務(wù),當(dāng)任務(wù)創(chuàng)建好之后,它就具有了一個(gè)任務(wù)句柄* 以后我們要想操作這個(gè)任務(wù)都需要通過(guò)這個(gè)任務(wù)句柄,如果是自身的任務(wù)操作自己,那么* 這個(gè)句柄可以為NULL。*//* 創(chuàng)建任務(wù)句柄 */ static TaskHandle_t AppTaskCreate_Handle; /* LED任務(wù)句柄 */ static TaskHandle_t LED_Task_Handle; /********************************** 內(nèi)核對(duì)象句柄 *********************************/ /** 信號(hào)量,消息隊(duì)列,事件標(biāo)志組,軟件定時(shí)器這些都屬于內(nèi)核的對(duì)象,要想使用這些內(nèi)核* 對(duì)象,必須先創(chuàng)建,創(chuàng)建成功之后會(huì)返回一個(gè)相應(yīng)的句柄。實(shí)際上就是一個(gè)指針,后續(xù)我* 們就可以通過(guò)這個(gè)句柄操作這些內(nèi)核對(duì)象。** 內(nèi)核對(duì)象說(shuō)白了就是一種全局的數(shù)據(jù)結(jié)構(gòu),通過(guò)這些數(shù)據(jù)結(jié)構(gòu)我們可以實(shí)現(xiàn)任務(wù)間的通信,* 任務(wù)間的事件同步等各種功能。至于這些功能的實(shí)現(xiàn)我們是通過(guò)調(diào)用這些內(nèi)核對(duì)象的函數(shù)* 來(lái)完成的* *//******************************* 全局變量聲明 ************************************/ /** 當(dāng)我們?cè)趯?xiě)應(yīng)用程序的時(shí)候,可能需要用到一些全局變量。*/ /* AppTaskCreate任務(wù)任務(wù)堆棧 */ static StackType_t AppTaskCreate_Stack[128]; /* LED任務(wù)堆棧 */ static StackType_t LED_Task_Stack[128];/* AppTaskCreate 任務(wù)控制塊 */ static StaticTask_t AppTaskCreate_TCB; /* AppTaskCreate 任務(wù)控制塊 */ static StaticTask_t LED_Task_TCB;/* 空閑任務(wù)任務(wù)堆棧 */ static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE]; /* 定時(shí)器任務(wù)堆棧 */ static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];/* 空閑任務(wù)控制塊 */ static StaticTask_t Idle_Task_TCB; /* 定時(shí)器任務(wù)控制塊 */ static StaticTask_t Timer_Task_TCB;/*** 使用了靜態(tài)分配內(nèi)存,以下這兩個(gè)函數(shù)是由用戶(hù)實(shí)現(xiàn),函數(shù)在task.c文件中有引用* 當(dāng)且僅當(dāng) configSUPPORT_STATIC_ALLOCATION 這個(gè)宏定義為 1 的時(shí)候才有效*/ void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize);void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);/****************************************************************** @brief 主函數(shù)* @param 無(wú)* @retval 無(wú)* @note 第一步:開(kāi)發(fā)板硬件初始化 第二步:創(chuàng)建APP應(yīng)用任務(wù)第三步:啟動(dòng)FreeRTOS,開(kāi)始多任務(wù)調(diào)度****************************************************************/ int main(void) { /* 開(kāi)發(fā)板硬件初始化 */BSP_Init();printf("這是一個(gè)[野火]-STM32全系列開(kāi)發(fā)板-FreeRTOS-靜態(tài)創(chuàng)建單任務(wù)!\r\n");/* 創(chuàng)建 AppTaskCreate 任務(wù) */AppTaskCreate_Handle = xTaskCreateStatic((TaskFunction_t )AppTaskCreate, //任務(wù)函數(shù)(const char* )"AppTaskCreate", //任務(wù)名稱(chēng)(uint32_t )128, //任務(wù)堆棧大小(void* )NULL, //傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )3, //任務(wù)優(yōu)先級(jí)(StackType_t* )AppTaskCreate_Stack, //任務(wù)堆棧(StaticTask_t* )&AppTaskCreate_TCB); //任務(wù)控制塊 if(NULL != AppTaskCreate_Handle)/* 創(chuàng)建成功 */vTaskStartScheduler(); /* 啟動(dòng)任務(wù),開(kāi)啟調(diào)度 */while(1); /* 正常不會(huì)執(zhí)行到這里 */ }/************************************************************************ @ 函數(shù)名 : AppTaskCreate* @ 功能說(shuō)明: 為了方便管理,所有的任務(wù)創(chuàng)建函數(shù)都放在這個(gè)函數(shù)里面* @ 參數(shù) : 無(wú) * @ 返回值 : 無(wú)**********************************************************************/ static void AppTaskCreate(void) {taskENTER_CRITICAL(); //進(jìn)入臨界區(qū)/* 創(chuàng)建LED_Task任務(wù) */LED_Task_Handle = xTaskCreateStatic((TaskFunction_t )LED_Task, //任務(wù)函數(shù)(const char* )"LED_Task", //任務(wù)名稱(chēng)(uint32_t )128, //任務(wù)堆棧大小(void* )NULL, //傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )4, //任務(wù)優(yōu)先級(jí)(StackType_t* )LED_Task_Stack, //任務(wù)堆棧(StaticTask_t* )&LED_Task_TCB); //任務(wù)控制塊 if(NULL != LED_Task_Handle)/* 創(chuàng)建成功 */printf("LED_Task任務(wù)創(chuàng)建成功!\n");elseprintf("LED_Task任務(wù)創(chuàng)建失敗!\n");vTaskDelete(AppTaskCreate_Handle); //刪除AppTaskCreate任務(wù)taskEXIT_CRITICAL(); //退出臨界區(qū) }/*********************************************************************** @ 函數(shù)名 : LED_Task* @ 功能說(shuō)明: LED_Task任務(wù)主體* @ 參數(shù) : * @ 返回值 : 無(wú)********************************************************************/ static void LED_Task(void* parameter) { while (1){LED1_ON;vTaskDelay(500); /* 延時(shí)500個(gè)tick */printf("LED_Task Running,LED1_ON\r\n");LED1_OFF; vTaskDelay(500); /* 延時(shí)500個(gè)tick */ printf("LED_Task Running,LED1_OFF\r\n");} }/************************************************************************ @ 函數(shù)名 : BSP_Init* @ 功能說(shuō)明: 板級(jí)外設(shè)初始化,所有板子上的初始化均可放在這個(gè)函數(shù)里面* @ 參數(shù) : * @ 返回值 : 無(wú)*********************************************************************/ static void BSP_Init(void) {/** STM32中斷優(yōu)先級(jí)分組為4,即4bit都用來(lái)表示搶占優(yōu)先級(jí),范圍為:0~15* 優(yōu)先級(jí)分組只需要分組一次即可,以后如果有其他的任務(wù)需要用到中斷,* 都統(tǒng)一用這個(gè)優(yōu)先級(jí)分組,千萬(wàn)不要再分組,切忌。*/NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );/* LED 初始化 */LED_GPIO_Config();/* 測(cè)試硬件是否正常工作 */ LED1_ON;/* 讓程序停在這里,不再繼續(xù)往下執(zhí)行 */while(1);/* 串口初始化 */USART_Config();}/************************************************************************* @brief 獲取空閑任務(wù)的任務(wù)堆棧和任務(wù)控制塊內(nèi)存* ppxTimerTaskTCBBuffer : 任務(wù)控制塊內(nèi)存* ppxTimerTaskStackBuffer : 任務(wù)堆棧內(nèi)存* pulTimerTaskStackSize : 任務(wù)堆棧大小* @date 2018-xx-xx***********************************************************************/ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {*ppxIdleTaskTCBBuffer=&Idle_Task_TCB;/* 任務(wù)控制塊內(nèi)存 */*ppxIdleTaskStackBuffer=Idle_Task_Stack;/* 任務(wù)堆棧內(nèi)存 */*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;/* 任務(wù)堆棧大小 */ }/************************************************************************ @brief 獲取定時(shí)器任務(wù)的任務(wù)堆棧和任務(wù)控制塊內(nèi)存* ppxTimerTaskTCBBuffer : 任務(wù)控制塊內(nèi)存* ppxTimerTaskStackBuffer : 任務(wù)堆棧內(nèi)存* pulTimerTaskStackSize : 任務(wù)堆棧大小***********************************************************************/ void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {*ppxTimerTaskTCBBuffer=&Timer_Task_TCB;/* 任務(wù)控制塊內(nèi)存 */*ppxTimerTaskStackBuffer=Timer_Task_Stack;/* 任務(wù)堆棧內(nèi)存 */*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;/* 任務(wù)堆棧大小 */ }/********************************END OF FILE****************************/注意:在使用靜態(tài)創(chuàng)建任務(wù)的時(shí)候必須要將 FreeRTOSConfig.h 中 的 configSUPPORT_STATIC_ALLOCATION 宏配置為 1。
下載后,可以看到板子上面的 LED 燈已經(jīng)在 閃爍,說(shuō)明我們創(chuàng)建的單任務(wù)(使用靜態(tài)內(nèi)存)已經(jīng)跑起來(lái)了。
本篇內(nèi)容摘自野火《FreeRTOS內(nèi)核實(shí)現(xiàn)與應(yīng)用開(kāi)發(fā)》
總結(jié)
以上是生活随笔為你收集整理的FreeRTOS基础教程第一章创建任务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 牛人自述模拟电路学习历程
- 下一篇: Express实现路由分发控制、REST