FreeRTOS之系统配置

1.FreeRTOS的系统配置文件为FreeRTOSConfig.h,在此配置文件中可以完成FreeRTOS的裁剪和配置。
在官方的demo中,每个工程都有一个该文件。

2.先说一下”INCLUDE_”开始的宏
使用“INCLUDE_”开头的宏用来表示使能或除能FreeRTOS中的相应API函数,作用就是用来配置FreeRTOS中的可选API函数。
(1)INCLUDE_xSemaphoreGetMutexHolder
如果要使用函数xSemaphoreGetMutexHolder(),则宏INCLUDE_xSemaphoreGetMutexHolder必须定义为1。
(2)INCLUDE_xTaskAbortDelay
如果要使用函数xTaskAbortDelay(),则宏INCLUDE_xTaskAbortDelay定义为1。
(3)INCLUDE_vTaskDelay
如果要使用函数vTaskDelay(),则宏INCLUDE_vTaskDelay定义为1。
(4)INCLUDE_vTaskDelayUntil
如果要使用函数vTaskDelayUntil(),则宏INCLUDE_vTaskDelayUntil定义为1。
(5)INCLUDE_vTaskDelete
如果要使用函数vTaskDelete(),则宏INCLUDE_vTaskDelete定义为1。
(6)INCLUDE_xTaskGetCurrentTaskHandle
如果要使用函数xTaskGetCurrentTaskHandle(),则宏INCLUDE_xTaskGetCurrentTaskHandle定义为1。
(7)INCLUDE_xTaskGetHandle
如果要使用函数xTaskGetHandle(),则宏INCLUDE_xTaskGetHandle定义为1。
(8)INCLUDE_xTaskGetIdleTaskHandle
如果要使用函数xTaskGetIdleTaskHandle(),则INCLUDE_xTaskGetIdleTaskHandle定义为1。
(9)INCLUDE_xTaskGetSchedulerState
如果要使用函数xTaskGetSchedulerState(),则宏INCLUDE_xTaskGetSchedulerState定义为1。
(10)INCLUDE_uxTaskGetStackHighWaterMark
如果要使用函数uxTaskGetStackHighWaterMark(),则宏INCLUDE_uxTaskGetStackHighWaterMark定义为1。
(11)INCLUDE_uxTaskPriorityGet
如果要使用函数uxTaskPriorityGet(),则宏INCLUDE_uxTaskPriorityGet定义为1。
(12)INCLUDE_vTaskPrioritySet
如果要使用函数vTaskPrioritySet(),则宏INCLUDE_vTaskPrioritySet定义为1。
(13)INCLUDE_xTaskResumeFromISR
如果要使用函数xTaskResumeFromISR(),则需要将宏INCLUDE_xTaskResumeFromISR和INCLUDE_vTaskSuspend都定义为1。
(14)INCLUDE_eTaskGetState
如果要使用函数eTaskGetState(),则宏INCLUDE_eTaskGetState定义为1。
(15)INCLUDE_vTaskSuspend
如果要使用函数vTaskSuspend()、vTaskResume()、prvTaskIsTaskSuspended()、xTaskResumeFromISR(),则宏INCLUDE_vTaskSuspend定义为1。
如果要使用函数xTaskResumeFromISR(),则宏INCLUDE_xTaskResumeFromISR和INCLUDE_vTaskSuspend都必须定义为1。
(16)INCLUDE_xTimerPendFunctionCall
如果要使用函数xTimerPendFunctionCall()和xTimerPendFunctionCallFromISR(),则宏INCLUDE_xTimerPendFunctionCall和configUSE_TIMERS都必须定义为1。

3.再来说一下config开始的宏
(1)configAPPLICATION_ALLOCATED_HEAP
该宏与系统的堆内存的分配相关,在heap_1.c、heap_2.c、heap_3.c、heap_4.c、heap_5中都有定义。当该宏为1时,需要用户自行堆内存ucHeap,否则就由编译器来分配。

#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
    static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif

(2)configASSERT
断言类似C语言中的assert()函数。
该宏需要在FreeRTOSConfig.h中定义。

#define configASSERT((x))           if ((x) == 0) vAssertCalled(__FILE_, __LINE__)

注意:vAssertCalled()函数需要自行定义。

#define vAssertCalled(char, int)        printf("Error: %s, %d\r\n", char, int)              

断言会导致开销增大,一般在调试阶段使用,调试完成后去掉。
(3)configCHECK_FOR_STACK_OVERFLOW
该宏设置堆栈溢出检测。
每一个任务都有一个任务栈,使用函数vTaskCreate()创建任务时,任务栈是自动从FreeRTOS的堆(ucHeap)中分配的;而xTaskCreateStatic()创建任务时,任务站时由用户分配的。
任务栈的检测方式有两种,当该宏为1时使用第1种方式,当该宏为2时,使用第2中方式,两种方式的不同不再描述。
(4)configCPU_CLOCK_HZ
设置CPU的频率
(5)configSUPPORT_DYNAMIC_ALLOCATION
定义为1–在创建FreeRTOS内核对象时,需要的RAM就会从FreeRTOS的堆中动态的获取;定义为0–所需的RAM就需要用户自行提供。默认为1。
(6)configENABLE_BACKWARD_COMPATIBILITY
FreeRTOS.h中有一些数据类型名字的宏定义 。

#if configENABLE_BACKWARD_COMPATIBILITY == 1
    #define eTaskStateGet eTaskGetState
    #define portTickType TickType_t
    #define xTaskHandle TaskHandle_t
    #define xQueueHandle QueueHandle_t
    #define xSemaphoreHandle SemaphoreHandle_t
    #define xQueueSetHandle QueueSetHandle_t
    #define xQueueSetMemberHandle QueueSetMemberHandle_t
    #define xTimeOutType TimeOut_t
    #define xMemoryRegion MemoryRegion_t
    #define xTaskParameters TaskParameters_t
    #define xTaskStatusType TaskStatus_t
    #define xTimerHandle TimerHandle_t
    #define xCoRoutineHandle CoRoutineHandle_t
    #define pdTASK_HOOK_CODE TaskHookFunction_t
    #define portTICK_RATE_MS portTICK_PERIOD_MS
    #define pcTaskGetTaskName pcTaskGetName
    #define pcTimerGetTimerName pcTimerGetName
    #define pcQueueGetQueueName pcQueueGetName
    #define vTaskGetTaskInfo vTaskGetInfo

    /* Backward compatibility within the scheduler code only - these definitions
    are not really required but are included for completeness. */
    #define tmrTIMER_CALLBACK TimerCallbackFunction_t
    #define pdTASK_CODE TaskFunction_t
    #define xListItem ListItem_t
    #define xList List_t
#endif

宏configENABLE_BACKWARD_COMPATIBILITY默认为1。
(7)configGENERATE_RUN_TIME_STATS
设置为1开启时间统计功能,则相应的API函数会被编译;为0则关闭时间统计功能。
(8)configIDLE_SHOULD_YIELD
此宏定义了与空闲任务(idle Task)出于同等优先级的其他用户任务的行为。为0,表示空闲任务不会为其他处于同等优先级的任务让出CPU使用权;为1,则空闲任务为处于同等优先级的用户让出CPU使用权。
一般建议关闭这个功能。
(9)configKERNEL_INTERRUPT_PRIORITY、configMAX_SYSCALL_INTERRUPT_PRIORITY、configMAX_API_CALL_INTERRUPT_PRIORITY
这3个宏和FreeRTOS的中断配置有关,后面会有专门的章节来讲解。
(10)configMAX_CO_ROUTINE_PRIORITIES
设置可以分配给协程的最大优先级,也就是协程的优先级数。
0是最低优先级,configMAX_CO_ROUTINE_PRIORITIES-1为最高的优先级。
(11)configMAX_PRIORITIES
设置任务的优先级数量,设置好以后任务就可以使用从0~configMAX_PRIORITIES-1的优先级。
0时最低优先级,configMAX_PRIORITIES-1是最高优先级。
(12)configMAX_TASK_NAME_LEN
设置任务名的最大长度
(13)configMINIMAL_STACK_SIZE
设置空闲任务的任务栈的最小值。
注意:这里以字为单位,不是字节。
(14)configNUM_THREAD_LOCAL_STORAGE_POINTERS
设置每个任务的本地存储指针数组大小。
任务控制块中有本地存储数组指针,用户应用程序可以在这些本地存储中存入一些数据。
(15)configQUEUE_REGISTRY_SIZE
设置可以注册的队列和信号量的最大数量。使用内核调试器查看信号量和队列的是否需要设置此宏,不使用内核调试器时此宏设置为0即可。
(16)configSUPPORT_STATIC_ALLOCATION
此宏定义为1时,在创建一些内核对象的时候需要用户指定RAM;为0时,则自动使用heap.c中的动态内存管理函数来申请RAM。
若定义为1,需要实现两个函数vApplicationGetIdleTaskMemory()和vApplicationGetTimerTaskMemory()。
(17)configTICK_RATE_HZ
设置FreeRTOS的系统时钟节拍频率,单位为Hz。
此频率是系统滴答定时器的中断频率。
(18)configTIMER_QUEUE_LENGTH
此宏与软件定时器相关,用来设置软件定时器的命令队列的长度。
(19)configTIMER_TASK_PRIORITY
设置软件定时器任务的任务优先级。
(20)configTIMER_TASK_STACK_DEPTH
设置定时器任务的任务栈的大小。
(21)configTOTAL_HEAP_SIZE
用来设置堆大小。
如果使用动态内存管理,则FreeRTOS在创建任务、信号量、队列等的时候就会使用heap_x.c(x为1~5)中的内存申请函数来申请内存。
(22)configUSE_16_BIT_TICKS
设置系统节拍计数器变量的数据类型,系统节拍计数器变量类型为TickType_t。
configUSE_16_BIT_TICKS为1时,TickType_t是16位的;configUSE_16_BIT_TICKS为0时,TickType_t是32位的。
(23)configUSE_APPLICATION_TASK_TAG
此宏设置为1时,函数configUSE_APPLICATION_TASK_TAGF()和xTaskCallApplicationTaskHook()就会被编译。
(24)configUSE_CO_ROUTINES
此宏为1时开启协程。
协程可以节省开销,但是功能有限,现在的CPU性能已经很强大了,建议关闭协程。
(25)configUSE_COUNTING_SEMAPHORES
设置为1时启用计数型信号量,相关的API函数就会被编译。
(26)configUSE_DAEMON_TASK_STARTUP_HOOK
当宏configUSE_TIMERS和configUSE_DAEMON_TASK_STARTUP_HOOK都为1时需要定义函数vApplicationDaemonTaskStartupHook()。
函数原型:void vApplicationDaemonTaskStartupHook(void)
(27)configUSE_IDLE_HOOK
为1时使用空闲任务钩子函数,用户需要实现空闲任务钩子函数,函数的原型为:void vApplicationIdleHook(void)
(28)configUSE_MALLOC_FAILED_HOOK
为1时使用内存分配函数失败钩子函数,用户需要实现内存分配失败钩子函数,函数原型为:void vApplicationMallocFailedHook(void)
(29)configUSE_MUTEXES
为1时使用互斥信号量,相关的API函数会被编译。
(30)configUSE_PORT_OPTIMISED_TASK_SELECTION
FreeRTOS有两种方法来选择下一个要运行的任务:一个是通用的方法,另外一个是特殊的方法,也就是硬件方法,使用MCU自带的硬件指令来实现。
为0,使用通用方法计算下一个要运行的任务;为1,使用硬件方法计算下一个要运行的任务。
(31)configUSE_PREEMPTION
为1时,使用抢占式调度器;为0时,使用协程。
如果使用抢占式调度器,则内核会在每个时钟节拍中断中进行任务切换;使用协程时会在如下的地方进行任务切换:任务调用了函数taskYIELD()、任务调用了可以使任务进入阻塞态的API函数、应用程序明确定义了在中断中执行上下文切换。
(32)configUSE_QUEUE_SETS
为1时,启用队列集功能。
(33)configUSE_RECURSIVE_MUTEXES
为1时使用递归互斥信号量,相关的API函数会被编译。
(34)configUSE_STATS_FORMATTING_FUNCTIONS
宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS都为1时,函数vTaskList()和vTaskGetRunTimeStats()会被编译。
(35)configUSE_TASK_NOTIFICATIONS
为1时使用任务通知功能,相关的API函数会被编译。开启了此功能的话,每个任务会多消耗8个字节。
(36)configUSE_TICK_HOOK
为1时使能时间片钩子函数,用户需要实现时间片钩子函数,函数原型如下:void vApplicationTickHook(void)
(37)configUSE_TICKLESS_IDLE
为1时使能低功耗tickless模式。
(38)configUSE_TIMERS
为1时使用软件定时器,相关的API函数会被编译。
当宏configUSE_TIMERS为1的话,宏configTIMER_TASK_PRIORITY、configTIMER_QUEUE_LENGTH和configTIMER_TASK_STACK_DEPTH必须定义。
(39)configUSE_TIME_SLICING
默认情况下,FreeRTOS使用抢占式调度器,这意味着调度器永远都在执行已经就绪了的最高优先级的任务,优先级相同的任务在时钟节拍中断中进行切换。当宏configUSE_TIME_SLICING为0时,不会在时钟节拍中断中执行相同优先级任务的任务切换。默认情况下宏configUSE_TIME_SLICING为1。
(40)configUSE_TRACE_FACILITY
为1时启用可视化跟踪调试,则会增加一些结构体成员和API函数。

4.条件编译后说
FreeRTOS中的裁剪和配置就是用这种条件编译的方法来实现的,很多协议栈、RTOS系统和GUI库等也都是使用条件编译的方法来完成配置和裁剪的。
条件编译的好处就是节省空间,不需要的功能就不编译,这样可以根据实际需求来减少系统占用的ROM和RAM大小,根据自己使用的MCU来调整系统功耗,降低成本。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 在CubeMX中配置定时器 首先在CubeMX的"Pinout & Configuration"页面中选择一个可用的定时器,例如TIM2。 然后在"Clock Configuration"页中,启用TIM2的时钟,并配置其时钟频率。可以将TIM2的时钟频率设置为100kHz,用于实现一个10ms的定时器。 接下来,在"Configuration"页面,将TIM2配置为定时器模式,并设置其预分频器和计数器值,以实现一个10ms的定时器。例如,选择TIM2的时钟预分频器为999,计数器值为99,可以得到一个10ms的定时器。 2. 生成FreeRTOS的定时器中断 在"Project Manager"页面中,将FreeRTOS添加到项目中,并在FreeRTOSConfig.h文件中启用定时器中断。 //启用FreeRTOS的定时器中断 #define configUSE_TIMERS 1 接下来,在FreeRTOSConfig.h文件中配置定时器中断的优先级。可以选择一个较高的优先级,以确保定时器中断能够及时地被处理。 //定时器中断的优先级 #define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) 3. 实现定时器中断处理函数 在项目的main.c文件中,实现定时器中断处理函数。首先定义一个变量用于计数,每次定时器中断时将该变量加1。然后在定时器中断处理函数中,调用FreeRTOS的xTaskIncrementTick()函数,以增加FreeRTOS的系统时间计数器。 //定义一个变量用于计数 volatile uint32_t ulTickCounter = 0; //定时器中断处理函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { //计数加1 ulTickCounter++; //增加FreeRTOS的系统时间计数器 if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { xTaskIncrementTick(); } } 4. 启动定时器 在main函数中,调用HAL_TIM_Base_Start_IT()函数启动定时器。这将启用定时器中断,并开始计时。 int main(void) { //初始化FreeRTOS和HAL库 HAL_Init(); SystemClock_Config(); MX_FREERTOS_Init(); //启动定时器 HAL_TIM_Base_Start_IT(&htim2); //启动FreeRTOS的调度器 vTaskStartScheduler(); //永远不会到达这里 while (1) { } } 通过以上步骤,就可以在FreeRTOS中使用定时器中断了。每当定时器中断发生时,FreeRTOS的系统时间计数器就会增加1,从而实现任务调度和延时等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值