目前在进行对使用FreeRTOS的项目的代码升级,之前采用的主逻辑任务切换模式:由一个任务来进行逻辑上为串行的不同功能切换,其他任务分别负责通信实时传输、传感器检测和电机控制,系统中断中采用变量传递参数而非二值信号量。
这个模式有两个问题:
(1)传感器的信号传递过于复杂:当一个传感器信号(如上升沿)到来时,改变传感器标志变量的值,然后等待任务轮询到该变量的改变,再改变任务中的逻辑步骤变量值,来使任务下一次轮询时进入下一步逻辑,且任务通过轮询来不断检测来自队列的逻辑执行命令。这样的机制会导致传感器信号传递的实时性降低。
(2)由于需要接收队列中的命令的同时还需要自动执行当前的逻辑步骤,任务设计就必须设计成轮询机制,这样无法利用阻塞机制来提高系统资源的利用率,还大大增加了任务设计的复杂性,出BUG概率大大增加,且修改BUG牵一发动全身的现象极其严重。
基于以上原因我决定重新设计任务切换、管理系统,以充分利用RTOS任务阻塞和二值信号量同步中断、任务的优点。
这个项目的特点是:
1.功能性任务不可同时运行
2.对传感器信号和串口通信实时性要求高
3.对电机的电流检测实时性要求高
4.每次执行功能性任务都要求从任务头开始执行,即使中途被其他功能性任务中断
基于以上特点,我决定采用添加/删除任务的方式来进行任务切换。
在串口接收任务中进行任务的创建,每个功能性任务都由以下结构组成,以系统初始化任务举例:
void InitTask(void const * argument)
{
PeriStatus.SystemStatue = TASK_Init;
HandleTemp = TaskInitHandle;
if(PeriStatus.FeedRest != Motor_Init)MotorCtrl(FeedRestType, Motor_Reset);
FLASH_EEPROM_Write();
RotateReset();
if(PeriStatus.Hold != Motor_Init)MotorCtrl(HoldType, Motor_Reset);
if(PeriStatus.Slide != Motor_Init)MotorCtrl(SlideType, Motor_Reset);
for(;;)
{
if((PeriStatus.Hold == Motor_Init)&&
(PeriStatus.Slide == Motor_Init)&&
(PeriStatus.Rotate == Motor_Init)&&
(PeriStatus.FeedRest == Motor_Init)&&
(PeriStatus.Feed == Motor_Init))
{
PeriStatus.SystemStatue = TASK_Default;
HandleTemp = defaultTaskHandle;
vTaskDelete(NULL);
}
osDelay(50);
}
}
任务在执行完毕后会自行删除,如果中途串口接收任务想要创建别的功能性任务,只需利用HandleTemp
储存的当前任务句柄将任务删除,再创建新的任务即可。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)