FreeRTOS


一、內核配置

1、configUSE_PREEMPTION

設置為1,使用搶先式內核;設置為0,為合作輪轉內核。

2、configCPU_CLOCK_HZ

內部處理器執行的頻率。這個值需要正確配置外圍定時器。

3、configTICK_RATE_HZ(1-1000)

RTOS時間片中斷的頻率。

時間片中斷用來測量時間。因此更高時間片頻率意味着時間測量可以有更高分辨率,同時意味着內核占用更多的CPU(效率很低)。

多個任務共有同一優先級。通過切換任務,在每一個RTOS時間片內,內核將在同一優先級的任務間分配處理器時間。高時間片頻率意味着將減少給予每個任務的時間份額。

4、configMAX_PRIORITIES(4-32)

應用程序任務中可用優先級的數目. 

任何數量的任務,都可以分配同一優先級也可以單獨分配優先級。參考configMAX_CO_ROUTINE_PRIORITIES。 內核分配的每個可用的優先級都消耗RAM,因此這個值不應該設置為高於實際應用程序中需要的。

5、configMINIMAL_STACK_SIZE(64words-768words)

空閑任務使用的堆棧大小。通常這個值不用少於 FreeRTOSConfig.h file中演示程序提供的。

max value = configTOTAL_HEAP_SIZE / 4(when allocation is dynamic)

max value = MCU RAM Size / 4 (when allocation is static)

6、configMAX_TASK_NAME_LEN(12-255)

當創建一個任務,能夠給予描述任務名稱的最大容許長度。這個長度指定符號數目,包括NULL終止字節。

7、configUSE_16_BIT_TICKS

時間片(內核開始執行后,時間片中斷的次數)來測量時間。時間片計數器定義為可用的portTickType.類型。

定義configUSE_16_BIT_TICKS為1,將使portTickType定義為16位無符號類型。定義為0,將是32位無符號類型。 使用16位類型,將使在16位或8位單片機大幅度提高性能。但是,這樣限制了最大指定可用時間周期(65535時間片)。然而,假定時間片頻率為250Hz,一個任務在16位上,最大延時或中斷時間位262秒,而32位為17179869秒。

8、configIDLE_SHOULD_YIELD

這個參數控制任務與空閑任務優先級相同時的行為。僅僅有以下影響:

  1. 使用優先級調度
  2. 用戶程序創建的任務,運行在空閑任務一樣的優先級

任務在時間片輪轉中,使用同一優先級。假定沒有更高優先級的任務,這樣每一個任務,在空閑優先級下,將被分配相同數量的處理時間。如果,他們的優先級高於空閑任務的優先級,那么這種情況更是如此。 當任務處於空閑優先級下的行為,會有稍許不同。當configIDLE_SHOULD_YIELD設置為1時,當其他在空閑優先級的任務准備運行時,空閑任務將立刻讓出CPU。當程序的任務調度可用時,要確保空閑任務能夠執行的最少時間以上。這個行為,產生了不好的影響(根據應用程序的需要),如下描述:

上述圖表表明,四個在空閑優先級的任務執行模型。任務A, B,和C,是應用程序任務。任務 I是空閑任務。上下文切換在T0, T1....T6規律的周期間發生。當空閑任務執行時,任務A准備執行,但是空閑任務已經占去了當前時間片的部分時間。結果是,任務I 和任務A共同分享一個時間片。任務B 和任務C比任務A獲得更多的執行時間。

這些可以通過如下避免:

  1. 如果合適,可以使用空閑鈎子代替在空閑優先級的分開任務。創建程序任務的優先級高於空閑優先級。
  2. 設置configIDLE_SHOULD_YIELD為1

設置configIDLE_SHOULD_YIELD為1,將阻止空閑任務讓出執行時間直到它的時間片用完。這就確保了所有在空閑優先級的任務分配了相同數量的執行時間。這是以分配給空閑任務更高比例的執行時間為代價。

9、configUSE_MUTEXES

設置為1,將使用互斥功能;設置為0,將不使用。

10、configUSE_RECURSIVE_MUTEXES

設置為1,將使用遞歸互斥功能;設置為0,將不使用。

11、configUSE_COUNTING_SEMAPHORES

設置為1,將使用計數器型信號量功能;設置為0,將不使用。

12、configQUEUE_REGISTRY_SIZE(0-255)

隊列記錄有兩個功能,都這涉及到內核相關的調試:

  1. 允許一個隊列相關的名稱,可以在GUI調試中容易定義。
  2. 包含了調試器所需的信息,來定位每個記錄的隊列和信號量。

隊列記錄除了進行內核相關的調試外,沒有什么目的。 configQUEUE_REGISTRY_SIZE定義了可以記錄的隊列和信號量的最大數目。這些僅能夠在使用內核相關調試時需要記錄的。查看API中vQueueAddToRegistry() 和 vQueueUnregisterQueue()參考文檔,獲得更多信息。

13、configUSE_APPLICATION_TASK_TAG

為任務分配標簽值,設置為1來使用vTaskSetApplicationTaskTag函數,分配的標簽只對應用程序有用,內核不使用

14、configENABLE_BACKWARD_COMPATIBILITY

頭文件FreeRTOS.h包含一系列#define宏定義,用來映射版本V8.0.0和V8.0.0之前版本的數據類型名字。這些宏可以確保RTOS內核升級到V8.0.0或以上版本時,之前的應用代碼不用做任何修改。在FreeRTOSConfig.h文件中設置宏configENABLE_BACKWARD_COMPATIBILITY為0會去掉這些宏定義,並且需要用戶確認升級之前的應用沒有用到這些名字

15、configUSE_PORT_OPTIMISED_TASK_SELECTION

某些運行FreeRTOS的硬件有兩種方法選擇下一個要執行的任務:通用方法和特定於硬件的方法(以下簡稱“特殊方法”)。

通用方法:

  • configUSE_PORT_OPTIMISED_TASK_SELECTION設置為0或者硬件不支持這種特殊方法。
  • 可以用於所有FreeRTOS支持的硬件。
  • 完全用C實現,效率略低於特殊方法。
  • 不強制要求限制最大可用優先級數目

特殊方法:

  • 並非所有硬件都支持。
  • 必須將configUSE_PORT_OPTIMISED_TASK_SELECTION設置為1。
  • 依賴一個或多個特定架構的匯編指令(一般是類似計算前導零[CLZ]指令)。
  • 比通用方法更高效。
  • 一般強制限定最大可用優先級數目為32。

16、configUSE_TICKLESS_IDLE

設置configUSE_TICKLESS_IDLE為1使能低功耗tickless模式,為0保持系統節拍(tick)中斷一直運行。

通常情況下,FreeRTOS回調空閑任務鈎子函數(需要設計者自己實現),在空閑任務鈎子函數中設置微處理器進入低功耗模式來達到省電的目的。因為系統要響應系統節拍中斷事件,因此使用這種方法會周期性的退出、再進入低功耗狀態。如果系統節拍中斷頻率過快,則大部分電能和CPU時間會消耗在進入和退出低功耗狀態上。

FreeRTOS的tickless空閑模式會在空閑周期時停止周期性系統節拍中斷。停止周期性系統節拍中斷可以使微控制器長時間處於低功耗模式。移植層需要配置外部喚醒中斷,當喚醒事件到來時,將微控制器從低功耗模式喚醒。微控制器喚醒后,會重新使能系統節拍中斷。由於微控制器在進入低功耗后,系統節拍計數器是停止的,但我們又需要知道這段時間能折算成多少次系統節拍中斷周期,這就需要有一個不受低功耗影響的外部時鍾源,即微處理器處於低功耗模式時它也在計時的,這樣在重啟系統節拍中斷時就可以根據這個外部計時器計算出一個調整值並寫入RTOS 系統節拍計數器變量中。

17、configUSE_TASK_NOTIFICATIONS

設置宏configUSE_TASK_NOTIFICATIONS為1(或不定義宏configUSE_TASK_NOTIFICATIONS)將會開啟任務通知功能,有關的API函數也會被編譯。設置宏configUSE_TASK_NOTIFICATIONS為0則關閉任務通知功能,相關API函數也不會被編譯。默認這個功能是開啟的。開啟后,每個任務多增加8字節RAM。
這是個很有用的特性,一大亮點。

每個RTOS任務具有一個32位的通知值,RTOS任務通知相當於直接向任務發送一個事件,接收到通知的任務可以解除任務的阻塞狀態(因等待任務通知而進入阻塞狀態)。相對於以前必須分別創建隊列、二進制信號量、計數信號量或事件組的情況,使用任務通知顯然更靈活。更好的是,相比於使用信號量解除任務阻塞,使用任務通知可以快45%(使用GCC編譯器,-o2優化級別)。

二、內存管理設置

1、configSUPPORT_DYNAMIC_ALLOCATION 

定義為 1的話在創建 FreeRTOS的內核對象時候 所需要的 RAM就會從 FreeRTOS的堆中 的堆中 動態的獲取內存,定義為0的話需要用戶自行提供。默認為1。詳細信息,參見Static Vs Dynamic Memory Allocation

2、configSUPPORT_STATIC_ALLOCATION

設置為1,那么可以使用應用程序編寫器提供的RAM創建RTOS對象。設置為0,則只能使用從FreeRTOS堆分配的RAM創建RTOS對象。默認(未定義時)為0 

如果設置為1,則應用程序編寫器還必須提供兩個回調函數:vApplicationGetIdleTaskMemory()以提供內存供RTOS空閑任務使用;(如果configUSE_TIMERS設置為1)vApplicationGetTimerTaskMemory() 以提供內存供RTOS守護進程/定時器服務任務使用。

3、configTOTAL_HEAP_SIZE(512Bytes-64KBytes)

系統可用內存。一般設成除了操作系統和你的程序所用RAM外的最大RAM。 比如20KRAM你用了2K,系統用了3K,剩下15就是最大HEAP 尺寸。你可以先設小然后看編譯結果往大里加。

每當創建任務、隊列、互斥量、軟件定時器或信號量時,RTOS內核會為此分配RAM,這里的RAM都屬於configTOTAL_HEAP_SIZE指定的內存區。

4、HEAP_NUMBER選擇

可從heap_1、 heap_2、 heap_3、 heap_4、 heap_5中選擇一種heap分配方案

三、與鈎子相關的功能定義

1、configUSE_IDLE_HOOK

設置為1, 使用空閑鈎子,用戶應用程序必須定義一個空閑任務鈎子函數void vApplicationIdleHook(void);設置為0,不使用空閑鈎子。

當RTOS調度器開始工作后,為了保證至少有一個任務在運行,空閑任務被自動創建,占用最低優先級(0優先級)。對於已經刪除的RTOS任務,空閑任務可以釋放分配給它們的堆棧內存。因此,在應用中應該注意,使用vTaskDelete()函數時要確保空閑任務獲得一定的處理器時間。除此之外,空閑任務沒有其它特殊功能,因此可以任意的剝奪空閑任務的處理器時間。應用程序也可能和空閑任務共享同個優先級。

2、configUSE_TICK_HOOK

設置為1使用時間片鈎子(Tick Hook),用戶應用程序必須定義一個tick鈎子函數void vApplicationTickHook(void);0忽略時間片鈎子。

時間片中斷可以周期性的調用一個被稱為鈎子函數(回調函數)的應用程序。時間片鈎子函數可以很方便的實現一個定時器功能。

3、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()失敗鈎子函數void vApplicationMallocFailedHook( void),如果宏configUSE_MALLOC_FAILED_HOOK設置為0,malloc()失敗鈎子函數不會被調用,即便已經定義了這個函數。

4、configUSE_DAEMON_TASK_STARTUP_HOOK

定義守護進程HOOK函數,如果設置為1且configUSE_TIMERS設置為1,用戶應用程序必須定義一個守護鈎子函數void vApplicationDaemonTaskStartupHook(void);

5、configCHECK_FOR_STACK_OVERFLOW

每個任務維護自己的棧空間,任務創建時會自動分配任務需要的棧內存,分配內存大小由創建任務函數(xTaskCreate())的一個參數指定。堆棧溢出是設備運行不穩定的最常見原因,因此FreeeRTOS提供了兩個可選機制用來輔助檢測和改正堆棧溢出。配置宏configCHECK_FOR_STACK_OVERFLOW為不同的常量來使用不同堆棧溢出檢測機制。

注意,這個選項僅適用於內存映射未分段的微處理器架構。並且,在RTOS檢測到堆棧溢出發生之前,一些處理器可能先產生故障(fault)或異常(exception)來反映堆棧使用的惡化。如果宏configCHECK_FOR_STACK_OVERFLOW沒有設置成0,用戶必須提供一個棧溢出鈎子函數,這個鈎子函數的函數名和參數必須如下所示:

void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName );

參數xTask和pcTaskName為堆棧溢出任務的句柄和名字。請注意,如果溢出非常嚴重,這兩個參數信息也可能是錯誤的!在這種情況下,可以直接檢查pxCurrentTCb變量。

方法1:設置configCHECK_FOR_STACK_OVERFLOW為1:

任務切換出去后,該任務的上下文環境被保存到自己的堆棧空間,這時很可能堆棧的使用量達到了最大(最深)值。在這個時候,RTOS內核會檢測堆棧指針是否還指向有效的堆棧空間。如果堆棧指針指向了有效堆棧空間之外的地方,堆棧溢出鈎子函數會被調用。

這個方法速度很快,但是不能檢測到所有堆棧溢出情況(比如,堆棧溢出沒有發生在上下文切換時)。

方法2:設置configCHECK_FOR_STACK_OVERFLOW為2(包括方法1):

當堆棧首次創建時,在它的堆棧區中填充一些已知值(標記)。當任務切換時,RTOS內核會檢測堆棧最后的16個字節,確保標記數據沒有被覆蓋。如果這16個字節有任何一個被改變,則調用堆棧溢出鈎子函數。

這個方法比第一種方法要慢,但也相當快了。它能有效捕捉堆棧溢出事件(即使堆棧溢出沒有發生在上下文切換時),但是理論上它也不能百分百的捕捉到所有堆棧溢出(比如堆棧溢出的值和標記值相同,當然,這種情況發生的概率極小)。

四、系統運行與收集任務統計相關的定義

1、configGENERATE_RUN_TIME_STATS

設置宏configGENERATE_RUN_TIME_STATS為1使能運行時間統計功能。一旦設置為1,則下面兩個宏必須被定義:

  Ⅰ、portCONFIGURE_TIMER_FOR_RUN_TIME_STATS():用戶程序需要提供一個基准時鍾函數,函數完成初始化基准時鍾功能,這個函數要被define到宏portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()上。這是因為運行時間統計需要一個比系統節拍中斷頻率還要高分辨率的基准定時器,否則,統計可能不精確。基准定時器中斷頻率要比統計節拍中斷快10~100倍。基准定時器中斷頻率越快,統計越精准,但能統計的運行時間也越短(比如,基准定時器10ms中斷一次,8位無符號整形變量可以計到2.55秒,但如果是1秒中斷一次,8位無符號整形變量可以統計到255秒)。
  Ⅱ、portGET_RUN_TIME_COUNTER_VALUE():用戶程序需要提供一個返回基准時鍾當前“時間”的函數,這個函數要被define到宏portGET_RUN_TIME_COUNTER_VALUE()上。

舉一個例子,假如我們配置了一個定時器,每500us中斷一次。在定時器中斷服務例程中簡單的使長整形變量ulHighFrequencyTimerTicks自增。那么上面提到兩個宏定義如下(可以在FreeRTOSConfig.h中添加):

extern volatile unsigned longulHighFrequencyTimerTicks;
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ( ulHighFrequencyTimerTicks = 0UL )
#define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerTicks

2、configUSE_TRACE_FACILITY

設置成1表示啟動可視化跟蹤調試,會激活一些附加的結構體成員和函數。

3、configUSE_STATS_FORMATTING_FUNCTIONS

設置為1且宏configUSE_TRACE_FACILITY也設置為1,則會編譯vTaskList()和vTaskGetRunTimeStats()函數。如果將這兩個宏任意一個設置為0,上述兩個函數不會被編譯。

五、協程定義

1、configUSE_CO_ROUTINES

設置成1表示使用協程,0表示不使用協程。如果使用協程,必須在工程中包含croutine.c文件。

注:協程(Co-routines)主要用於資源發非常受限的嵌入式系統(RAM非常少),通常不會用於32位微處理器。

在當前嵌入式硬件環境下,不建議使用協程,FreeRTOS的開發者早已經停止開發協程。

2、configMAX_CO_ROUTINE_PRIORITIES(1-255)

應用程序協程(Co-routines)的有效優先級數目,任何數目的協程都可以共享一個優先級。使用協程可以單獨的分配給任務優先級。見configMAX_PRIORITIES。

六、軟件定時器定義

1、configUSE_TIMERS

設置成1使用軟件定時器,為0不使用軟件定時器功能。

如果使能,將會給定時器任務分配4*configTIMER_TASK_STACK_DEPTH字節

七、中斷嵌套行為配置

1、configLIBRARY_LOWEST_INTERRUPT_PRIORITY

此宏定義是用來配置FreeRTOS用到的SysTick中斷和PendSV中斷的優先級。在NVIC分組設置為4的情況下,此宏定義的范圍就是0-15,即專門配置搶占優先級。這里配置為了0x0f,即SysTick和PendSV都是配置為了最低優先級,實際項目中也建議大家配置最低優先級即可。

2、configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

此宏定義比較重要,定義了受FreeRTOS管理的最高優先級中斷。簡單的說就是允許用戶在這個中斷服務程序里面調用FreeRTOS的API的最高優先級。設置NVIC的優先級分組為4的情況下。配置configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY為0x01表示用戶可以在搶占式優先級為1到15的中斷里面調用FreeRTOS的API函數,搶占式優先級為0的中斷里面是不允許調用的。

3、configKERNEL_INTERRUPT_PRIORITY

宏定義configLIBRARY_LOWEST_INTERRUPT_PRIORITY的數值經過4bit偏移后得到一個8bit的優先級數值,即宏定義configKERNEL_INTERRUPT_PRIORITY的數值。這個8bit的數值才可以實際賦值給相應中斷的優先級寄存器。

也許初學者有疑問了,為什么前面NVIC配置的時候不是8bit的方式進行配置?這是因為ST的庫函數NVIC_Init()已經為我們做好了。這里的宏定義數值是供PendSV和SysTick中斷進行優先級配置的。比如:我們這里配置宏定義configLIBRARY_LOWEST_INTERRUPT_PRIORITY是0x0f,經過4bit偏移后就是0xf0,即SysTick和PendSV的中斷優先級就是240。

#define configKERNEL_INTERRUPT_PRIORITY   ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

4、configMAX_SYSCALL_INTERRUPT_PRIORITY

宏定義configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的數值經過4bit偏移后得到一個8bit的優先級數值,即宏定義configMAX_SYSCALL_INTERRUPT_PRIORITY的數值。這個數值是賦值給寄存器basepri使用的,8bit的數值才可以實際賦值給相應中斷的優先級寄存器。這里的宏定義數值賦給寄存器basepri后就可以實現全局的開關中斷操作了。

比如:我們這里配置宏定義configLIBRARY_LOWEST_INTERRUPT_PRIORITY是0x01,經過4bit偏移后就是0x10,即16。調用了FreeRTOS的關中斷后,所有優先級數值大於等於16的中斷都會被關閉。優先級數值小於16的中斷不會被關閉,對寄存器basepri寄存器賦值0,那么被關閉的中斷會被打開。

八、INCLUDE參數配置

1、INCLUDE_vTaskPrioritySet 

原型:void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )

描述:函數vTaskPrioritySet用於實現FreeRTOS任務優先級的修改

(1)第1個參數是任務句柄,用於區分不同的任務

(2)第2個參數是給任務配置的新優先級

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_vTaskPrioritySet 1

(2)如果第二個參數里面填的是NULL,即數值0的話,那么配置的就是當前正在執行的任務

(3)如果被修改的任務的優先級,修改后高於正在執行的任務,將執行任務切換,切換到修改好的高優先級任務

(4)第二個參數數值不可大於等於FreeRTOSConfig.h文件中的宏定義:#define configMAX_PRIORITIES 配置的數值

2、INCLUDE_uxTaskPriorityGet

原型:UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )

描述:函數uxTaskPriorityGet用於獲取FreeRTOS任務優先級

(1)第1個參數是任務句柄,用於區分不同的任務

(2)返回任務優先級

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_uxTaskPriorityGet 1

(2)如果第二個參數里面填的是NULL,即數值0的話,那么配置的就是當前正在執行的任務

3、INCLUDE_vTaskDelete

原型:void vTaskDelete( TaskHandle_t xTask )

描述:從RTOS內核管理器中刪除一個任務。任務刪除后將會從就緒、阻塞、暫停和事件列表中移除。

(1)第1個參數是任務句柄,用於區分不同的任務

注意事項:

 (1)被刪除的任務,其在任務創建時由內核分配的存儲空間,會由空閑任務釋放。如果有應用程序調用xTaskDelete(),必須保證空閑任務獲取一定的微控制器處理時間。任務代碼自己分配的內存是不會自動釋放的,因此刪除任務前,應該將這些內存釋放。

(2)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_vTaskDelete 1

(3)如果參數里面填的是NULL,即數值0的話,那么刪除的就是當前正在執行的任務

4、INCLUDE_vTaskCleanUpResources

原型:void vTaskCleanUpResources( 未知 )

描述:未知

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_vTaskCleanUpResources 1

5、INCLUDE_vTaskSuspend

原型:void vTaskSuspend( TaskHandle_t xTaskToSuspend )

描述:掛起指定任務,被掛起的任務絕不會得到處理器時間,不管該任務具有什么優先級

(1)第1個參數是任務句柄,用於區分不同的任務

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_vTaskSuspend 1

(2)調用vTaskSuspend函數是不會累計的:即使多次調用vTaskSuspend ()函數將一個任務掛起,也只需調用一次vTaskResume ()函數就能使掛起的任務解除掛起狀態。

(3)如果參數里面填的是NULL,即數值0的話,那么刪除的就是當前正在執行的任務

6、INCLUDE_vTaskDelayUntil

原型:void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )

描述:任務絕對延時,該函數用在周期性任務以保證任務執行頻率的穩定

(1)第1個參數:上一次喚醒的時間計數器

(2)第2個參數:間隔周期計數器

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_vTaskDelayUntil 1

(2)任務體的執行時間必須小於延時時間,否則延時將不起作用

(3)就算是低優先級任務在需要運行的時候被打斷也會在下一次延時中補償回來,所以延時時間相對絕對

(4)絕對延時是指每隔指定的時間,執行一次調用vTaskDelayUntil()函數的任務,換句話說:延時時間是保證任務以固定頻率執行,例如設置TimeIncrement為20ms,則1s內任務將被執行50次

(5)當執行vTaskDelayUntil()后,除了第一次是間隔TimeIncrement時間執行vTaskDelayUntil()之后的代碼外,之后的情況都比這個時間少,因為延時的時間是包括任務體執行的時間在內的

7、INCLUDE_vTaskDelay

原型:void vTaskDelay( const TickType_t xTicksToDelay )

描述:任務相對延時

(1)第一個參數指延時的時間片,例如系統頻率200HZ,則一個時間片就是5ms,設置參數為100,那么延時時間就是500ms

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_vTaskDelay 1

(2)相對延時是指每次延時都是從任務執行函數vTaskDelay()開始,延時指定的時間結束

8、INCLUDE_xTaskGetSchedulerState

原型:BaseType_t xTaskGetSchedulerState( void )

描述:獲取調度器當前狀態

(1)返回值是以下常量之一(定義在task.h):taskSCHEDULER_NOT_STARTED(未啟動)、taskSCHEDULER_RUNNING(正常運行)、taskSCHEDULER_SUSPENDED(掛起)

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xTaskGetSchedulerState 1或者onfigUSE_TIMERS必須定義為1

9、INCLUDE_xTaskResumeFromISR

原型:BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )

描述:用於在中斷里面恢復一個掛起的任務

(1)第一個參數是要恢復運行的任務句柄

(2)如果恢復任務后需要上下文切換返回pdTRUE,否則返回pdFALSE

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xTaskResumeFromISR 1

(2)通過調用一次或多次vTaskSuspend()函數而掛起的任務,只需調用一次xTaskResumeFromISR()函數即可恢復運行

(3) xTaskResumeFromISR()不可用於任務和中斷間的同步,如果中斷恰巧在任務被掛起之前到達,這就會導致一次中斷丟失(任務還沒有掛起,調用xTaskResumeFromISR()函數是沒有意義的,只能等下一次中斷)。這種情況下,可以使用信號量作為同步機制。

10、INCLUDE_xQueueGetMutexHolder

原型:void* xQueueGetMutexHolder( QueueHandle_t xSemaphore )

描述:獲取信號量的隊列擁有者

(1)第一個參數指定一個信號量

(2)返回擁有此信號量的隊列

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xQueueGetMutexHolder 1

(2)此函數由xSemaphoreGetMutexHolder()調用,不應該直接使用

(3)此配置常量被用於xSemaphoreGetMutexHolder的默認值

11、INCLUDE_xSemaphoreGetMutexHolder

原型:TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex )

描述:查詢擁有互斥鎖的任務句柄

(1)第一個參數指定一個互斥鎖

(2)返回非NULL,任務持有互斥信號量的任務句柄,NULL,xMutex不是一個互斥信號量或者信號量沒有被任務持有

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xSemaphoreGetMutexHolder 1且配置configUSE_MUTEXES為1

(2)此函數在RTOS中的定義為#define xSemaphoreGetMutexHolder( xSemaphore )  xQueueGetMutexHolder( ( xSemaphore ) ),其配置值由xQueueGetMutexHolder決定

12、INCLUDE_pcTaskGetTaskName

原型:char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery )

描述:獲取任務的名字

(1)第一個參數指定任務句柄

(2)返回任務的名字

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_pcTaskGetTaskName 1

(2)如果參數為NULL,則獲取的當前調用任務的名字

13、INCLUDE_uxTaskGetStackHighWaterMark

原型:UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )

描述:每個任務都獨立維護自己的棧空間, 棧空間總量在任務創建時進行設定。uxTaskGetStackHighWaterMark()主要用來查詢指定任務的運行歷史中, 其棧空間還差多少就要溢出。這個值被稱為棧空間的”高水線(High Water Mark)

(1)第一個參數:被查詢任務的句柄
(2)任務棧空間的實際使用量會隨着任務執行和中斷處理過程上下浮動。uxTaskGetStackHighWaterMark()返回從任務啟動執行開始的運行歷史中,棧空間具有的最小剩余量。這個值即是棧空間使用達到最深時的剩下的未使用的棧空間。這個值越是接近 0,則這個任務就越是離棧溢出不遠了

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_uxTaskGetStackHighWaterMark 1

14、INCLUDE_xTaskGetCurrentTaskHandle

原型:TaskHandle_t xTaskGetCurrentTaskHandle( void )

描述:獲取當前執行任務的句柄

(1)返回任務句柄

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xTaskGetCurrentTaskHandle 1

15、INCLUDE_eTaskGetState

原型:eTaskState eTaskGetState( TaskHandle_t xTask )

描述:獲取任務運行狀態

(1)第一個參數:任務句柄

(2)返回任務狀態的枚舉值

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_eTaskGetState 1

(2)任務的枚舉狀態有:eRunning(運行)、eReady(就緒)、eBlocked(阻塞)、eSuspended(掛起)、eDeleted(刪除)(任務的結構等待被清理狀態)

16、INCLUDE_xEventGroupSetBitFromISR

原型:BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )

描述:用於設置指定的事件標志位為1

(1)第1個參數是事件標志組句柄

(2)第2個參數表示24個可設置的事件標志位,EventBits_t是定義的32位變量,低24位用於事件標志設置。變量uxBitsToSet的低24位的某個位設置為1,那么被設置的事件標志組的相應位就設置為1。變量uxBitsToSet設置為0的位對事件標志相應位沒有影響。比如設置變量uxBitsToSet = 0x0003就表示將事件標志的位0和位1設置為1,其余位沒有變化

(3)返回值,如果消息成功發送給daemon任務(就是FreeRTOS的定時器任務)返回pdPASS,否則返回pdFAIL,另外daemon任務中的消息隊列滿了也會返回pdFAIL

注意事項:

(1)使用前一定要保證事件標志已經通過函數xEventGroupCreate創建了

(2)在FreeRTOSConfig.h文件中使能如下三個宏定義:

  #define  INCLUDE_xEventGroupSetBitFromISR   1

  #define  configUSE_TIMERS                        1

  #define  INCLUDE_xTimerPendFunctionCall     1

(3) 函數xEventGroupSetBitsFromISR是用於中斷服務程序中調用的,故不可以在任務代碼中調用此函數,任務代碼中使用的是xEventGroupSetBits

(4)函數xEventGroupSetBitsFromISR對事件標志組的操作是不確定性操作,因為不知道當前有多少個任務在等待此事件標志。而FreeRTOS不允許在中斷服務程序和臨界段中執行不確定性操作。為了不在中斷服務程序中執行,就通過此函數給FreeRTOS的daemon任務(就是FreeRTOS的定時器任務)發送消息,在daemon任務中執行事件標志的置位操作。同時也為了不在臨界段中執行此不確定操作,將臨界段改成由調度鎖來完成。這樣不確定性操作在中斷服務程序和臨界段中執行的問題就都得到解決了

(5)由於函數xEventGroupSetBitsFromISR對事件標志的置位操作是在daemon任務里面執行的,如果想讓置位操作立即生效,即讓等此事件標志的任務能夠得到及時執行,需要設置daemon任務的優先級高於使用此事件標志組的所有其它任務

17、INCLUDE_xTimerPendFunctionCall

原型:BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait )

描述:定時器守護任務回調函數,用於延時定時器守護任務的執行

(1)第一個參數:定時器守護任務執行的功能函數,類型為PendedFunction_t

(2)第二個參數:傳遞給回調函數的值,可以是任意類型

(3)第三個參數:傳遞給回調函數的第二個值,為uint32_t 類型

(4)第四個參數:當調用此函數的時候將會發送一個消息到定時器守護任務隊列,xTicksToWait 指定了任務在隊列滿的情況下處於阻塞狀態的時間

(5)返回:

  pdPASS:消息成功發送到RTOS守護任務

  other:由於消息隊列滿導致消息發送失敗。消息隊列長度在FreeRTOSConfig.h配置文件中設置configTIMER_QUEUE_LENGTH

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xTimerPendFunctionCall 1且configUSE_TIMERS也要置為1

(2)定時器守護任務使用到一個命令隊列,只要向隊列發送信號就可以執行相應代碼,所以可以實現“中斷推遲處理”功能;只用到定時器守護任務這一個任務,節省資源,但建議回調函數執行時間短一些,否則影響其他定時器回調函數的執行周期

18、INCLUDE_xTaskAbortDelay

原型:BaseType_t xTaskAbortDelay( TaskHandle_t xTask )

描述:終止任務的阻塞狀態並且使之進入就緒狀態

(1)將要被移除阻塞狀態的任務句柄

(2)返回:

  pdPASS:任務從阻塞狀態進入就緒狀態

  pdFAIL:在調用此函數時任務並沒有處於阻塞狀態

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xTaskAbortDelay 1

19、INCLUDE_xTaskGetHandle

原型:TaskHandle_t xTaskGetHandle( const char *pcNameToQuery )

描述:通過任務名獲取任務句柄

(1)第一個參數:任務的名字(標准非空的c字符串)

(2)如果存在與pcNameToQuery 指定的一樣的任務名字則返回任務句柄,否則返回NULL

注意事項:

(1)使用此函數需要在FreeRTOSConfig.h配置文件中配置如下宏定義為1,#define INCLUDE_xTaskGetHandle 1

(2)如果存在多個任務名字相同此函數功能將會無效

(3)此函數花的時間相對較長,因此推薦使用一次后保存查找到的任務句柄以備之后重復使用此句柄

 參考鏈接:https://blog.csdn.net/zhzht19861011/article/details/50134883、http://blog.sina.com.cn/s/blog_98ee3a930102wfst.html、http://blog.sina.com.cn/s/articlelist_2565749395_12_1.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM