FreeRTOS實時作業系統核心設定說明
FreeRTOS核心是高度可客製化的,使用組態檔FreeRTOSConfig.h進行客製化。每個FreeRTOS應用都必須包含這個標頭檔案,使用者根據實際應用來裁剪客製化FreeRTOS核心。這個組態檔是針對使用者程式的,而非核心,因此組態檔一般放在應用程式目錄下,不要放在RTOS核心原始碼目錄下。
在下載的FreeRTOS檔案包中,每個演範例程都有一個FreeRTOSConfig.h檔案。有些例程的組態檔是比較舊的版本,可能不會包含所有有效選項。如果沒有在組態檔中指定某個選項,那麼RTOS核心會使用預設值。典型的FreeRTOSConfig.h組態檔定義如下所示,隨後會說明裡面的每一個引數。
#ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /*Here is a good place to include header files that are required across yourapplication. */ #include "something.h" #define configUSE_PREEMPTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_TICKLESS_IDLE 0 #define configCPU_CLOCK_HZ 60000000 #define configTICK_RATE_HZ 250 #define configMAX_PRIORITIES 5 #define configMINIMAL_STACK_SIZE 128 #define configTOTAL_HEAP_SIZE 10240 #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_MUTEXES 0 #define configUSE_RECURSIVE_MUTEXES 0 #define configUSE_COUNTING_SEMAPHORES 0 #define configUSE_ALTERNATIVE_API 0/* Deprecated! */ #define configQUEUE_REGISTRY_SIZE 10 #define configUSE_QUEUE_SETS 0 #define configUSE_TIME_SLICING 0 #define configUSE_NEWLIB_REENTRANT 0 #define configENABLE_BACKWARD_COMPATIBILITY 0 #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 /*Hook function related definitions. */ #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_MALLOC_FAILED_HOOK 0 /*Run time and task stats gathering related definitions. */ #define configGENERATE_RUN_TIME_STATS 0 #define configUSE_TRACE_FACILITY 0 #define configUSE_STATS_FORMATTING_FUNCTIONS 0 /*Co-routine related definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES 1 /*Software timer related definitions. */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY 3 #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE /*Interrupt nesting behaviour configuration. */ #define configKERNEL_INTERRUPT_PRIORITY [dependent of processor] #define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application] #define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application] /*Define to trap errors during development. */ #define configASSERT( ( x ) ) if( ( x ) == 0) vAssertCalled( __FILE__, __LINE__ ) /*FreeRTOS MPU specific definitions. */ #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 /*Optional functions - most linkers will remove unused functions anyway. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_xResumeFromISR 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_xTaskGetIdleTaskHandle 0 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 #define INCLUDE_pcTaskGetTaskName 0 #define INCLUDE_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 1 #define INCLUDE_xTimerPendFunctionCall 0 /* Aheader file that defines trace macro can be included here. */ #end if/* FREERTOS_CONFIG_H*/
1.configUSE_PREEMPTION
為1時RTOS使用搶佔式排程器,為0時RTOS使用共同作業式排程器(時間片)。
注:在多工管理機制上,作業系統可以分為搶佔式和共同作業式兩種。共同作業式作業系統是任務主動釋放CPU後,切換到下一個任務。工作切換的時機完全取決於正在執行的任務。
2.configUSE_PORT_OPTIMISED_TASK_SELECTION
某些執行FreeRTOS的硬體有兩種方法選擇下一個要執行的任務:通用方法和特定於硬體的方法(以下簡稱“特殊方法”)。
通用方法:
- configUSE_PORT_OPTIMISED_TASK_SELECTION設定為0或者硬體不支援這種特殊方法。
- 可以用於所有FreeRTOS支援的硬體。
- 完全用C實現,效率略低於特殊方法。
- 不強制要求限制最大可用優先順序數目
特殊方法:
- 並非所有硬體都支援。
- 必須將configUSE_PORT_OPTIMISED_TASK_SELECTION設定為1。
- 依賴一個或多個特定架構的組合指令(一般是類似計算前導零[CLZ]指令)。
- 比通用方法更高效。
- 一般強制限定最大可用優先順序數目為32。
3.configUSE_TICKLESS_IDLE
設定configUSE_TICKLESS_IDLE為1使能低功耗tickless模式,為0保持系統節拍(tick)中斷一直執行。
通常情況下,FreeRTOS回撥空閒任務勾點函數(需要設計者自己實現),在空閒任務勾點函數中設定微處理器進入低功耗模式來達到省電的目的。因為系統要響應系統節拍中斷事件,因此使用這種方法會週期性的退出、再進入低功耗狀態。如果系統節拍中斷頻率過快,則大部分電能和CPU時間會消耗在進入和退出低功耗狀態上。
FreeRTOS的tickless空閒模式會在空閒週期時停止週期性系統節拍中斷。停止週期性系統節拍中斷可以使微控制器長時間處於低功耗模式。移植層需要設定外部喚醒中斷,當喚醒事件到來時,將微控制器從低功耗模式喚醒。微控制器喚醒後,會重新使能系統節拍中斷。由於微控制器在進入低功耗後,系統節拍計數器是停止的,但我們又需要知道這段時間能折算成多少次系統節拍中斷週期,這就需要有一個不受低功耗影響的外部時鐘源,即微處理器處於低功耗模式時它也在計時的,這樣在重啟系統節拍中斷時就可以根據這個外部計時器計算出一個調整值並寫入RTOS 系統節拍計數器變數中。
4.configUSE_IDLE_HOOK
設定為1使用空閒勾點(Idle Hook類似於回撥函數),0忽略空閒勾點。
當RTOS排程器開始工作後,為了保證至少有一個任務在執行,空閒任務被自動建立,佔用最低優先順序(0優先順序)。對於已經刪除的RTOS任務,空閒任務可以釋放分配給它們的堆疊記憶體。因此,在應用中應該注意,使用vTaskDelete()函數時要確保空閒任務獲得一定的處理器時間。除此之外,空閒任務沒有其它特殊功能,因此可以任意的剝奪空閒任務的處理器時間。
應用程式也可能和空閒任務共用同個優先順序。
空閒任務勾點是一個函數,這個函數由使用者來實現,RTOS規定了函數的名字和引數,這個函數在每個空閒任務週期都會被呼叫。
要建立一個空閒勾點:
設定FreeRTOSConfig.h 檔案中的configUSE_IDLE_HOOK 為1;
定義一個函數,函數名和引數如下所示:
void vApplicationIdleHook(void );
這個勾點函數不可以呼叫會引起空閒任務阻塞的API函數(例如:vTaskDelay()、帶有阻塞時間的佇列和號誌函數),在勾點函數內部使用協程是被允許的。
使用空閒勾點函數設定CPU進入省電模式是很常見的。
5.configUSE_MALLOC_FAILED_HOOK
每當一個任務、佇列、號誌被建立時,核心使用一個名為pvPortMalloc()的函數來從堆中分配記憶體。官方的下載包中包含5個簡單記憶體分配策略,分別儲存在原始檔heap_1.c、heap_2.c、heap_3.c、heap_4.c、heap_5.c中。僅當使用這五個簡單策略之一時,宏configUSE_MALLOC_FAILED_HOOK才有意義。
如果定義並正確設定malloc()失敗勾點函數,則這個函數會在pvPortMalloc()函數返回NULL時被呼叫。只有FreeRTOS在響應記憶體分配請求時發現堆記憶體不足才會返回NULL。
如果宏configUSE_MALLOC_FAILED_HOOK設定為1,那麼必須定義一個malloc()失敗勾點函數,如果宏configUSE_MALLOC_FAILED_HOOK設定為0,malloc()失敗勾點函數不會被呼叫,即便已經定義了這個函數。malloc()失敗勾點函數的函數名和原型必須如下所示:
void vApplicationMallocFailedHook( void);
6.configUSE_TICK_HOOK
設定為1使用時間片勾點(Tick Hook),0忽略時間片勾點。
注:時間片勾點函數(Tick Hook Function)
時間片中斷可以週期性的呼叫一個被稱為勾點函數(回撥函數)的應用程式。時間片勾點函數可以很方便的實現一個定時器功能。
只有在FreeRTOSConfig.h中的configUSE_TICK_HOOK設定成1時才可以使用時間片勾點。一旦此值設定成1,就要定義勾點函數,函數名和引數如下所示:
void vApplicationTickHook( void );
vApplicationTickHook()函數在中斷服務程式中執行,因此這個函數必須非常短小,不能大量使用堆疊,只能呼叫以”FromISR" 或 "FROM_ISR”結尾的API函數。
在FreeRTOSVx.x.xFreeRTOSDemoCommonMinimal資料夾下的crhook.c檔案中有使用時間片勾點函數的例程。
7.configCPU_CLOCK_HZ
寫入實際的CPU核心時脈頻率,也就是CPU指令執行頻率,通常稱為Fcclk。設定此值是為了正確的設定系統節拍中斷週期。
8.configTICK_RATE_HZ
RTOS 系統節拍中斷的頻率。即一秒中斷的次數,每次中斷RTOS都會進行任務排程。
系統節拍中斷用來測量時間,因此,越高的測量頻率意味著可測到越高的解析度時間。但是,高的系統節拍中斷頻率也意味著RTOS核心佔用更多的CPU時間,因此會降低效率。RTOS演範例程都是使用系統節拍中斷頻率為1000HZ,這是為了測試RTOS核心,比實際使用的要高。(實際使用時不用這麼高的系統節拍中斷頻率)
多個任務可以共用一個優先順序,RTOS排程器為相同優先順序的任務分享CPU時間,在每一個RTOS 系統節拍中斷到來時進行工作切換。高的系統節拍中斷頻率會降低分配給每一個任務的“時間片”持續時間。
9.configMAX_PRIORITIES
設定應用程式有效的優先順序數目。任何數量的任務都可以共用一個優先順序,使用協程可以單獨的給與它們優先權。見configMAX_CO_ROUTINE_PRIORITIES。
在RTOS核心中,每個有效優先順序都會消耗一定量的RAM,因此這個值不要超過你的應用實際需要的優先順序數目。
注:任務優先順序
每一個任務都會被分配一個優先順序,優先順序值從0~ (configMAX_PRIORITIES - 1)之間。低優先順序數表示低優先順序任務。空閒任務的優先順序為0(tskIDLE_PRIORITY),因此它是最低優先順序任務。
FreeRTOS排程器將確保處於就緒狀態(Ready)或執行狀態(Running)的高優先順序任務比同樣處於就緒狀態的低優先順序任務優先獲取處理器時間。換句話說,處於執行狀態的任務永遠是高優先順序任務。
處於就緒狀態的相同優先順序任務使用時間片排程機制共用處理器時間。
10.configMINIMAL_STACK_SIZE
定義空閒任務使用的堆疊大小。通常此值不應小於對應處理器演範例程檔案FreeRTOSConfig.h中定義的數值。
就像xTaskCreate()函數的堆疊大小引數一樣,堆疊大小不是以位元組為單位而是以字為單位的,比如在32位元架構下,棧大小為100表示棧記憶體佔用400位元組的空間。
11.configTOTAL_HEAP_SIZE
RTOS核心總計可用的有效的RAM大小。僅在你使用官方下載包中附帶的記憶體分配策略時,才有可能用到此值。每當建立任務、佇列、互斥量、軟體定時器或號誌時,RTOS核心會為此分配RAM,這裡的RAM都屬於configTOTAL_HEAP_SIZE指定的記憶體區。後續的記憶體設定會詳細講到官方給出的記憶體分配策略。
12.configMAX_TASK_NAME_LEN
呼叫任務函數時,需要設定描述任務資訊的字串,這個宏用來定義該字串的最大長度。這裡定義的長度包括字串結束符’