关于Free-RTOS调度器启动前API调用造成中断关闭问题

本文介绍了在FreeRTOS调度器启动前调用系统API如信号量创建函数,可能会关闭中断的问题。作者通过分析发现,这是由于 pvPortMalloc() 在分配内存时引发的中断关闭,而中断嵌套计数变量uxCriticalNesting的初始值非零导致。解决方案是在调度器启动前避免调用与操作系统相关的内存管理API,或手动将uxCriticalNesting置零。
摘要由CSDN通过智能技术生成

啰嗦两句

额,想了好久,不知道这篇文章该起个什么名字好,只能总结一下造成问题的原因放到标题那,但是还是感觉问题的指向性不明确,先这样吧。
先说结论:系统调度开始之前,使用诸如信号量创建函数等系统API会造成中断关闭


正文开始

事情的起因是这个样子的。前段时间在编写移动机器人底盘控制系统,使用的是STM32F4+Free-RTOS构建控制系统,外设除了控制移动的电机,还有一块全场定位系统,依据其检测机器人在环境中的位置作为反馈控制移动机器人底盘完成相应的路径任务,主控和外设之间使用CAN通信。

程序的大概流程是这样的。

    Main->BSP_Init->TaskCreate->TaskStartScheduler...

大家也许都看到了,我的所有外设初始化和硬件初始化都放在了main函数中开始的部分,包括时钟,串口,电机,全场定位模块等等。也就是说,进入main之后,我首先进行了必要的外设初始化,之后才创建相关任务,启用调度器进行操作系统任务调度,进入正常调度。

平时这样写是没有问题的,但是因为这次的底盘控制建立在全场定位模块的位置信息之上,位置信息是通过CAN中断接收,而且第一个任务就是电机控制任务,也就是在TaskCreate执行的时候,要保证全场定位初始化完成并通过CAN接收到正确的数据,不然就会炸车。但是关键问题在于——全场定位模块的初始化之后需要一段时间的延迟才会返回正确的数据,换句话说,我必须在全场定位初始化之后等待一段时间才能进行控制任务创建,启用调度器。不然控制任务就会跑飞。
正常情况下,我只需要在全场定位初始化后面加一点点延时就好,但是考虑到不知道全场定位初始化之后需要多少延时合适,并且满足快速启动要求,所以并没有采取使用延时的方法,而是采用了信号量的方式。流程如下

CAN_Init->xSemaphoreCreate(GPS_SEM)->GPS_Init->xSemaphoreTake(GPS_SEM)->TaskCreate-> TaskStartScheduler...;

CAN_Rx
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值