CSP.2020
技術標籤:轉載# FreeRTOSFreeRTOS
FreeRTOS(1)---FreeRTOS 核心配置說明
InfiniteYuan 2018-10-10 14:31:17 1515 收藏 20 分類專欄: # FreeRTOS 文章標籤: FreeRTOS 最後釋出:2018-10-10 14:31:17 首次釋出:2018-10-10 14:31:17 版權FreeRTOS 核心配置說明
FreeRTOS 核心配置
FreeRTOS 核心是高度可定製的,使用配置檔案 FreeRTOSConfig.h
在下載的 FreeRTOS 檔案包中,每個演示例程都有一個 FreeRTOSConfig.h
檔案。有些例程的配置檔案是比較舊的版本,可能不會包含所有有效選項。如果沒有在配置檔案中指定某個選項,那麼 RTOS 核心會使用預設值。典型的 FreeRTOSConfig.h
配置檔案定義如下所示,隨後會說明裡面的每一個引數。
FreeRTOS 配置檔案
#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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
FreeRTOS 配置說明
-
configUSE_PREEMPTION
為1時RTOS使用搶佔式排程器,為0時RTOS使用協作式排程器(時間片)。
注:在多工管理機制上,作業系統可以分為搶佔式和協作式兩種。協作式作業系統是任務主動釋放CPU後,切換到下一個任務。任務切換的時機完全取決於正在執行的任務。
-
configUSE_PORT_OPTIMISED_TASK_SELECTION
某些執行FreeRTOS的硬體有兩種方法選擇下一個要執行的任務:通用方法和特定於硬體的方法(以下簡稱“特殊方法”)。
通用方法:
-
configUSE_PORT_OPTIMISED_TASK_SELECTION
設定為 0 或者硬體不支援這種特殊方法。 -
可以用於所有 FreeRTOS 支援的硬體。
-
完全用 C 實現,效率略低於特殊方法。
-
不強制要求限制最大可用優先順序數目
特殊方法:
-
並非所有硬體都支援。
-
必須將
configUSE_PORT_OPTIMISED_TASK_SELECTION
設定為 1。 -
依賴一個或多個特定架構的彙編指令(一般是類似計算前導零[CLZ]指令)。
-
比通用方法更高效。
-
一般強制限定最大可用優先順序數目為 32。
-
configUSE_TICKLESS_IDLE
設定
configUSE_TICKLESS_IDLE
為1使能低功耗 tickless 模式,為 0 保持系統節拍(tick)中斷一直執行。通常情況下,FreeRTOS 回撥空閒任務鉤子函式(需要設計者自己實現),在空閒任務鉤子函式中設定微處理器進入低功耗模式來達到省電的目的。因為系統要響應系統節拍中斷事件,因此使用這種方法會週期性的退出、再進入低功耗狀態。如果系統節拍中斷頻率過快,則大部分電能和CPU時間會消耗在進入和退出低功耗狀態上。
FreeRTOS的tickless空閒模式會在空閒週期時停止週期性系統節拍中斷。停止週期性系統節拍中斷可以使微控制器長時間處於低功耗模式。移植層需要配置外部喚醒中斷,當喚醒事件到來時,將微控制器從低功耗模式喚醒。微控制器喚醒後,會重新使能系統節拍中斷。由於微控制器在進入低功耗後,系統節拍計數器是停止的,但我們又需要知道這段時間能折算成多少次系統節拍中斷週期,這就需要有一個不受低功耗影響的外部時鐘源,即微處理器處於低功耗模式時它也在計時的,這樣在重啟系統節拍中斷時就可以根據這個外部計時器計算出一個調整值並寫入RTOS 系統節拍計數器變數中。
-
configUSE_IDLE_HOOK
設定為1使用空閒鉤子(Idle Hook 類似於回撥函式),0忽略空閒鉤子。
當 RTOS 排程器開始工作後,為了保證至少有一個任務在執行,空閒任務被自動建立,佔用最低優先順序(0優先順序)。對於已經刪除的 RTOS 任務,空閒任務可以釋放分配給它們的堆疊記憶體。因此,在應用中應該注意,使用
vTaskDelete()
函式時要確保空閒任務獲得一定的處理器時間。除此之外,空閒任務沒有其它特殊功能,因此可以任意的剝奪空閒任務的處理器時間。應用程式也可能和空閒任務共享同個優先順序。
空閒任務鉤子是一個函式,這個函式由使用者來實現,RTOS 規定了函式的名字和引數,這個函式在每個空閒任務週期都會被呼叫。
要建立一個空閒鉤子:
-
設定
FreeRTOSConfig.h
檔案中的configUSE_IDLE_HOOK
為1; -
定義一個函式,函式名和引數如下所示:
void vApplicationIdleHook(void );
- 1
這個鉤子函式不可以呼叫會引起空閒任務阻塞的API函式(例如:vTaskDelay()、帶有阻塞時間的佇列和訊號量函式),在鉤子函式內部使用協程是被允許的。
使用空閒鉤子函式設定CPU進入省電模式是很常見的。
-
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);
- 1
-
configUSE_TICK_HOOK
設定為1使用時間片鉤子(Tick Hook),0忽略時間片鉤子。
注:時間片鉤子函式(Tick Hook Function)
時間片中斷可以週期性的呼叫一個被稱為鉤子函式(回撥函式)的應用程式。時間片鉤子函式可以很方便的實現一個定時器功能。
只有在FreeRTOSConfig.h中的configUSE_TICK_HOOK設定成1時才可以使用時間片鉤子。一旦此值設定成1,就要定義鉤子函式,函式名和引數如下所示:
void vApplicationTickHook( void );
- 1
vApplicationTickHook()函式在中斷服務程式中執行,因此這個函式必須非常短小,不能大量使用堆疊,不能呼叫任何不是以”FromISR" 或 "FROM_ISR”結尾的API函式。
在FreeRTOSVx.x.x\FreeRTOS\Demo\Common\Minimal資料夾下的crhook.c檔案中有使用時間片鉤子函式的例程。
-
configCPU_CLOCK_HZ
寫入實際的CPU核心時鐘頻率,也就是CPU指令執行頻率,通常稱為Fcclk。配置此值是為了正確的配置系統節拍中斷週期。
-
configTICK_RATE_HZ
RTOS 系統節拍中斷的頻率。即一秒中斷的次數,每次中斷RTOS都會進行任務排程。
系統節拍中斷用來測量時間,因此,越高的測量頻率意味著可測到越高的解析度時間。但是,高的系統節拍中斷頻率也意味著RTOS核心佔用更多的CPU時間,因此會降低效率。RTOS演示例程都是使用系統節拍中斷頻率為1000HZ,這是為了測試RTOS核心,比實際使用的要高。(實際使用時不用這麼高的系統節拍中斷頻率)
多個任務可以共享一個優先順序,RTOS排程器為相同優先順序的任務分享CPU時間,在每一個RTOS 系統節拍中斷到來時進行任務切換。高的系統節拍中斷頻率會降低分配給每一個任務的“時間片”持續時間。
-
configMAX_PRIORITIES
配置應用程式有效的優先順序數目。任何數量的任務都可以共享一個優先順序,使用協程可以單獨的給與它們優先權。見configMAX_CO_ROUTINE_PRIORITIES。
在RTOS核心中,每個有效優先順序都會消耗一定量的RAM,因此這個值不要超過你的應用實際需要的優先順序數目。
注:任務優先順序
每一個任務都會被分配一個優先順序,優先順序值從0~ (configMAX_PRIORITIES - 1)之間。低優先順序數表示低優先順序任務。空閒任務的優先順序為0(tskIDLE_PRIORITY),因此它是最低優先順序任務。
FreeRTOS排程器將確保處於就緒狀態(Ready)或執行狀態(Running)的高優先順序任務比同樣處於就緒狀態的低優先順序任務優先獲取處理器時間。換句話說,處於執行狀態的任務永遠是高優先順序任務。
處於就緒狀態的相同優先順序任務使用時間片排程機制共享處理器時間。
-
configMINIMAL_STACK_SIZE
定義空閒任務使用的堆疊大小。通常此值不應小於對應處理器演示例程檔案FreeRTOSConfig.h中定義的數值。
就像xTaskCreate()函式的堆疊大小引數一樣,堆疊大小不是以位元組為單位而是以字為單位的,比如在32位架構下,棧大小為100表示棧記憶體佔用400位元組的空間。
-
configTOTAL_HEAP_SIZE
RTOS核心總計可用的有效的RAM大小。僅在你使用官方下載包中附帶的記憶體分配策略時,才有可能用到此值。每當建立任務、佇列、互斥量、軟體定時器或訊號量時,RTOS核心會為此分配RAM,這裡的RAM都屬於configTOTAL_HEAP_SIZE指定的記憶體區。後續的記憶體配置會詳細講到官方給出的記憶體分配策略。
-
configMAX_TASK_NAME_LEN
呼叫任務函式時,需要設定描述任務資訊的字串,這個巨集用來定義該字串的最大長度。這裡定義的長度包括字串結束符’\0’。
-
configUSE_TRACE_FACILITY
設定成1表示啟動視覺化跟蹤除錯,會啟用一些附加的結構體成員和函式。
-
configUSE_STATS_FORMATTING_FUNCTIONS (V7.5.0新增)
設定巨集configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS為1會編譯vTaskList()和vTaskGetRunTimeStats()函式。如果將這兩個巨集任意一個設定為0,上述兩個函式不會被編譯。
-
configUSE_16_BIT_TICKS
定義系統節拍計數器的變數型別,即定義portTickType是表示16位變數還是32位變數。
-
定義configUSE_16_BIT_TICKS為1意味著portTickType代表16位無符號整形
-
定義configUSE_16_BIT_TICKS為0意味著portTickType代表32位無符號整形。
使用16位型別可以大大提高8位和16位架構微處理器的效能,但這也限制了最大時鐘計數為65535個’Tick’。因此,如果Tick頻率為250HZ(4MS中斷一次),對於任務最大延時或阻塞時間,16位計數器是262秒,而32位是17179869秒。
-
configIDLE_SHOULD_YIELD
這個引數控制任務在空閒優先順序中的行為。僅在滿足下列條件後,才會起作用。
-
使用搶佔式核心排程
-
使用者任務使用空閒優先順序。
通過時間片共享同一個優先順序的多個任務,如果共享的優先順序大於空閒優先順序,並假設沒有更高優先順序任務,這些任務應該獲得相同的處理器時間。
但如果共享空閒優先順序時,情況會稍微有些不同。當configIDLE_SHOULD_YIELD為1時,其它共享空閒優先順序的使用者任務就緒時,空閒任務立刻讓出CPU,使用者任務執行,這樣確保了能最快響應使用者任務。處於這種模式下也會有不良效果(取決於你的程式需要),描述如下:
圖中描述了四個處於空閒優先順序的任務,任務A、B和C是使用者任務,任務I是空閒任務。上下文切換週期性的發生在T0、T1…T6時刻。當用戶任務執行時,空閒任務立刻讓出CPU,但是,空閒任務已經消耗了當前時間片中的一定時間。這樣的結果就是空閒任務I和使用者任務A共享一個時間片。使用者任務B和使用者任務C因此獲得了比使用者任務A更多的處理器時間。
可以通過下面方法避免:
-
如果合適的話,將處於空閒優先順序的各單獨的任務放置到空閒鉤子函式中;
-
建立的使用者任務優先順序大於空閒優先順序;
-
設定IDLE_SHOULD_YIELD為0;
設定configIDLE_SHOULD_YIELD為0將阻止空閒任務為使用者任務讓出CPU,直到空閒任務的時間片結束。這確保所有處在空閒優先順序的任務分配到相同多的處理器時間,但是,這是以分配給空閒任務更高比例的處理器時間為代價的。