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