在前面已经把FreeRTOS移植成功,并有一个DEMO可以运行,但说如果仅仅是这样云里雾里的去让自己的产品跑FreeRTOS,心里肯定是很荒的,接下来是一步步的学习下去吧。下面是我使用的配置文件,也是从官方的DEMO里复制出来的。
#define configUSE_PREEMPTION 1 //为1时RTOS使用抢占式调度器,为0时RTOS使用协作式调度器(时间片)。
#define configUSE_IDLE_HOOK 0 //设置为1使用空闲钩子(Idle Hook类似于回调函数),0忽略空闲钩子。
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( 100000000UL ) //系统时钟100M,由硬件决定
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) //Systick,1000,也是FreeRTOS的时钟节拍
#define configMAX_PRIORITIES ( 9 ) //配置应用程序有效的优先级数目。任何数量的任务都可以共享一个优先级,使用协程可以单独的给与它们优先权。
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 90 ) //定义空闲任务使用的堆栈大小
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) ) //RTOS内核总计可用的有效的RAM大小
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1 //设置成1表示启动可视化跟踪调试,会激活一些附加的结构体成员和函数
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1 //其它共享空闲优先级的用户任务就绪时,空闲任务立刻让出CPU,用户任务运行,这样确保了能最快响应用户任务。
#define configUSE_MUTEXES 1 //使用互斥信号量
#define configQUEUE_REGISTRY_SIZE 0 //1.它允许在调试GUI中使用一个队列的文本名称来简单识别队列;2.包含调试器需要的每一个记录队列和信号量定位信息;
#define configCHECK_FOR_STACK_OVERFLOW 0 //堆栈溢出检测,调试时可以开启,正常运行建议关闭
#define configUSE_RECURSIVE_MUTEXES 0 //设置成1表示使用递归互斥量,设置成0表示不使用
#define configUSE_MALLOC_FAILED_HOOK 1 //内存分配失败勾子函数
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 0 //设置成1表示使用计数信号量,设置成0表示不使用。
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0 //协程(Co-routines)主要用于资源发非常受限的嵌入式系统(RAM非常少),通常不会用于32位微处理器
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 0 //使用软件定时功能
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function.使能一些API接口函数 */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
/* This demo makes use of one or more example stats formatting functions. These
format the raw data provided by the uxTaskGetSystemState() function in to human
readable ASCII form. See the notes in the implementation of vTaskList() within
FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* Run time stats gathering definitions. */
#ifdef __ICCARM__
/* The #ifdef just prevents this C specific syntax from being included in
assembly files. */
void vMainConfigureTimerForRunTimeStats( void );
unsigned long ulMainGetRunTimeCounterValue( void );
#endif
#define configGENERATE_RUN_TIME_STATS 1 //两个函数一起为统计任务运行时间服务
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vMainConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() ulMainGetRunTimeCounterValue()
/* Cortex-M specific definitions. */ //此处定义MCU使用几位进行中断优先级配置,本项目使用4位,可表示0-15的16个中断优先级
#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 /* 15 priority levels */
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf //最低优先级
/* 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 //FreeRTOS可以屏蔽的最高优先级,比如进入临界段代码的时候关中断,其实就是关闭比这个优先级更低的中断
/* 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. */ //断言,在调试阶段可以开启,调试完成后这尽量关闭
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler //系统服务异常
#define xPortPendSVHandler PendSV_Handler //可悬挂
#define xPortSysTickHandler SysTick_Handler //滴答定时器SysTick中断函数
在每行代码后面使用//进行注释其实是和源代码的规范和风格是不一致的,但多年来还是习惯用这种方式进行注解,这样代码左边看起来会比较整洁,右边注解看着也方便。上面的配置文件其实是不太全的,很多都没有列出来,暂时先按照这个来研究。
FreeRTOS的配置文件中有两种宏。
. “config”开始的宏:主要是用来定义一起功能模块的开启与关闭。
. “INCLUDE_”开始的宏:使用“INCLUDE_”开头的宏用来表示使能或除能 FreeRTOS 中相应的 API 函数, 作用就是用来配置 FreeRTOS 中的可选 API 函数的。
- configUSE_PREEMPTION 为 1 时使用抢占式调度器,为 0 时使用协程。如果使用抢占式调度器的话内核会在每个时钟节拍中断中进行任务切换,当使用协程的话会在如下地方进行任务切换:
● 一个任务调用了函数 taskYIELD()。
● 一个任务调用了可以使任务进入阻塞态的 API 函数。
● 应用程序明确定义了在中断中执行上下文切换。 - configUSE_IDLE_HOOK 设置为1使用空闲钩子(Idle Hook类似于回调函数),0忽略空闲钩子。在刚刚开始移植的调试的过程中可以全部禁止HOOK类的定义,当然DEMO里面已经做好的,可以保留,自己可研究下作用。
- configUSE_TICK_HOOK FreeRTOS的系统时钟的钩子函数。
- configCPU_CLOCK_HZ 单片机的工作时钟频率
- configTICK_RATE_HZ 配置滴答定时器Systick,1000,也是FreeRTOS的时钟节拍
- configMAX_PRIORITIES 配置应用程序有效的优先级数目。任何数量的任务都可以共享一个优先级,使用协程可以单独的给与它们优先权。任务优先级选择原则时间片轮转的任务可以低一些,IRQ中断触发的任务可以优先级高一些。
- configMINIMAL_STACK_SIZE 空闲任务堆栈大小,一般空闲任务没有太多的事情要做,可以适当分配少一点的堆栈空间,可实际测试下使用量,最做修改。
- configTOTAL_HEAP_SIZE RTOS内核总计可用的有效的RAM大小,这个在定义的时候可以稍微设置多一些,按照一个任务2K的大小设置,而FreeRTOS的全局变量及一些静态变量是不会占用这个空间大小的,这些全局及静态变量具体有多少还没有统计。
- configMAX_TASK_NAME_LEN 任务名称长度,任务名称不能太长,只要能区分出每个任务即可。
- configUSE_TRACE_FACILITY 设置成1表示启动可视化跟踪调试,会激活一些附加的结构体成员和函数,还没有测试过,不清楚具体功能怎么使用。
- configUSE_16_BIT_TICKS 设置系统节拍计数器变量数据类型,系统节拍计数器变量类型为 TickType_t,当configUSE_16_BIT_TICKS 为 1 的时候 TickType_t 就是 16 位的,当configUSE_16_BIT_TICKS为 0 的话 TickType_t 就是 32 位的。
- configIDLE_SHOULD_YIELD 其它共享空闲优先级的用户任务就绪时,空闲任务立刻让出CPU,用户任务运行,这样确保了能最快响应用户任务。
- configUSE_MUTEXES 互斥信号量,我自己的系统中不使用信号量,使用任务通知,并通过全局变量来实现数据交互与信息传递。
- configQUEUE_REGISTRY_SIZE 1.它允许在调试GUI中使用一个队列的文本名称来简单识别队列;2.包含调试器需要的每一个记录队列和信号量定位信息;这个是搜索出来的解答,目前没有用到。
- configCHECK_FOR_STACK_OVERFLOW 堆栈溢出检测,调试时可以开启,正常运行建议关闭
- configUSE_RECURSIVE_MUTEXES 设置成1表示使用递归互斥量,设置成0表示不使用,未使用也未研究。
- configUSE_MALLOC_FAILED_HOOK 内存分配失败勾子函数
- configUSE_APPLICATION_TASK_TAG 为任务分配标签值,设置为1来使用vTaskSetApplicationTaskTag函数,分配的标签只对应用程序有用,内核不使用,暂时不知道如何使用。
- configUSE_COUNTING_SEMAPHORES 设置成1表示使用计数信号量,设置成0表示不使用。
- configUSE_CO_ROUTINES 协程(Co-routines)主要用于资源发非常受限的嵌入式系统(RAM非常少),通常不会用于32位微处理器,以后也不使用
- configUSE_TIMERS 使用软件定时功能,当我们定时器不够用的时候可以考虑,在定时器资源充足的情况下无需使用。
- configUSE_STATS_FORMATTING_FUNCTIONS 和configUSE_TRACE_FACILITY一起开启函数 vTaskList() 任务列表和 vTaskGetRunTimeStats()获取任务运行时间。
下面为一些API函数使能定义: - INCLUDE_vTaskPrioritySet 任务优先级设置。
- INCLUDE_uxTaskPriorityGet 任务优先级获取。
- INCLUDE_vTaskDelete 任务删除,在我的系统里没有用到任务删除,可以不开启这个函数。
- INCLUDE_vTaskCleanUpResources 任务删除后,可以回收任务所使用的资源,和上面一起使用。
- INCLUDE_vTaskSuspend 任务挂起。
- INCLUDE_vTaskDelayUntil 绝对延时函数,周期性任务可以使用。
- INCLUDE_vTaskDelay 相对延时函数,此函数在我的项目中可以不开启。
- 关于配置文件的其它一些信息可以在上面的代码中查看。
版权声明:本文为weixin_43306071原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。