日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

freeRtos学习笔(1)内核剪裁

發布時間:2025/4/16 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 freeRtos学习笔(1)内核剪裁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

freeRtos學習筆記

freeRtos內核剪裁

#define configCPU_CLOCK_HZ

系統主頻

#define configTICK_RATE_HZ

時鐘節拍

#define configTOTAL_HEAP_SIZE

freeRtos使用的堆棧大小,注意cortex系列的內核一般都是雙堆棧指針的,MSP(Main Stack Pointer主堆棧指針)和PSP(Process Stack Pointer)。這種設計非常適合RTOS的設計。MSP顧名思義是給系統棧使用的。PSP是給進程棧使用的。在RTOS運行中,整個??臻g是由PSP管理的,而切換到ISR中則使用MSP。.s文件中的heap只管分配給MSP,而這里的則是分配給PSP。

#define configMINIMAL_STACK_SIZE

空閑任務堆棧大小,單位是字

#define configSUPPORT_DYNAMIC_ALLOCATION

是否使用動態內存分配API,一般使用動態分配,從configTOTAL_HEAP_SIZE中獲取未使用的內存塊進行分配。

#define configSUPPORT_STATIC_ALLOCATION

是否使用靜態內存分配API,一般不使用靜態分配,麻煩

#define configAPPLICATION_ALLOCATED_HEAP

使用動態內存分配時,freeRtos有5種內存分配方式,一般使用heap_4.c文件,該文件開始部分直接定義了一個configTOTAL_HEAP_SIZE大小的數組,用于動態內存分配使用。默認為1,如果為0,則需要用戶自己實現uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]數組,比如使用stm32F4系列單片機,通常使用CCM用作freeRtos的任務堆棧,就可以將此處設置為0,自己定義uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]并通過編譯器的__attribute__((at(n)))指令將數組存放在固定的地址,注意keil的AC6使用__attribute__((section(".ARM._at"#n)))

#define configMAX_PRIORITIES

任務最大優先級數 注意frertos任務優先級越大,優先級越高,空閑任務默認優先級為0.
用戶實際可以使用的優先級范圍是 1 到 configMAX_PRIORITIES – 1

#define configUSE_PREEMPTION

使用搶占式任務調度

#define configUSE_TIME_SLICING

是能時間片

#define configIDLE_SHOULD_YIELD

用戶任務是否可以使用空閑任務優先級,一般不使用

#define configMAX_TASK_NAME_LEN

用戶任務名字最大長度

#define configUSE_16_BIT_TICKS

是否是16位的單片機

#define configUSE_TIMERS

是否使用軟件定時器

#define configTIMER_TASK_PRIORITY

軟件定時器任務優先級

#define configTIMER_QUEUE_LENGTH

軟件定時器隊列長度,軟件定時器可以看作是一個系統任務,軟件定時器的一些API操作可以看作是對該任務發送消息。

#define configTIMER_TASK_STACK_DEPTH

軟件定時器任務堆棧大小

#define configUSE_MUTEXES

是否使用互斥信號量,互斥信號量可以避免優先級反轉,常用于臨界資源的互斥訪問

#define configUSE_RECURSIVE_MUTEXES

是否使用遞歸互斥信號量

#define configUSE_COUNTING_SEMAPHORES

計數信號量,可以當作二值信號量來用,常用于任務間的同步

#define configUSE_QUEUE_SETS

是否使用消息隊列

#define configUSE_TASK_NOTIFICATIONS

是否啟用任務通知功能,可以高效率進行任務間通訊

#define configUSE_TRACE_FACILITY

是否開啟跟蹤調試功能,會激活一些附加的結構體成員和函數,開啟后方便內核調試

#define configUSE_TICKLESS_IDLE

是否開啟低功耗模式

#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP

如果開啟了低功耗模式,除空閑任務外,其他任務在接下來configEXPECTED_IDLE_TIME_BEFORE_SLEEP 個tick時間中均堵塞或者掛起),則會進入低功耗模式

#define configUSE_APPLICATION_TASK_TAG

給任務分配標簽,一般不使用

#define configUSE_NEWLIB_REENTRANT

每個任務創建的時候將分配 Newlib 的重入結構體

#define configUSE_CO_ROUTINES

使用合作式調度,一般不使用

#define configCHECK_FOR_STACK_OVERFLOW

堆棧溢出檢查

  • 0不檢查

  • 1檢查 在任務切換時檢測任務棧指針是否過界了,如果過界了,在任務切換的時候會觸發棧溢出鉤子函
    數。
    void vApplicationStackOverflowHook( TaskHandle_t xTask,
    signed char *pcTaskName );
    用戶可以在鉤子函數里面做一些處理。這種方法不能保證所有的棧溢出都能檢測到。比如任務在執行
    的過程中出現過棧溢出。任務切換前棧指針又恢復到了正常水平,這種情況在任務切換的時候是檢測
    不到的。又比如任務棧溢出后, 把這部分棧區的數據修改了, 這部分棧區的數據不重要或者暫時沒有
    用到還好, 但如果是重要數據被修改將直接導致系統進入硬件異常, 這種情況下,棧溢出檢測功能也
    是檢測不到的。

  • 2檢查 任務創建的時候將任務棧所有數據初始化為 0xa5,任務切換時進行任務棧檢測的時候會檢測末
    尾的 16 個字節是否都是 0xa5,通過這種方式來檢測任務棧是否溢出了。相比方法一, 這種方法的速
    度稍慢些, 但是這樣就有效地避免了方法一里面的部分情況。 不過依然不能保證所有的棧溢出都能檢
    測到,比如任務棧末尾的 16 個字節沒有用到, 即沒有被修改,但是任務棧已經溢出了, 這種情況是
    檢測不到的。 另外任務棧溢出后, 任務棧末尾的 16 個字節沒有修改,但是溢出部分的棧區數據被修
    改了, 這部分棧區的數據不重要或者暫時沒有用到還好, 但如果是重要數據被修改將直接導致系統進
    入硬件異常, 這種情況下,棧溢出檢測功能也是檢測不到的。

#define configQUEUE_REGISTRY_SIZE

設置可以注冊的信號量和消息隊列個數。內核調試時使用,如果不進行內核調試,沒有作用。

#define configASSERT( x )

斷言

#define configUSE_IDLE_HOOK

空閑任務回調函數使能,發生空閑任務時,是否調用vApplicationIdleHook(void)函數,注意該函數需要用戶自己編寫

#define configUSE_TICK_HOOK

時間片鉤子函數使能,發生時間片中斷時,是否調用vApplicationTickHook(void)函數,注意該函數需要用戶自己編寫

#define 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()失敗鉤子函數不會被調用,即便已經定義了這個函數。

#define configUSE_DAEMON_TASK_STARTUP_HOOK

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

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY

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

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

此宏定義比較重要,定義了受FreeRTOS管理的最高優先級中斷。簡單的說就是允許用戶在這個中斷服務程序里面調用FreeRTOS的API的最高優先級。

比如說設置NVIC的優先級分組為4的情況下。配置configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY為0x01表示用戶可以在搶占式優先級為1到15的中斷里面調用FreeRTOS的API函數,搶占式優先級為0的中斷里面是不允許調用的,也就是說優先級為0的中斷服務函數和裸機上是一樣的。

#define configKERNEL_INTERRUPT_PRIORITY

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

宏定義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 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,那么被關閉的中斷會被打開。

本文參考 freertos官方文檔 https://freertos.org/a00110.html

博客 https://www.cnblogs.com/yeshenmeng/p/9805080.html

總結

以上是生活随笔為你收集整理的freeRtos学习笔(1)内核剪裁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。