中级会员
- 积分
- 321
- 金钱
- 321
- 注册时间
- 2015-3-28
- 在线时间
- 64 小时
|
5金钱
本帖最后由 小小速 于 2016-11-21 16:48 编辑
最近遇到点麻烦,写了十几天的驱动才发现放在一起主程序没法工作了刚毕业的小白,身边也没个懂的,只能来求助广大网友了
想用时间片轮询的方式,看了一天的资料现在有点迷糊了
[mw_shl_code=c,true]// 任务结构
typedef struct _TASK_COMPONENTS
{
uint8 Run; // 程序运行标记:0-不运行,1运行
uint8 Timer; // 计时器
uint8 ItvTime; // 任务运行间隔时间
void (*TaskHook)(void); // 要运行的任务函数
} TASK_COMPONENTS; // 任务定义[/mw_shl_code]定时器中断函数
[mw_shl_code=c,true]void TaskRemarks(void)
{
uint8 i;
for (i=0; i<TASKS_MAX; i++) // 逐个任务时间处理
{
if (TaskComps.Timer) // 时间不为0
{
TaskComps.Timer--; // 减去一个节拍
if (TaskComps.Timer == 0) // 时间减完了
{
TaskComps.Timer = TaskComps.ItvTime; // 恢复计时器值,从新下一次
TaskComps.Run = 1; // 任务可以运行
}
}
}
}[/mw_shl_code]
[mw_shl_code=c,true]/**************************************************************************************
* FunctionName : TaskProcess()
* Description : 任务处理
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void TaskProcess(void)
{
uint8 i;
for (i=0; i<TASKS_MAX; i++) // 逐个任务时间处理
{
if (TaskComps.Run) // 时间不为0
{
TaskComps.TaskHook(); // 运行任务
TaskComps.Run = 0; // 标志清0
}
}
}[/mw_shl_code]
问题在下面这里:
[mw_shl_code=c,true]static TASK_COMPONENTS TaskComps[] =
{
{0, 60, 60, TaskDisplayClock}, // 显示时钟
{0, 20, 20, TaskKeySan}, // 按键扫描
{0, 30, 30, TaskDispStatus}, // 显示工作状态
// 这里添加你的任务。。。。
};[/mw_shl_code]
时间片轮询去执行任务,每个任务的执行周期是在上面结构体里初始化的,然后每隔一定时间(如1ms)进入定时器中断,在中断函数里刷新任务,同时进行调度,这个能看懂
问题是这种方法,只是说明了每个周期性任务如何互不干扰的运行,但是并没有说当一个任务里面包含delay函数时,delay函数的实现,
比如有一个IIC的任务每隔100ms产生一次通信,这个100ms的周期可以在上面的任务结构体里面初始化参数uint8 ItvTime; // 任务运行间隔时间
那IIC的时序延时又该如何实现呢?小的延时通过死等实现,对于大于最小时间片(1ms)的延时,是不是在delay的地方重新对TaskComps.Timer进行赋值呢?还有就是这个时间轮询好像没有提到状态机的问题,是不是这种轮询不需要任务里面写状态机就能实现多任务并行呢?
|
最佳答案
查看完整内容[请看2#楼]
如果延时时间小于定时器中断的时间,那就只能死等或者另外再开个定时器来完成这部分延时
但我看你问的好像不完全是这个问题,你还想问在状态机编程时如何解决多个地方延时对吧?
关于这个问题我刚花了点时间仿照contiki的思想写了一个很简单的测试代码,风格跟操作系统很像,但本质还是状态机:
代码我晚点会以帖子的形式发布并做详细解释,你看下你想要的是不是这个效果吧,在某个任务里面有多个延时
|