前面篇幅介绍了下合作式调度器,并且实现了一个fpfsm调度器。但是这个只是一个调度,没有提供任何的系统服务。
看过时间触发那本书的同学,一定知道基于时间触发对于具有周期性质和带有延时性质的任务执行的便利,那么今天我就
为fpfsm添加了软件延时服务。
这个会带来什么便利呢?以一个灯为例。首先来看下基于软件延时的实现:
1、延时函数是NONE-block;
2、每次任务需要查询延时时间是否到了;
3、基于状态机实现;
/****************** TASK ******************/
enum{
TASK_DELAY_START = 0,
TASK_DELAY_WAIT,
TASK_DELAY_END
};
typedef struct{
uint8_t state;
uint16_t hwDelayTimer;
uint16_t hwDelayMS;
ptTask *PCallBack;
}tLEDTaskStack;
static bool task_delay(void* pTemp)
{
#define DELAY_1MS274//310
tLEDTaskStack *ptTaskStack = (tLEDTaskStack*)pTemp;
if(NULL == ptTaskStack){
return false;
}
switch(ptTaskStack->state){
case TASK_DELAY_START:
ptTaskStack->state = TASK_DELAY_WAIT;
ptTaskStack->hwDelayMS = DELAY_1MS;
//break;
case TASK_DELAY_WAIT:
ptTaskStack->hwDelayMS--;
if(!ptTaskStack->hwDelayMS){
ptTaskStack->hwDelayMS = DELAY_1MS;
ptTaskStack->hwDelayTimer--;
if(!ptTaskStack->hwDelayTimer){
ptTaskStack->state = TASK_DELAY_END;
}else{
break;
}
}else{
break;
}
case TASK_DELAY_END:
if(USER_NEW_TASK(ptTaskStack->PCallBack,ptTaskStack,ADD_TASK_FIFO_TAIL)){
return false;
}
break;
}
return true;
}
/****************** TASK1 ******************/
static bool task1_start(void *pTemp)
{
static tLEDTaskStack s_tTask1Pram;
s_tTask1Pram.state=TASK_DELAY_START;
s_tTask1Pram.hwDelayTimer = 100;
s_tTask1Pram.PCallBack = NULL;
if(USER_NEW_TASK(task1_task,&s_tTask1Pram,ADD_TASK_FIFO_TAIL)){
return false;
}
return true;
}
static bool task1_task(void* pTemp)
{
tLEDTaskStack *ptTask1Pram = (tLEDTaskStack*)pTemp;
if(NULL == ptTask1Pram){
return false;
}
switch(ptTask1Pram->state){
case TASK_DELAY_START:
LED1 = ~LED1;
ptTask1Pram->state = TASK_DELAY_WAIT;
case TASK_DELAY_WAIT:
if(USER_NEW_TASK(task_delay,ptTask1Pram,ADD_TASK_FIFO_TAIL)){
ptTask1Pram->state=TASK_DELAY_START;
ptTask1Pram->PCallBack = task1_start;
return false;
}
break;
}
return true;
}
具体的例子,可以参考历程里面那个。
如果系统提供延时服务:
add_task_software_timer_t(task2,NULL,100);
任务函数:
static bool task2(void *pTemp)
{
LED1 = ~LED1;
add_task_software_timer_t(task2,NULL,100);
return false;
}
相对于自己去实现类似功能,要省去很多工作。实现的大体思路如下:
1、有一个软件延时空闲队列;
2、有一个软件延时服务队列;
3、add_task_xxx就是从空闲队列取一个Item,初始化后放入延时服务队列;
4、软件服务调度每次查询服务队列,如果延时没到,则减减;如果时间到了,根据参变量添加
fpfsm的任务到就绪队列,同时从时间服务队列删除,加入到时间空闲队列;
以上就是实现一个简单的软件延时服务的思路,具体代码就不贴出来了,因为太简单了,自己去实现就好。