打印
[应用相关]

多优先级任务

[复制链接]
801|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
上次我们学习了位图结构操作,究竟会有什么用呢?学完本节你就会懂了,慢慢享受这个过程吧!在操作系统里,任务的数目很多,而资源却是有限的,当多个任务都在同一个资源时,这时资源该如何分发呢?这里我们引入优先级的概念,大概思路就是给每一个在等待资源的任务指定优先级,资源根据任务优先级的高低依次派发。

使用特权

评论回复
沙发
dingbo95|  楼主 | 2019-6-29 18:58 | 只看该作者
如何派发呢?这里引入一个RTOS的就绪表,在就绪表里面,每一个表项对应一个任务和一个优先级,就绪表表明哪些优先级的任务等待占用CPU运行。这里到了很关键的地方,就绪表不就是上次我们所学的位图结构吗?为了快速找到优先级高的任务,我们需要对整个就绪表进行查找。这就是我们所谓的位图中BitMapQueryFirstSet()函数。寻找就绪表就绪位置标记是否就绪,快速查找为0时,表明该优先级没有要执行的任务,为1时表明该优先级有要执行的任务。

使用特权

评论回复
板凳
dingbo95|  楼主 | 2019-6-29 18:58 | 只看该作者
多优先级任务的具体实现:
1.添加优先级字段(在任务结构体中)。

使用特权

评论回复
地板
dingbo95|  楼主 | 2019-6-29 18:59 | 只看该作者
2.添加就绪表(位图表)。
//添加任务就绪表
t_bitmap  TaskPrioBitmap;

使用特权

评论回复
5
dingbo95|  楼主 | 2019-6-29 18:59 | 只看该作者
3.添加配置文件,一个有远见的人总是为后面发生的一切有所考虑,按部就班照着做就好了。新建um_config.h文件,目前只定义了一个优先级个数的宏。

使用特权

评论回复
6
dingbo95|  楼主 | 2019-6-29 19:00 | 只看该作者
4.修改任务数组列表,使用定义的宏将修改为um_os  *taskTable[TaskPrioNum]

使用特权

评论回复
7
dingbo95|  楼主 | 2019-6-29 19:00 | 只看该作者
5.修改任务调度器算法,上次的任务调度算法又丑又长,只需区区几行,看着舒服又自在,强调一下这个主要是判断查找最高优先级就绪的任务是否是当前执行的任务,不是该任务将会发生切换。又长又臭的代码可以删除了,开心到极点。
if(taskTable[BitMapQueryFirstSet(&TaskPrioBitmap)] != currentTask)
{
           nextTask = taskTable[BitMapQueryFirstSet(&TaskPrioBitmap)];
           umTaskSwitch();
        }

使用特权

评论回复
8
dingbo95|  楼主 | 2019-6-29 19:06 | 只看该作者
修改任务调度器

使用特权

评论回复
9
dingbo95|  楼主 | 2019-6-29 19:06 | 只看该作者
6.修改Systick中断函数,主要是扫描任务中延时是否减为0,减为0时将任务就绪列表中的标志位设为1,该任务处于可执行状态。调用任务调度函数umTaskSched(),切换任务。
void SysTick_Handler(void)
{
int i;
  for(i=0;i<TaskPrioNum;i++)
        {
          if(taskTable[i]->DelayTicks >0)
                {
                   taskTable[i]->DelayTicks--;
                }
                else
                {
                   BitMapSet(&TaskPrioBitmap,i);
                }
        }
        umTaskSched();
}

使用特权

评论回复
10
dingbo95|  楼主 | 2019-6-29 19:07 | 只看该作者
7.修改任务初始化函数,添加任务优先级设置代码,然后根据任务的优先级来填充任务列表,最后就是将任务就绪。
task->prio = TaskPrioNum;
taskTable[Prio] = task;  
BitMapSet(&TaskPrioBitmap,Prio);       

使用特权

评论回复
11
dingbo95|  楼主 | 2019-6-29 19:08 | 只看该作者
8.修改任务初始化,主要是安排任务的优先级顺序,这里任务1的优先级为0,任务2的优先级为1,空闲任务的优先级为2,将nextTask指向优先级最高的那个任务。

使用特权

评论回复
12
dingbo95|  楼主 | 2019-6-29 19:08 | 只看该作者
下面开始Debug测试一下,先在nextTask = taskTable[BitMapQueryFirstSet(&TaskPrioBitmap)]处设置一下断点,看一下第一个执行的任务是不是优先级最高的任务。

使用特权

评论回复
13
dingbo95|  楼主 | 2019-6-29 19:09 | 只看该作者
点击全速运行,执行到断点处,单步运行完毕,可以看到nextTask的值已经是任务1了,说明第一个任务成功切换到了优先级最高的任务了。

使用特权

评论回复
14
dingbo95|  楼主 | 2019-6-29 19:09 | 只看该作者
再次将断点设置到任务1 中TaskDelay(10)处,执行延时会发生任务切换,同时将任务1优先级标志位清0,表明任务1此时还处于挂起状态。

使用特权

评论回复
15
dingbo95|  楼主 | 2019-6-29 19:09 | 只看该作者
此时在任务2中设置断点,由于任务1的优先级标志位已经清0,程序将切换到任务2中。

使用特权

评论回复
16
dingbo95|  楼主 | 2019-6-29 19:10 | 只看该作者
同样的。在任务2中执行延时,也会将任务2优先级的标志位清零,程序也会触发切换到没有被清零的最高优先级的任务中,毫无疑问,必将切换到空闲任务中。方便观察,在空闲任务中进行i++操作。

使用特权

评论回复
17
dingbo95|  楼主 | 2019-6-29 19:10 | 只看该作者
在空闲任务 i++处设置断点,全速执行程序会切换到此处,验证了此次多任务优先级的正确性。

使用特权

评论回复
18
dingbo95|  楼主 | 2019-6-29 19:10 | 只看该作者
又是一个周末,虽是心情疲惫,也要**下去,尽管写的不怎么样,也要写下去,万一能出版了呢?哈哈哈,沾沾自喜,周末愉快,大家晚安!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

52

主题

1197

帖子

5

粉丝