FreeRTOS知识点总结
1. 移植
- 添加src文件,添加包含路径
- 修改FreeRTOSconfig.h
- 定义中断组:4
- 宏定义SVC,PendSV,SysTick中断处理函数
- 根据所需功能,裁剪系统
2. 系统裁剪
对FreeRTOSConfig.h文件进行修改,宏定义打开/关闭,包含打开/关闭
- 内核相关配置
- 内存管理配置
- 钩子函数配置
- 任务追踪配置
- 协程配置
- 软件定时器配置
- 断言配置
- 中断配置
3. 调试方法
3.1 串口打印调试
- 需打开任务追踪配置
#define configUSE_TRACE_FACILITY 1
#define configGENERATE_RUN_TIME_STATS 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() 初始化定时器函数(),周期为系统时钟的10~20倍
#define portGET_RUN_TIME_COUNTER_VALUE() 设置全局变量,为时间统计功能提供节拍,在定时器中断服务函数中更新
- 初始化定时器,中断优先级设到最高
- 使用函数
vTaskList()
创建一个表格描述每个任务的详细信息 - 使用函数
vTaskGetRunTimeStats()
创建一个表格描述每个任务的运行时间和其所占总时间的百分比
函数原型:
void vTaskList( char * pcWriteBuffer );
void vTaskGetRunTimeStats( char *pcWriteBuffer );
- 调用
printf()
打印表格
3.2 IAR插件调试
- 打开任务追踪配置
#define configUSE_TRACE_FACILITY 1
- 打开IAR-Project-Options
- Debugger
- Plugins
- √ FreeRTOS and OpenRTOS
- Plugins
- Debugger
- 插件显示表格
3.3 栈溢出检测调试
3.3.1 方法1
在**任务切换**时,检测任务栈指针是否越界,越界则触发栈溢出钩子函数
- 打开钩子函数配置
#define configCHECK_FOR_STACK_OVERFLOW 1
- 在函数
vApplicationStackOverflowHook()
函数中,打印任务名
3.3.2 方法2
在任务创建时,任务栈所有数据初始化为0xa5,在任务切换时,检测末尾16个字节是否都为0xa5
- 打开钩子函数配置
#define configCHECK_FOR_STACK_OVERFLOW 2
- 在函数
vApplicationStackOverflowHook()
函数中,打印任务名
无论方法1、方法2都是在任务进行切换时执行,存在局限性:
- 任务执行的过程中出现过栈溢出,但任务切换前栈指针又恢复到了正常水平(方法1)
- 任务栈末尾的 16 个字节没有用到,即不会被修改,但是任务栈已经溢出了(方法2)
- 任务栈溢出后,把系统中的重要数据修改了导致系统直接进入Hardfault(方法1、2)
3.3.3 任务栈水位检测函数
函数uxTaskGetStackHighWaterMark (TaskHandle_t xTask)
,可返回自任务运行以来剩余可用堆栈空间的最小值,即任务运行过程中堆栈最大使用量时还剩余多少空间
- 打开包含
#define INCLUDE_uxTaskGetStackHighWaterMark 1
- 如果函数返回0则说明可能发生了任务堆栈溢出
4. 栈设置
- 创建任务时,设置任务栈大小,单位为word,从FreeRTOSConfig.h文件中定义的堆空间申请
- 启动文件.s中设置系统栈大小,单位为byte,中断函数与中断嵌套使用系统栈
- MSP主堆栈指针给系统栈使用,PSP进程堆栈指针给任务栈使用,进入中断函数及中断嵌套中,都是用MSP指针
- 实际应用中分配,按最坏情况:
- M3:64字节
- M4:200字节
5. 中断设置
-
中断优先级组配置:STM32只使用4位,共5组优先级组,使用FreeRTOS时,使用分组4,只有0~15抢占优先级
-
configPRIO_BITS
:配置系统中断优先级组寄存器[7:0]使用位数,设为 4 -
configLIBRARY_LOWEST_INTERRUPT_PRIORITY
:设置系统最低优先级,设为 15 -
configKERNEL_INTERRUPT_PRIORITY
配置内核中断优先级,由宏
configLIBRARY_LOWEST_INTERRUPT_PRIORITY
左移8-configPRIO_BITS
位得到,即配置PendSV,SysTick中断优先级为最低
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
:设为 1<=n<=15
设置 FreeRTOS 系统可管理的最大优先级,实际即对
BASEPRI
寄存器进行操作,优先级高于该值的中断,FreeRTOS内核无法调度
configMAX_SYSCALL_INTERRUPT_PRIORITY
由宏
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
左移8-configPRIO_BITS
位得到
图片
6. 列表
-
FreeRTOS列表:双向循环链表,初始化时,通过列表位迷你列表项作为末尾哨兵节点,将整个链表连接