FreeRTOS學習05】深度解剖FreeRTOSConfig.h實現對系統的自定義剪裁

      網友投稿 1034 2025-03-31

      ROM/RAM太小,因此要對系統進行剪裁;


      相關文章

      【FreeRTOS實戰匯總】小白博主的RTOS學習實戰快速進階之路(持續更新)

      文章目錄

      相關文章

      1 系統的剪裁

      2 FreeRTOSConfig.h

      3 應用相關配置

      configUSE_PREEMPTION

      configMAX_PRIORITIES

      configMINIMAL_STACK_SIZE

      configUSE_16_BIT_TICKS

      configUSE_CO_ROUTINES

      configMAX_CO_ROUTINE_PRIORITIES

      4 內存管理配置

      configSUPPORT_STATIC_ALLOCATION

      configSUPPORT_DYNAMIC_ALLOCATION

      configTOTAL_HEAP_SIZE

      configAPPLICATION_ALLOCATED_HEAP

      5 hook 鉤子函數

      configUSE_TICK_HOOK

      configUSE_IDLE_HOOK

      configUSE_MALLOC_FAILED_HOOK

      configUSE_DAEMON_TASK_STARTUP_HOOK

      6 功能選配

      7 總結

      1 系統的剪裁

      嵌入式系統通常都支持用戶自定義進行剪裁,比較常見的Linux系統通過Kbuild在構建系統的時候進行剪裁,同樣,國產的RT-Thread也支持Kbuild,可以很方便地通過menuconfig進行內核的剪裁,具體如下所示;

      另外也支持通過對config文件進行配置,Linux的內核構建過程可以參考文章《探索Linux內核:Kconfig / kbuild的秘密》;

      FreeRTOS支持使用FreeRTOSConfig.h配置文件進行定制,下面有幾點需要注意的地方;

      每個FreeRTOS應用程序的預處理器必須包含頭文件FreeRTOSConfig.h;

      FreeRTOSConfig.h是根據用戶需求而進行定制產生的文件,它應位于應用程序的目錄中,而不是RTOS內核代碼的目錄;

      FreeRTOS源碼中的每一個demo程序都有屬于自己的FreeRTOSConfig.h文件,如果一下配置選項被省略,那這些設置為默認值;

      用戶通過修改FreeRTOSConfig.h頭文件中的宏定義,從而刪減系統的模塊,設置任務棧空間大小,設置系統分配的堆大小等等,下面配合源碼進行詳細解析。

      2 FreeRTOSConfig.h

      這里先找到文件FreeRTOSConfig.h,這個FreeRTOS工程是通過CubeIDE進行快速整合的,具體可以參考《【FreeRTOS學習01】CubeIDE快速整合FreeRTOS創建第一個任務》;工程結構如下圖所示;

      本文的FreeRTOSConfig.h頭文件是根據集成在CubeIDE中的CubeMX插件自動生成的,源碼如下所示;

      #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /* Ensure definitions are only used by the compiler, and not by the assembler. */ #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) #include extern uint32_t SystemCoreClock; void xPortSysTickHandler(void); #endif #define configUSE_PREEMPTION 1 #define configSUPPORT_STATIC_ALLOCATION 0 #define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configUSE_IDLE_HOOK 0 // #define configUSE_TICK_HOOK 0 // #define configCPU_CLOCK_HZ ( SystemCoreClock ) //輸入以Hz為單位的CPU頻率:例如 72Mb->72000000 #define configTICK_RATE_HZ ((TickType_t)1000) //輸入以Hz為單位的滴答中斷頻率 #define configMAX_PRIORITIES ( 7 ) //應用程序任務可用的優先級數 #define configMINIMAL_STACK_SIZE ((uint16_t)128) #define configTOTAL_HEAP_SIZE ((size_t)15360) #define configMAX_TASK_NAME_LEN ( 16 ) //創建任務時,任務的名稱允許的最大長度 #define configUSE_16_BIT_TICKS 0 #define configUSE_MUTEXES 1 //使用互斥功能 #define configQUEUE_REGISTRY_SIZE 8 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 0 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 0 #define INCLUDE_vTaskDelay 1 #define INCLUDE_xTaskGetSchedulerState 1 /* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 /* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 /* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Normal assert() semantics without relying on the provision of an assert.h header file. */ /* USER CODE BEGIN 1 */ #define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} /* USER CODE END 1 */ /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler /* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick, to prevent overwriting SysTick_Handler defined within STM32Cube HAL */ /* #define xPortSysTickHandler SysTick_Handler */ #endif /* 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

      下面將對某些額外需要注意的進行另外注釋;

      3 應用相關配置

      configUSE_PREEMPTION

      這個宏定義來選擇當前系統任務之間的調度算法;

      設置為1,則表示選擇RTOS為搶占式調度;

      設置為0,則表示調度算法為時間片調度;

      通常這里需要設置為搶占式調度,一般設置為1

      configMAX_PRIORITIES

      應用程序任務可用 的優先級數,任意數量的任務可以共享相同的優先級。協同例程(Co-routines)分別進行優先級排序,可以參考configMAX_CO_ROUTINE_PRIORITIES;

      每個可用的優先級都會消耗RTOS內核中的RAM,因此該值不應設置為高于應用程序實際需要的值;

      configMINIMAL_STACK_SIZE

      空閑任務使用的堆棧大小;通常,不應將此值從演示應用程序隨附的FreeRTOSConfig.h文件中為您所使用的端口設置的值中減少。

      xTaskCreate()和 xTaskCreateStatic()函數的堆棧大小參數一樣,

      堆棧大小以字而不是字節

      ,如果放在堆棧上的每個單元都是32位,堆棧大小100則表示 400字節,4bytes等于32bit;

      configUSE_16_BIT_TICKS

      設置為1:TickType_t被定義(類型定義)為無符號的16位類型;

      設置為0:TickType_t被定義(類型定義)為無符號的32位類型;

      當系統是8位或16位的結構時,使用這個設置,可以提高能;

      configUSE_CO_ROUTINES

      設置為1可在構建中包括協同例程功能;

      設置為0可從構建中省略協同例程功能;

      要包含協例程,必須在項目中包含croutine.c

      configMAX_CO_ROUTINE_PRIORITIES

      應用程序協同例程可用的優先級數。任意數量的協同例程可以共享相同的優先級。任務分別進行優先級排序-請參閱configMAX_PRIORITIES

      4 內存管理配置

      configSUPPORT_STATIC_ALLOCATION

      設置為1:則可以使用程序中預先分配好的RAM創建RTOS對象;

      設置為0:只能使用從FreeRTOS堆分配的RAM創建RTOS對象;

      如果未定義configSUPPORT_STATIC_ALLOCATION,則默認為0

      如果將configSUPPORT_STATIC_ALLOCATION設置為1

      ,則應用程序編寫器還必須提供兩個回調函數:- -

      vApplicationGetIdleTaskMemory():用于提供RTOS空閑任務的內存;

      vApplicationGetTimerTaskMemory():用于提供RTOS守護程序/計時器服務任務(如果configUSE_TIMERS設置為1)的內存: 。

      這個在移植的時候可能也會遇到,具體如下所示;

      /* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an implementation of vApplicationGetIdleTaskMemory() to provide the memory that is used by the Idle task. */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { /* If the buffers to be provided to the Idle task are declared inside this function then they must be declared static – otherwise they will be allocated on the stack and so not exists after this function exits. */ static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; /* Pass out a pointer to the StaticTask_t structure in which the Idle task’s state will be stored. */ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; /* Pass out the array that will be used as the Idle task’s stack. */ *ppxIdleTaskStackBuffer = uxIdleTaskStack; /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. Note that, as the array is necessarily of type StackType_t, configMINIMAL_STACK_SIZE is specified in words, not bytes. */ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } /*———————————————————–*/ /* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the application must provide an implementation of vApplicationGetTimerTaskMemory() to provide the memory that is used by the Timer service task. */ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) { /* If the buffers to be provided to the Timer task are declared inside this function then they must be declared static – otherwise they will be allocated on the stack and so not exists after this function exits. */ static StaticTask_t xTimerTaskTCB; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; /* Pass out a pointer to the StaticTask_t structure in which the Timer task’s state will be stored. */ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; /* Pass out the array that will be used as the Timer task’s stack. */ *ppxTimerTaskStackBuffer = uxTimerTaskStack; /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. Note that, as the array is necessarily of type StackType_t, configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; }

      1

      2

      3

      【FreeRTOS學習05】深度解剖FreeRTOSConfig.h實現對系統的自定義剪裁

      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

      configSUPPORT_DYNAMIC_ALLOCATION

      設置為1:則可以使用從FreeRTOS堆自動分配的RAM創建RTOS對象;

      設置為0:則只能使用應用程序編寫器提供的RAM創建RTOS對象;

      如果未定義configSUPPORT_DYNAMIC_ALLOCATION,則默認為1;

      configTOTAL_HEAP_SIZE

      設置FreeRTOS中堆可用的RAM總量;

      僅當configSUPPORT_DYNAMIC_ALLOCATION設置為1;且使用FreeRTOS源代碼下載中提供的示例內存分配方案(heap_1.c,heap_2.c,heap_3.c,heap_4.c,heap_5.c)時,才會配置這個值;

      configAPPLICATION_ALLOCATED_HEAP

      設置為0:FreeRTOS堆由FreeRTOS聲明,并由鏈接器放置在內存中;

      設置為1:可以使堆改為由用戶程序進行設置,允許將堆放置在內存中任意位置;

      如果使用heap_1.c,heap_2.c或heap_4.c,并且configAPPLICATION_ALLOCATED_HEAP設置為1,那么應用程序編寫器必須提供一個uint8_t數組,其名稱和維數如下所示。

      uint8_t ucHeap [configTOTAL_HEAP_SIZE];

      該數組將被作為FreeRTOS的堆來使用。如何將數組放置在特定的內存位置取決于所使用的編譯器–請參閱編譯器的文檔。

      5 hook 鉤子函數

      鉤子函數的本質就是回調函數,有下面四個函數;

      configUSE_TICK_HOOK;

      configUSE_IDLE_HOOK;

      configUSE_MALLOC_FAILED_HOOK;

      configUSE_DAEMON_TASK_STARTUP_HOOK;

      具體參考hook函數;

      configUSE_TICK_HOOK

      程序必須為hook函數提供以下原型:

      void vApplicationTickHook( void );

      configUSE_IDLE_HOOK

      configUSE_IDLE_HOOK設置為1,才會調用IDLE_HOOK,設置此選項后,應用程序必須為hook函數提供以下原型:

      void vApplicationIdleHook(void);

      configUSE_MALLOC_FAILED_HOOK

      程序必須為hook函數提供以下原型:

      void vApplicationMallocFailedHook( void );

      configUSE_DAEMON_TASK_STARTUP_HOOK

      RTOS守護程序任務與計時器服務任務相同。有時將其稱為守護程序任務,因為該任務現在不僅用于維護計時器,還用于更多任務。

      將configUSE_DAEMON_TASK_STARTUP_HOOK設置為1,則在守護程序任務首次開始執行時,將立即調用守護程序任務啟動鉤子函數。應用程序的初始化代碼如果需要放在該鉤子函數中,則該功能將很有用,這將允許初始化代碼利用RTOS功能。

      應用程序編寫器必須使用以下名稱提供原型的“守護程序任務”啟動掛鉤函數的實現。

      void vApplicationDaemonTaskStartupHook( void );

      6 功能選配

      如果以下函數沒有被使用到,已經設置為0,使其不被包含到應用程序中,從而減少程序的應用空間;

      #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_eTaskGetState 0 #define INCLUDE_xEventGroupSetBitFromISR 1 #define INCLUDE_xTimerPendFunctionCall 0 #define INCLUDE_xTaskAbortDelay 0 #define INCLUDE_xTaskGetHandle 0 #define INCLUDE_xTaskResumeFromISR 1

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      7 總結

      如果是學習FreRTOS的初期,只需要了解幾個比價關鍵的配置即可,隨著后期對該系統功能了解的深入,在系統的剪裁,RAM和ROM的優化上就可以進一步的了解,另外也可以參考https://www.freertos.org/a00110.html,

      嵌入式

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:word文檔怎么顯示字數
      下一篇:OKR什么意思?是時候建立一本“OKR字典”啦(OKR的意思)
      相關文章
      亚洲精品自产拍在线观看| 亚洲AV伊人久久青青草原| 亚洲老妈激情一区二区三区| 精品国产亚洲男女在线线电影| 爱情岛论坛亚洲品质自拍视频网站 | 日韩亚洲翔田千里在线| 亚洲AV无码一区二区乱子仑| 亚洲欧美中文日韩视频| 亚洲欧美中文日韩视频| 亚洲爆乳成av人在线视菜奈实| 亚洲国产成人综合精品| 国产精品亚洲专区无码牛牛| 国产精品亚洲а∨无码播放不卡| MM1313亚洲国产精品| 亚洲第一网站男人都懂| 亚洲伊人久久综合中文成人网| 亚洲色偷偷综合亚洲AV伊人| 久久亚洲中文字幕精品一区四| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 国产精品久久久久久亚洲小说| 蜜芽亚洲av无码一区二区三区| 麻豆亚洲AV成人无码久久精品 | 91情国产l精品国产亚洲区 | 亚洲人成网站看在线播放| 成人区精品一区二区不卡亚洲| 亚洲精品国产第一综合99久久 | 亚洲精品无码永久在线观看你懂的 | 亚洲视频在线观看免费| 久久亚洲国产精品成人AV秋霞| 亚洲国产综合人成综合网站00| 亚洲av无码片区一区二区三区| 2017亚洲男人天堂一| 亚洲成a∧人片在线观看无码| 国产天堂亚洲精品| 精品国产亚洲男女在线线电影 | 亚洲AV无码一区二区三区在线观看| 亚洲国产成人久久笫一页| 亚洲午夜久久久影院| 无码欧精品亚洲日韩一区| 亚洲美女aⅴ久久久91| 亚洲人成网男女大片在线播放|