性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

小麥大叔
認(rèn)證:普通會員
所在專題目錄 查看專題
基于CubeIDE快速整合FreeRTOS創(chuàng)建第一個任務(wù)
【FreeRTOS學(xué)習(xí)02】源碼結(jié)構(gòu)/數(shù)據(jù)類型/命名規(guī)則總結(jié)
【FreeRTOS學(xué)習(xí)03】Task Management 任務(wù)管理基本概念介紹
【FreeRTOS學(xué)習(xí)04】Queue Management 消息隊(duì)列使用詳解
【FreeRTOS學(xué)習(xí)05】深度解剖FreeRTOSConfig.h實(shí)現(xiàn)對系統(tǒng)的自定義剪裁
【FreeRTOS學(xué)習(xí)06】深度解剖中斷與任務(wù)之間同步的具體使用場景
作者動態(tài) 更多
一款輕量級的開源GUI項(xiàng)目——SimpleGUI,可以完美適配單色屏
02-22 09:47
看到這100多個軟硬件開源項(xiàng)目,真是爽爆了
2024-11-30 14:12
推薦一個高效,可靠,安全的串口通訊開源方案
2024-11-27 11:17
推薦一款開源hack硬件平臺工具
2024-11-26 13:58
新手學(xué)STM32的話,先學(xué)標(biāo)準(zhǔn)庫還是HAL庫?
2024-10-18 15:09

【FreeRTOS學(xué)習(xí)05】深度解剖FreeRTOSConfig.h實(shí)現(xiàn)對系統(tǒng)的自定義剪裁

1 系統(tǒng)的剪裁

嵌入式系統(tǒng)通常都支持用戶自定義進(jìn)行剪裁,比較常見的Linux系統(tǒng)通過Kbuild在構(gòu)建系統(tǒng)的時(shí)候進(jìn)行剪裁,同樣,國產(chǎn)的RT-Thread也支持Kbuild,可以很方便地通過menuconfig進(jìn)行內(nèi)核的剪裁,具體如下所示;

另外也支持通過對config文件進(jìn)行配置,Linux的內(nèi)核構(gòu)建過程可以參考文章《探索Linux內(nèi)核:Kconfig / kbuild的秘密》;

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

  • 每個FreeRTOS應(yīng)用程序的預(yù)處理器必須包含頭文件FreeRTOSConfig.h;
  • FreeRTOSConfig.h是根據(jù)用戶需求而進(jìn)行定制產(chǎn)生的文件,它應(yīng)位于應(yīng)用程序的目錄中,而不是RTOS內(nèi)核代碼的目錄;
  • FreeRTOS源碼中的每一個demo程序都有屬于自己的FreeRTOSConfig.h文件,如果一下配置選項(xiàng)被省略,那這些設(shè)置為默認(rèn)值;
  • 用戶通過修改FreeRTOSConfig.h頭文件中的宏定義,從而刪減系統(tǒng)的模塊,設(shè)置任務(wù)??臻g大小,設(shè)置系統(tǒng)分配的堆大小等等,下面配合源碼進(jìn)行詳細(xì)解析。

2 FreeRTOSConfig.h

這里先找到文件FreeRTOSConfig.h,這個FreeRTOS工程是通過CubeIDE進(jìn)行快速整合的,具體可以參考《【FreeRTOS學(xué)習(xí)01】CubeIDE快速整合FreeRTOS創(chuàng)建第一個任務(wù)》;工程結(jié)構(gòu)如下圖所示;

本文的FreeRTOSConfig.h頭文件是根據(jù)集成在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 <stdint.h>
  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 )					//應(yīng)用程序任務(wù)可用的優(yōu)先級數(shù)
#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
#define configTOTAL_HEAP_SIZE                    ((size_t)15360)
#define configMAX_TASK_NAME_LEN                  ( 16 )					//創(chuàng)建任務(wù)時(shí),任務(wù)的名稱允許的最大長度
#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 */

下面將對某些額外需要注意的進(jìn)行另外注釋;

3 應(yīng)用相關(guān)配置

configUSE_PREEMPTION

這個宏定義來選擇當(dāng)前系統(tǒng)任務(wù)之間的調(diào)度算法;

  • 設(shè)置為1,則表示選擇RTOS為搶占式調(diào)度;
  • 設(shè)置為0,則表示調(diào)度算法為時(shí)間片調(diào)度;

通常這里需要設(shè)置為搶占式調(diào)度,一般設(shè)置為1

configMAX_PRIORITIES

應(yīng)用程序任務(wù)可用 的優(yōu)先級數(shù),任意數(shù)量的任務(wù)可以共享相同的優(yōu)先級。協(xié)同例程(Co-routines)分別進(jìn)行優(yōu)先級排序,可以參考configMAX_CO_ROUTINE_PRIORITIES;每個可用的優(yōu)先級都會消耗RTOS內(nèi)核中的RAM,因此該值不應(yīng)設(shè)置為高于應(yīng)用程序?qū)嶋H需要的值;

configMINIMAL_STACK_SIZE

空閑任務(wù)使用的堆棧大??;通常,不應(yīng)將此值從演示應(yīng)用程序隨附的FreeRTOSConfig.h文件中為您所使用的端口設(shè)置的值中減少。xTaskCreate()和 xTaskCreateStatic()函數(shù)的堆棧大小參數(shù)一樣,堆棧大小以字而不是字節(jié),如果放在堆棧上的每個單元都是32位,堆棧大小100則表示??400字節(jié),4bytes等于32bit;

configUSE_16_BIT_TICKS

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

當(dāng)系統(tǒng)是8位或16位的結(jié)構(gòu)時(shí),使用這個設(shè)置,可以提高能;

configUSE_CO_ROUTINES

  • 設(shè)置為1可在構(gòu)建中包括協(xié)同例程功能;
  • 設(shè)置為0可從構(gòu)建中省略協(xié)同例程功能;

要包含協(xié)例程,必須在項(xiàng)目中包含croutine.c

configMAX_CO_ROUTINE_PRIORITIES

應(yīng)用程序協(xié)同例程可用的優(yōu)先級數(shù)。任意數(shù)量的協(xié)同例程可以共享相同的優(yōu)先級。任務(wù)分別進(jìn)行優(yōu)先級排序-請參閱configMAX_PRIORITIES

4 內(nèi)存管理配置

configSUPPORT_STATIC_ALLOCATION

  • 設(shè)置為1:則可以使用程序中預(yù)先分配好的RAM創(chuàng)建RTOS對象;
  • 設(shè)置為0:只能使用從FreeRTOS堆分配的RAM創(chuàng)建RTOS對象;

如果未定義configSUPPORT_STATIC_ALLOCATION,則默認(rèn)為0如果將configSUPPORT_STATIC_ALLOCATION設(shè)置為1,則應(yīng)用程序編寫器還必須提供兩個回調(diào)函數(shù):- -

  • vApplicationGetIdleTaskMemory():用于提供RTOS空閑任務(wù)的內(nèi)存;
  • vApplicationGetTimerTaskMemory():用于提供RTOS守護(hù)程序/計(jì)時(shí)器服務(wù)任務(wù)(如果configUSE_TIMERS設(shè)置為1)的內(nèi)存: 。

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

/* 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;
}

configSUPPORT_DYNAMIC_ALLOCATION

  • 設(shè)置為1:則可以使用從FreeRTOS堆自動分配的RAM創(chuàng)建RTOS對象;
  • 設(shè)置為0:則只能使用應(yīng)用程序編寫器提供的RAM創(chuàng)建RTOS對象;

如果未定義configSUPPORT_DYNAMIC_ALLOCATION,則默認(rèn)為1;

configTOTAL_HEAP_SIZE

設(shè)置FreeRTOS中堆可用的RAM總量;僅當(dāng)configSUPPORT_DYNAMIC_ALLOCATION設(shè)置為1;且使用FreeRTOS源代碼下載中提供的示例內(nèi)存分配方案(heap_1.c,heap_2.c,heap_3.c,heap_4.cheap_5.c)時(shí),才會配置這個值;

configAPPLICATION_ALLOCATED_HEAP

  • 設(shè)置為0FreeRTOS堆由FreeRTOS聲明,并由鏈接器放置在內(nèi)存中;
  • 設(shè)置為1:可以使堆改為由用戶程序進(jìn)行設(shè)置,允許將堆放置在內(nèi)存中任意位置;

如果使用heap_1.cheap_2.cheap_4.c,并且configAPPLICATION_ALLOCATED_HEAP設(shè)置為1,那么應(yīng)用程序編寫器必須提供一個uint8_t數(shù)組,其名稱和維數(shù)如下所示。uint8_t ucHeap [configTOTAL_HEAP_SIZE];該數(shù)組將被作為FreeRTOS的堆來使用。如何將數(shù)組放置在特定的內(nèi)存位置取決于所使用的編譯器–請參閱編譯器的文檔。

5 hook 鉤子函數(shù)

鉤子函數(shù)的本質(zhì)就是回調(diào)函數(shù),有下面四個函數(shù);

  • configUSE_TICK_HOOK;
  • configUSE_IDLE_HOOK;
  • configUSE_MALLOC_FAILED_HOOK;
  • configUSE_DAEMON_TASK_STARTUP_HOOK;

具體參考hook函數(shù)

configUSE_TICK_HOOK

程序必須為hook函數(shù)提供以下原型:void vApplicationTickHook( void );

configUSE_IDLE_HOOK

configUSE_IDLE_HOOK設(shè)置為1,才會調(diào)用IDLE_HOOK,設(shè)置此選項(xiàng)后,應(yīng)用程序必須為hook函數(shù)提供以下原型:void vApplicationIdleHook(void);

configUSE_MALLOC_FAILED_HOOK

程序必須為hook函數(shù)提供以下原型:void vApplicationMallocFailedHook( void );

configUSE_DAEMON_TASK_STARTUP_HOOK

RTOS守護(hù)程序任務(wù)與計(jì)時(shí)器服務(wù)任務(wù)相同。有時(shí)將其稱為守護(hù)程序任務(wù),因?yàn)樵撊蝿?wù)現(xiàn)在不僅用于維護(hù)計(jì)時(shí)器,還用于更多任務(wù)。將configUSE_DAEMON_TASK_STARTUP_HOOK設(shè)置為1,則在守護(hù)程序任務(wù)首次開始執(zhí)行時(shí),將立即調(diào)用守護(hù)程序任務(wù)啟動鉤子函數(shù)。應(yīng)用程序的初始化代碼如果需要放在該鉤子函數(shù)中,則該功能將很有用,這將允許初始化代碼利用RTOS功能。

應(yīng)用程序編寫器必須使用以下名稱提供原型的“守護(hù)程序任務(wù)”啟動掛鉤函數(shù)的實(shí)現(xiàn)。void vApplicationDaemonTaskStartupHook( void );

6 功能選配

如果以下函數(shù)沒有被使用到,已經(jīng)設(shè)置為0,使其不被包含到應(yīng)用程序中,從而減少程序的應(yīng)用空間;

#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
7 總結(jié)

如果是學(xué)習(xí)FreRTOS的初期,只需要了解幾個比價(jià)關(guān)鍵的配置即可,隨著后期對該系統(tǒng)功能了解的深入,在系統(tǒng)的剪裁,RAM和ROM的優(yōu)化上就可以進(jìn)一步的了解,另外也可以參考https://www.freertos.org/a00110.html

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 2
關(guān)注 144
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧