FreeRTOS常见错误排查

FreeRTOS常见错误排查

1,栈溢出问题

每个TASK(任务)都有着自己独立维护的栈空间,而栈空间在任务被创建时就已经设定,任务当前使用栈空间大小对于开发者来说至关重要。在RTOS中提供了多种跟踪辅助调试栈相关问题的工具。

1,栈空间高水线函数

高水线通常被用在检测河流水位高度场景,高水线具有预警指示旱涝自然灾害发生可能性。同理,本节介绍的高水位函数同样能提供开发者参考的栈使用“水位”预警信息。

unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );

**传入参数xTask:**被查询任务的句柄----API 函数xTaskCreate()的参数pxCreatedTask

**函数返回值:**xTask从执行开始的运行历史中,栈空间最小余量,也就是该任务能使用栈空间的最长深度,这个值接近0时候,表明改任务离溢出不远了。

2,栈溢出检测参数调用钩子函数

HOOK(钩子)函数可以说是操作系统必有的一类函数,像Windows、Linux以及我前面讲述过的UCOS嵌入式实时操作系统都有这类钩子函数。是操作系统消息处理机制的程序段,通过系统调用,把它挂入系统。本节关注的是栈溢出钩子函数,具体介绍参考以下内容。

https://www.jianshu.com/p/6c5cfc0a3e9a

configCHECK_FOR_STACK_OVERFLOW

赋值1情况下:内核会在任务交换的时刻,任务的上下文在栈内全部保存完成后,检测栈指针指向是否超出了任务栈有效范围,溢出则钩子函数会被调用;

赋值2情况下:此方法在1上进行些许改进。当任务被创建后,任务栈空间被预置一个标记,通过这个标记是否被覆盖掉来判断是否发生了数据溢出事件。通常是使用栈内最后20字节来储存标记数据,不断检测这20字节内容来判断栈空间使用是否超出预期。

##2,其他常见错误##

###1,在TaskA中创建一个TaskB

任务在创建的时候就需要在内存堆中分配空间,许多Task在定义堆空间的时候可能就只够当前任务所有信息保存。

若开发者在不明白当前任务堆空间使用状态下,强行创建新任务,或者一些队列和信号量,这样无疑会导致溢出或者TaskA任务无法被创建。

此外,vTaskStartScheduler()被调用是他还会自动生成一个空闲任务,这个任务具有最小优先级。如在调用调度器时发生上述堆内存分配过小,此时空闲任务无法被创建,TaskA任务创建失败。所以,在调用vTaskStartScheduler()后加上一条空循环[for(;?]可以使这种错误更加容易调试。

###2,在中断中调用OS的危险API函数###

除了具有后缀为“FromISR”函数名的API函数,千万不要在中断服务程序中调用其他API。

###3,中断函数出现崩溃###

① 检查中断程序是否发生溢出。

② 中断服务程序语法书写是否正确,具体可能由宏使用,接口传值。

③ 中断若存在优先级,最好从最高优先级中断开始盘查。

###4,启动第一个任务后,调度器就崩溃了###

在第一个任务就崩溃,可能与两个地方有关:1 第一个任务内存分配过小,解决方案见上。2 调度器自身设置存在问题,如在ARM7使用调度器前,需要将调度器设定为管理模式(Supervisor mode),排查某些不能启动调度器的设置参数。

###5,调度器在挂载下调用OS的API###

RTOS分别提供了vTaskSuspendAll()和xTaskResumeAll()两个接口来使得调度器挂起和唤醒。所以在Pend期间千万不用尝试调用其他API。

###6,在调度器启动前程序就崩溃了###

同调度器挂起一样,在调度器未调用启动前就调用其他API,这样可能对导致程序崩溃。同时如果在中断中需要上下文切换操作的(读写队列或者信号量),那么这个中断在调度器启动前不能使能!

调度器在启动前依然可以使用创建任务,队列和信号量的API。

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值