第一章 构建整体系统框图
我们最终要设计的是一个完成的操作系统,因此我们最开始要做的就是构建整体的系统架构图,在构建系统框图之前我们需要先定义下我们操作系统的一些参数,也就是操作系统支持多少个任务,任务的调度方式,以及任务的一些结构体属性。对于嵌入式操作系统而言,其任务实际上对应着线程的概念,所有的线程都是共享一个硬件资源。为了方便后续的设计,我们这里先给出必要的参数:
任务属性 | 支持同优先级和不同优先级 |
调度方式 | 同优先级:时间片调度 不同优先级:抢占式调度 |
同优先级最大数量 | 8 |
不同优先级最大数量 | 8 |
下面是就绪队列结构图:
由于任务有四个状态,分别是运行状态,就绪状态,阻塞状态和挂起状态,但是微控制器在任意时刻只能运行一个任务,因此其他的任务就需要我们将其任务保存起来,这样就需要增加阻塞队列和挂起队列。上图中蓝色的箭头表示时间片切换时使用的指针,黑色的箭头表示控制块插入和删除时使用的指针,每个链表的头部和尾部各有一个无用的控制块,这个控制块是保证链表至少有两个控制块,这样做的目的是保证链表的所有操作都是相同的。
阻塞任务和挂起任务如何管理呢,由于阻塞队列每个滴答时钟都要刷新,因此我们也可以用一个双向链表来管理,挂起链表也是一样,唯一不一样的是挂起链表不需要刷新,而是用户主动去操作,这样就涉及到一个操作任务的过程,为了方便操作,我们需要记录每个任务的首地址,这样句柄就这样出现了,句柄实际上就是任务的首地址的一个变量。我们操作任务只需要使用其句柄就可以完成队列的删除和插入。
下面是操作系统的阻塞队列:
阻塞队列的操作有以下几种情况需要访问并操作:
1.当任务遇到系统延时
2.当任务的信号量不能得到满足时
3.系统滴答时钟
对于挂起队列而言,可以没有具体的数据结构对其进行保存,因为我们操作任务的时候需要使用该任务的句柄对其进行操作,但是为了方便查看,我们使用一个双向链表对其进行管理,如下图所示:
这样我们的整个大体结构就完成了。