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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


啰嗦两句

额,想了好久,不知道这篇文章该起个什么名字好,只能总结一下造成问题的原因放到标题那,但是还是感觉问题的指向性不明确,先这样吧。
先说结论:系统调度开始之前,使用诸如信号量创建函数等系统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
### FreeRTOS 裁剪方法及配置 #### 一、FreeRTOS 配置文件概述 `FreeRTOSConfig.h` 是 FreeRTOS 中最重要的配置头文件之一。通过修改该文件中的宏定义,可以调整内核的行为以满足特定的应用需求和硬件资源限制[^1]。 #### 二、内存管理方案的选择 FreeRTOS 提供了几种不同的内存分配策略(Heap_1.c 至 Heap_5.c),开发者可以根据目标系统的特性选择最合适的版本并将其编译入项目中。例如,在嵌入式系统中如果希望减少堆碎片,则可以选择更高效的实现方式[^2]。 #### 三、任务调度器参数设定 - **最大优先级数**:可以通过 `configMAX_PRIORITIES` 来设置支持的最大优先级数目; - **时间片轮转间隔**:使用 `configTICK_RATE_HZ` 定义每秒发生的滴答次数,默认情况下为 100Hz 即每隔 10ms 发生一次中断处理程序调用; 这些选项直接影响到实时性能表现以及功耗水平等方面的表现。 #### 四、队列长度与消息大小定制化 当创建队列时,除了指定其类型外还可以自定义存储的消息数量 (`uxQueueLength`) 和单条消息所占用的空间字节数(`uxItemSize`) 。合理规划这两项数值有助于优化RAM利用率的同时也提高了通信效率。 #### 五、禁用不必要的组件和服务 为了进一步缩小镜像体积并加快启动速度,应该仔细审查哪些服务是真正必需的,并关闭其余部分的功能开关。比如: - 如果应用程序不需要软件定时器功能的话就可以把 `INCLUDE_vTaskDelayUntil` 设置成 0 ; - 不打算使用的互斥信号量机制则应将对应的使能位设为 false ,即 `configUSE_MUTEXES=0`; 以上措施均能在不影响核心业务逻辑的提下有效降低开销。 ```c // 示例: 修改 configMAX_PRIORITIES 参数 #define configMAX_PRIORITIES (7) // 示例: 关闭某些不必要组件的支持 #define INCLUDE_vTaskDelete 0 #define INCLUDE_vTaskSuspend 0 #define INCLUDE_xTimerPendFunctionCall 0 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值