一、FreeRTOS介紹
1、FreeRTOS主要特點
(1)、支持搶占式調(diào)度,合作式調(diào)度和時間片調(diào)度;
(2)、高效的軟件定時器;
(3)、開源免費;
(4)、支持多種系統(tǒng)架構(gòu);
(5)、任務數(shù)量不限等等;
2、FreeRTOS命令規(guī)則
(1)、變量
uint32_t定義的變量都加前綴ul,u -- unsigned? ? ?l -- long;
uint16_t定義的變量都加前綴us,u -- unsigned? ? s -- short;
uint8_t定義的變量都加前綴uc, u -- unsigned? ? ?c -- char;
size_t定義的變量加上前綴ux;
枚舉變量會加上前綴e;
指針變量加上前綴p,uint16_t定義的指針變量加上pus;
(2)、函數(shù)
static聲明的函數(shù),定義時加上前綴prv(private的縮寫);
帶返回值的函數(shù),根據(jù)返回值的類型,加上響應前綴,void前綴加上v;
文件中的函數(shù)名也包含文件名;
3、FreeRTOS中的數(shù)據(jù)類型
(1)、TickType_t
? ? 如果定義了configUSE_16_BIT_TICKS,TickType_t為16位無符號,否則為32位無符號,因此,對于32位處理器來說,此宏必須為0。
(2)、BaseType_t (與系統(tǒng)架構(gòu)有關,此類型定義的是有符號數(shù))
(3)、UBaseType_t(BaseType_t的無符號版本)
(4)、StackType_t(棧變量數(shù)據(jù)類型)
二、FreeRTOS配置文件(FreeRTOSConfig —— 系統(tǒng)裁剪)
1、基本配置
(1)、configUSE_PREEMPTION:搶占式調(diào)度器師使能(1:搶占式調(diào)度器? 0:合作式調(diào)度器);
(2)、configUSE_PORT_OPTIMISED_TASK_SELECTION:優(yōu)化列表中要執(zhí)行的最高優(yōu)先級任務的算法(1:專用方式? ? 0:通用方式);
(3)、configUSE_TICKLESS_IDLE:tickless低功耗模式使能;
(4)、configCPU_CLOCK_HZ:定義SOC主頻;
(5)、configTICK_RATE_HZ:定義系統(tǒng)時鐘節(jié)拍數(shù),單位HZ,一般為1000HZ;
(6)、configMAX_PRIORITIES:定義用戶可使用的最大優(yōu)先級數(shù);
(7)、configMINIMAL_STACK_SIZE:定義空閑任務的棧大小;
(8)、configTOTAL_HEAP_SIZE:定義堆大小,任務創(chuàng)建,消息隊列創(chuàng)建等都需要;
(9)、configMAX_TASK_NAME_LEN:任務名最大字符數(shù);
(10)、configUSE_16_BIT_TICKS:TickType_t類型含義, 1:16位架構(gòu)處理器? ? ?0:32位架構(gòu)處理器;
(11)、configIDLE_SHOULD_YIELD:建議配置為0;
(12)、configUSE_TASK_NOTIFICATIONS: 1:使能任務間直接的消息傳遞? ? ?0:失能;
(13)、configUSE_MUTEXES: 1:使能互斥信號量? ? ?0:失能互斥信號量;
(14)、configUSE_RECURSIVE_MUTEXES: 1:使能遞歸互斥信號量? ?0:失能遞歸互斥信號量;
(15)、configUSE_COUNTING_SEMAPHORES: 1:使能計數(shù)信號量? ? 0:失能計數(shù)信號量;
(16)、configQUEUE_REGISTRY_SIZE: 設置可以注冊的信號量和消息隊列個數(shù);
(17)、configUSE_QUEUE_SETS: 1:使能消息隊列? ? 0:失能消息隊列;
(18)、configUSE_TIME_SLICING: 1:使能時間片調(diào)度? ? 0:失能時間片調(diào)度;
2、鉤子函數(shù)
(1)、configUSE_IDLE_HOOK: 1:使能空閑任務的鉤子函數(shù)? ? 0:失能空閑任務鉤子函數(shù);
(2)、configUSE_MALLOC_FAILED_HOOK: 1:使能動態(tài)內(nèi)存申請失敗的鉤子函數(shù)? ?0:失能;
(3)、configUSE_TICK_HOOK: 1:使能滴答定時器中斷的鉤子函數(shù);
3、合作式任務配置
(1)、configUSE_CO_ROUTINES: 1:使能合作式調(diào)度相關函數(shù)? ? ?0:失能合作式調(diào)用相關函數(shù);
(2)、configMAX_CO_ROUTINE_PRIORITIES:最大的合作式任務優(yōu)先級數(shù);
4、軟件定時器配置
(1)、configUSE_TIMERS: 1:使能軟件定時器? ? 0:失能軟件定時器;
(2)、configTIMER_TASK_PRIORITY:軟件定時器任務的優(yōu)先級;
(3)、configTIMER_QUEUE_LENGTH:軟件定時器命令隊列的長度;
(4)、configTIMER_TASK_STACK_DEPTH:軟件定時器任務的棧空間大??;
5、內(nèi)核配置
(1)、configPRIO_BITS:stm32f103/407/429等都是4;
(2)、configLIBRARY_LOWEST_INIERRUPT_PRIORITY:0-15,建議配置中斷最低優(yōu)先級15,;
(3)、configLIBRARY_MAX_SYSCALL_INIERRUPT_PRIORITY:系統(tǒng)可管理的最高優(yōu)先級中斷;
(4)、configKERNEL_INTERRUPT_PRIORITY
(5)、configMAX_SYSCALL_INTERRUPT_PRIORITY
6、INCLUDE配置
#define?INCLUDE_xTaskGetSchedulerState??????????1??????????????????????? #define?INCLUDE_vTaskPrioritySet 1 #define?INCLUDE_uxTaskPriorityGet 1 #define?INCLUDE_vTaskDelete 1 #define?INCLUDE_vTaskCleanUpResources ????????1 #define?INCLUDE_vTaskSuspend 1 #define?INCLUDE_vTaskDelayUntil 1 #define?INCLUDE_vTaskDelay 1 #define?INCLUDE_eTaskGetState 1 #define?INCLUDE_xTimerPendFunctionCall ????????1
三、FreeRTOS任務管理
1、任務狀態(tài)(運行態(tài),就緒態(tài),阻塞態(tài),掛起態(tài))
2、系統(tǒng)啟動vTaskStartScheduler()
? ? 啟動FreeRTOS調(diào)度器,即啟動多任務運行。
3、任務創(chuàng)建xTaskCreate()
BaseType_t?xTaskCreate(TaskFunction_t?pvTaskCode,???/*?任務函數(shù)?*/ ???????????????????????const?char?*?const?pcName,???/*?任務名?*/ ???????????????????????unsigned?short?usStackDepth,?/*?任務棧大小,單位?word,也就是?4?字節(jié)?*/ ???????????????????????void?*pvParameters,??????????/*?任務參數(shù)?*/ ???????????????????????UBaseType_t?uxPriority,??????/*?任務優(yōu)先級?*/ ???????????????????????TaskHandle_t?*pvCreatedTask??/*?任務句柄?*/ );
#include?"FreeRTOS.h" #include?"task.h" #include?"queue.h" #include?"croutine.h" #define?TASK_PRIO_START?????????1 #define?TASK_START_STK_SIZE?????(1?*?256) TaskHandle_t?start_handler; static?void?start_task(void?*arg) { ??while(1) ??{ vTaskDelay(500); ??} } int?main(void) { ??xTaskCreate(start_task, ??????????????"start_task", ??????????????TASK_START_STK_SIZE, ??????????????NULL, ??????????????TASK_PRIO_START, ??????????????&start_handler); ?? ??vTaskStartScheduler(); }
4、任務刪除vTaskDelete()
void?vTaskDelete(?TaskHandle_t?xTaskToDelete?)
必須配置#define INCLUDE_vTaskDelete? ?1
5、任務掛起vTaskSuspend()
void?vTaskSuspend(?TaskHandle_t?xTaskToSuspend?)
必須配置#define INCLUDE_vTaskSuspend? ?1
6、任務恢復vTaskResume()
void?vTaskResume(?TaskHandle_t?xTaskToResume?)
必須配置#define INCLUDE_vTaskResume? ?1
7、任務恢復中斷方式xTaskResumeFromISR()
BaseType_t?xTaskResumeFromISR(?TaskHandle_t?xTaskToResume?)
必須配置#define INCLUDE_vTaskResumeFromISR? ?1
8、空閑任務(低功耗時,在空閑任務中實現(xiàn)睡眠)
四、臨界段和開關中斷
1、臨界段
? ? 不允許中斷打斷,進入臨界區(qū)前必須關中斷,退出臨界區(qū)后開中斷。UCOS有臨界區(qū),RTX沒有。
2、臨界段處理(開關中斷)
#define?taskENTER_CRITICAL()??portENTER_CRITICAL() #define?taskEXIT_CRITICAL()???portEXIT_CRITICAL()
????開關中斷就是對計數(shù)uxCriticalNesting變量操作,進入臨界區(qū),變量+1,退出臨界區(qū),變量-1。
3、中斷臨界段
#define?taskENTER_CRITICAL_FROM_ISR()???portSET_INTERRUPT_MASK_FROM_ISR() #define?taskEXIT_CRITICAL_FROM_ISR(?x?)?portCLEAR_INTERRUPT_MASK_FROM_ISR(?x?)
五、FreeRTOS時間管理
1、任務等待vTaskDelay()
void?vTaskDelay(?const?TickType_t?xTicksToDelay?)
延時等待范圍:1-0xFFFFFFFF
作用:任務切換
其他幾個任務延時函數(shù)個人沒怎么使用,故不介紹了。
六、FreeRTOS消息隊列
? ? 消息傳遞的是數(shù)據(jù)的復制,RTX/UCOS傳遞的是數(shù)據(jù)的地址。
1、消息隊列創(chuàng)建xQueueCreate()
QueueHandle_t?xQueueCreate(?UBaseType_t?uxQueueLength,?/*?消息個數(shù)?*/ ????????????????????????????UBaseType_t?uxItemSize?);??/*?每個消息大小,單位字節(jié)?*/
返回消息隊列句柄。
2、消息隊列發(fā)送xQueueSend()
BaseType_t?xQueueSend( ??????????????????????QueueHandle_t?xQueue,???????/*?消息隊列句柄?*/ ??????????????????????const?void?*?pvItemToQueue,?/*?要傳遞數(shù)據(jù)地址?*/ ??????????????????????TickType_t?xTicksToWait?????/*?等待消息隊列有空間的最大等待時間?*/ );
3、消息隊列從中斷發(fā)送xQueueSendFromISR()
BaseType_t?xQueueSendFromISR( ?????????????????????????????QueueHandle_t?xQueue,???????/*?消息隊列句柄?*/ ?????????????????????????????const?void?*?pvItemToQueue,?/*?要傳遞數(shù)據(jù)地址?*/ ?????????????????????????????TickType_t?xTicksToWait?????/*?等待消息隊列有空間的最大等待時間?*/ );
4、消息隊列接收xQueueReceive()? ? xQueueReceiveFromISR
BaseType_t?xQueueReceiveFromISR(?QueueHandle_t?xQueue,?void?*?const?pvBuffer,?BaseType_t?*?const?pxHigherPriorityTaskWoken?)
BaseType_t?xQueueReceive( ?????????????????????????QueueHandle_t?xQueue,???/*?消息隊列句柄?*/ ?????????????????????????void?*pvBuffer,?????????/*?接收消息隊列數(shù)據(jù)的緩沖地址?*/ ?????????????????????????TickType_t?xTicksToWait?/*?等待消息隊列有數(shù)據(jù)的最大等待時間?*/ );
七、FreeRTOS事件標志組(任務間同步)
1、事件標志組創(chuàng)建xEventGroupCreate()
EventGroupHandle_t?xEventGroupCreate(?void?);
返回事件標志組句柄。
必須定義:
#define INCLUDE_xEventGroupSetBitFromISR 1
#define configUSE_TIMERS? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1
#define INCLUDE_xTimerPendFunctionCall? ? ? 1
2、時間標志組設置xEventGroupSetBits()
EventBits_t?xEventGroupSetBits(?EventGroupHandle_t?xEventGroup,??/*?事件標志組句柄?*/ ????????????????????????????????const?EventBits_t?uxBitsToSet?);?/*?事件標志位設置?*/
BaseType_t?xEventGroupSetBitsFromISR(EventGroupHandle_t?xEventGroup,?/*?事件標志組句柄?*/ ?????????????????????????????????????const?EventBits_t?uxBitsToSet,?/*?事件標志位設置?*/ ?????????????????????????????????????BaseType_t?*pxHigherPriorityTaskWoken?);?/*?高優(yōu)先級任務是否被喚醒的狀態(tài)保存?*/
第二個參數(shù)表示24個可設置的時間標志位,返回當前的事件標志組數(shù)值。中斷中使用xEventGroupSetBitsFromISR()。
3、事件標志組獲取xEventGroupWaitBits()
EventBits_t?xEventGroupWaitBits(const?EventGroupHandle_t?xEventGroup,?/*?事件標志組句柄?*/ ????????????????????????????????const?EventBits_t?uxBitsToWaitFor,?/*?等待被設置的事件標志位?*/ ????????????????????????????????const?BaseType_t?xClearOnExit,?????/*?選擇是否清零被置位的事件標志位?*/ ????????????????????????????????const?BaseType_t?xWaitForAllBits,??/*?選擇是否等待所有標志位都被設置?*/ ????????????????????????????????TickType_t?xTicksToWait?);?????????/*?設置等待時間?*/
//?STM32F10X?FreeRTOSConfig舉例 #ifndef?FREERTOS_CONFIG_H #define?FREERTOS_CONFIG_H #include?"type.h" /***************************************************************************************************************/ /*????????????????????????????????????????FreeRTOS基礎配置配置選項??????????????????????????????????????????????*/ /***************************************************************************************************************/ #define?configUSE_PREEMPTION 1???????????????????????//?1使用搶占式內(nèi)核,0使用協(xié)程 #define?configUSE_TIME_SLICING 1 //?1使能時間片調(diào)度(默認式使能的) #define?configUSE_PORT_OPTIMISED_TASK_SELECTION 1???????????????????????//?1啟用特殊方法來選擇下一個要運行的任務 ????????????????????????????????????????????????????????????????????????//?一般是硬件計算前導零指令,如果所使用的 ????????????????????????????????????????????????????????????????????????//?MCU沒有這些硬件指令的話此宏應該設置為0! #define?configUSE_TICKLESS_IDLE 0???????????????????????//?1啟用低功耗tickless模式 #define?configUSE_QUEUE_SETS 1???????????????????????//?為1時啟用隊列 #define?configCPU_CLOCK_HZ 72000000????????????????//?CPU頻率 #define?configTICK_RATE_HZ (1000)??????????????????//?時鐘節(jié)拍頻率,這里設置為1000,周期就是1ms #define?configMAX_PRIORITIES (32)????????????????????//?可使用的最大優(yōu)先級 #define?configMINIMAL_STACK_SIZE ((unsigned?short)130)???//?空閑任務使用的堆棧大小 #define?configMAX_TASK_NAME_LEN (20)????????????????????//?任務名字字符串長度 #define?configUSE_16_BIT_TICKS 0???????????????????????//?系統(tǒng)節(jié)拍計數(shù)器變量數(shù)據(jù)類型, ????????????????????????????????????????????????????????????????????????//?1表示為16位無符號整形,0表示為32位無符號整形 #define?configIDLE_SHOULD_YIELD 1???????????????????????//?為1時空閑任務放棄CPU使用權(quán)給其他同優(yōu)先級的用戶任務 #define?configUSE_TASK_NOTIFICATIONS????????????1???????????????????????//?為1時開啟任務通知功能,默認開啟 #define?configUSE_MUTEXES 1???????????????????????//?為1時使用互斥信號量 #define?configQUEUE_REGISTRY_SIZE 8???????????????????????//?不為0時表示啟用隊列記錄,具體的值是可以 ????????????????????????????????????????????????????????????????????????//?記錄的隊列和信號量最大數(shù)目。 #define?configCHECK_FOR_STACK_OVERFLOW 0???????????????????????//?大于0時啟用堆棧溢出檢測功能,如果使用此功能 ????????????????????????????????????????????????????????????????????????//?用戶必須提供一個棧溢出鉤子函數(shù),如果使用的話 ????????????????????????????????????????????????????????????????????????//?此值可以為1或者2,因為有兩種棧溢出檢測方法。 #define?configUSE_RECURSIVE_MUTEXES 1???????????????????????//?為1時使用遞歸互斥信號量 #define?configUSE_MALLOC_FAILED_HOOK 0???????????????????????//?1使用內(nèi)存申請失敗鉤子函數(shù) #define?configUSE_APPLICATION_TASK_TAG 0??????????????????????? #define?configUSE_COUNTING_SEMAPHORES 1???????????????????????//?為1時使用計數(shù)信號量 /***************************************************************************************************************/ /*????????????????????????????????FreeRTOS與內(nèi)存申請有關配置選項????????????????????????????????????????????????*/ /***************************************************************************************************************/ #define?configSUPPORT_DYNAMIC_ALLOCATION????????1???????????????????????//?支持動態(tài)內(nèi)存申請 #define?configTOTAL_HEAP_SIZE ((size_t)(20*1024))?????//?系統(tǒng)所有總的堆大小 /***************************************************************************************************************/ /*????????????????????????????????FreeRTOS與鉤子函數(shù)有關的配置選項??????????????????????????????????????????????*/ /***************************************************************************************************************/ #define?configUSE_IDLE_HOOK 0???????????????????????//?1,使用空閑鉤子;0,不使用 #define?configUSE_TICK_HOOK 0???????????????????????//?1,使用時間片鉤子;0,不使用 ???????????????????????????????????????????????????????????????????????? /***************************************************************************************************************/ /*????????????????????????????????FreeRTOS與協(xié)程有關的配置選項??????????????????????????????????????????????????*/ /***************************************************************************************************************/ #define?configUSE_CO_ROUTINES? ????????0???????????????????????//?為1時啟用協(xié)程,啟用協(xié)程以后必須添加文件croutine.c #define?configMAX_CO_ROUTINE_PRIORITIES?????????(?2?)???????????????????//?協(xié)程的有效優(yōu)先級數(shù)目 /***************************************************************************************************************/ /*????????????????????????????????FreeRTOS與軟件定時器有關的配置選項????????????????????????????????????????????*/ /***************************************************************************************************************/ #define?configUSE_TIMERS ????????1???????????????????????????????//?為1時啟用軟件定時器 #define?configTIMER_TASK_PRIORITY ????????(configMAX_PRIORITIES-1)????????//?軟件定時器優(yōu)先級 #define?configTIMER_QUEUE_LENGTH ????????5???????????????????????????????//?軟件定時器隊列長度 #define?configTIMER_TASK_STACK_DEPTH ????????(configMINIMAL_STACK_SIZE*2)????//?軟件定時器任務堆棧大小 /***************************************************************************************************************/ /*????????????????????????????????FreeRTOS可選函數(shù)配置選項??????????????????????????????????????????????????????*/ /***************************************************************************************************************/ #define?INCLUDE_xTaskGetSchedulerState??????????1??????????????????????? #define?INCLUDE_vTaskPrioritySet ????????1 #define?INCLUDE_uxTaskPriorityGet ????????1 #define?INCLUDE_vTaskDelete ????????1 #define?INCLUDE_vTaskCleanUpResources ????????1 #define?INCLUDE_vTaskSuspend ????????1 #define?INCLUDE_vTaskDelayUntil ????????1 #define?INCLUDE_vTaskDelay ????????1 #define?INCLUDE_eTaskGetState ????????1 #define?INCLUDE_xTimerPendFunctionCall ????????1 /***************************************************************************************************************/ /*????????????????????????????????FreeRTOS與中斷有關的配置選項??????????????????????????????????????????????????*/ /***************************************************************************************************************/ #ifdef?__NVIC_PRIO_BITS #define?configPRIO_BITS??????? __NVIC_PRIO_BITS #else #define?configPRIO_BITS??????? 4?????????????????? #endif #define?configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15??????????????????????//?中斷最低優(yōu)先級 #define?configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5???????????????????????//?系統(tǒng)可管理的最高中斷優(yōu)先級 #define?configKERNEL_INTERRUPT_PRIORITY? (?configLIBRARY_LOWEST_INTERRUPT_PRIORITY?<<?(8?-?configPRIO_BITS)?) #define?configMAX_SYSCALL_INTERRUPT_PRIORITY? (?configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY?<<?(8?-?configPRIO_BITS)?) /***************************************************************************************************************/ /*????????????????????????????????FreeRTOS與中斷服務函數(shù)有關的配置選項??????????????????????????????????????????*/ /***************************************************************************************************************/ #define?xPortPendSVHandler? PendSV_Handler #define?vPortSVCHandler? SVC_Handler #endif?/*?FREERTOS_CONFIG_H?*/