第十八讲 任务延时队列

十七讲比较简单,就是介绍双向列表,就不介绍了。

  问题引入:目前在systick的中断函数中,会扫描所有的32个任务,减去任务的延时。这样做有点浪费,因为进入延时的任务不多,所以设计一种方案,只扫描进入延时的任务,所以考虑设置一个延时任务队列。

    

  延时任务队列有两种办法。方式一很容易理解,每个延时任务带延时时间,每次全列表扫描,每个延时时间减1。方式2中,每个任务的真正延时时间,等于自己结构体中的延时时间,加上前面所有任务的延时时间。

  方式一的好处是插入很容易,问题是每次都要扫描所有的任务。方式二,插入的时候需要扫描所有的任务,但是减1的时候,只要减去最前面的任务即可,如果延时时间不为0,马上返回,不需要扫描后面的任务。例子中用的是方式一。

    这里有个操作,比较有意思,需要说明下。要实现的功能是,知道了结构体中某个字段的地址,反推这个结构体的地址。

#define tNodeParent(node, parent, name) (parent *)((uint32_t)node - (uint32_t)&((parent *)0)->name)
 tTask * task = tNodeParent(node, tTask, delayNode);

tTask是父结构体,下面有个delayNode的字段,它也是个结构体。然后node是delayNode的实例,表示这个字段的实际地址,然后减去偏移,就得到了这个父结构体的地址。

 最主要的改动就是在systick的中断函数上,扫描delay的列表,如果task的延时减到0了,就从这个delay list 中移除。

 

  

posted on 2018-03-06 20:17  nasduc  阅读(274)  评论(0编辑  收藏  举报

导航