OSE
OSE理解
OSE就是用于快速调度的操作系统。
其主要包括内存管理与进程管理两个方面。
OSE的全局变量与初始化
OSE的Main函数就调用一个函数start_OSE。在start_OSE函数中首先调用odo_config_start_handler1对系统的硬件进行初始化。
再调用odo_init_os进行OSE操作系统初始化。
odo_init_os
这其中会对OSE使用到的全局变量初始化,包括:
odo_config
odo_file_list/ odo_line_list
记录了各进程被强制start代码所在的文件名与行号。
OSE Process
Process状态
Waiting:
被W AIT的进程处于Waiting状态。
表示此任务正在等待一个新号Semaphore或事件Signal。Ready:
当一个W AITING进程接收到事件后,就会处于Ready状态了。
Running:
Ready状态的进程,如果CPU空出时间后,就会对齐进行调度。被调用的进程,CPU会运行其回调函数。
当某个进程运行在其回调函数中,则此进程就是Running状态。
Process functions
Start
进程被创建后,其就被Start,然后处于ready状态。
进程在创建后,其第一次进入进程是从进程的回调函数开始的。
进程的回调函数是一个死循环,后面的进入则是从进程保存的Context开始的。
如果进程回调函数运行完毕(死循环被break掉),则进程要被kill,同时其参数要被释放。如果进程回调函数运行完毕而不kill掉,则为垃圾进程了,不能完成任何工作。
W AIT(odo_wait)
当进程Start后,如果其需要ready一个消息,则会被W AIT。
终止进程,使其处于ready状态。直到被事件唤醒
唤醒进程的事件包括semaphore和signal。
其过程如下:
odo_swap_if_necessary
odo_swap_context
OSE Process的基本流程
对进程的理解:
进程是建立在操作系统的基础上的。有了操作系统才有进程的概念。
在操作系统之下的是CPU时间。进程只是操作系统为了让用户合理使用CPU时间以及各种外部资源而创建的CPU资源占用方式。
OSE本身的对进程管理的代码,可以认为是运行在超进程之上的代码。这个超进程也占用一定的CPU资源。
为了实现抢占式的CPU调度或者硬件中断最高优先级调度,并须要有某个起点代码地址。一般会遇到CPU抢占的情况有:
一个更高优先级的进程被W AIT,而后一个正在运行的低优先级进程给它一个事件,或者多
核系统中其它核给它一个事件进行触发。
这时候,必须有一个超进程,从某个固定起始代码点运行,把当前进程切换出来,并获取更高优先级进程开始运行。
进程创建删除与切换
新P创建
create_process函数创建新的进程。进程创建包括下面几个步骤
1.进程创建关键参数:
a)进程名称:
i.一个字符串指针,并须是字符常量的指针。
ii.最大15字符
b)进程类型:
i.包括OS_IDLE_PROC (1 << 4)、OS_PRI_PROC (1 << 2)、OS_INT_PROC
(1 << 0)。一般用户创建的是后两种。IDEL进程是系统自己创建的,且有且只
有一个IDEL进程。
ii.无效值是0,为OS_ILLEGAL
c)进程回调函数:
i.进程第一次进入的位置,也叫entry point.
ii.进程后续进入都是从系统保持的context进入的,不会再使用entry point了
d)优先级:是本进程类型内的优先级。用于优先调度
i.优先级值越大,优先级越低
ii.IDLE进程优先级是255
iii.INT进程优先级是从OSINT_PRIO_START 64开始
iv.PRI进程优先级是从0开始
v.但是INT比PRI类型有更高的优先级。
e)中断向量号(0-14):
i.在OS_INT_PROC进程有效,表示一种此进程的触发方式。可以是无效值-1。
ii.相对于普通OS_PRI_PROC进程,OS_INT_PROC进程还多有一种触发方式,就是中断触发。
iii.但是并不是所有OS_INT_PROC类型的进程都具有此触发方式。
OS_INT_PROC仅仅表示一种调度优先级类型。并不表明其一定会被中断触
发。
f)栈空间大小
i.OS_PRI_PROC类型的进程具有自己的栈空间
ii.OS_INT_PROC类型的进程全部共用OSE为其分配的公共栈空间
g)返回值PId:为中断好,是一个u16的值。
i.IDEL进程总是第一个被创建,且其PId为0
ii.其它的Process的Id从1开始,最大值可以定制,一般为63。
2.odo_init_pdb创建PDB(Process data block)结点:
a)pdb_t结点会记录此进程的所有参数。
b)记录进程的name/type/entry point/PRI/Stack Size/V ector/stack Pool ID
3.odo_init_pcb把创建调度PDB结点加入到PCB(process control block)链中:
a)odo_pcb_list[64] PCB是进程的控制结构,每个进程具有一个。
b)初始化的时候,每个都执行IDEL进程的PCB空间(IDEL固定用odo_pcb_list[0])
c)进程创建的时候从1开始找,发现空闲PCB结点(PId = 0),则为其分配新的PCB
结构空间。并指向此空间。
d)PCB空间的结构(pcb_s)的起始几个字段如下:
i.4B: POOL_MAGIC_PCB = 0xF55FU
ii.4B: sigbuf_head*
iii.4B: sigbuf_tail*
iv.2B:Pid
v.1B: process priority
vi.1B: process Type
vii.1B: process state
e)PCB中有进程的context字段:
i.进程被切换前,应该记录进程当前的SP/PC/REGISTERS的值,便于进程切回
时能够继续上次的运行
ii.同时记录了进程的一些更关键信息:比如进程的栈首指针、栈长等。
4.odo_init_process初始化被创建进程的状态:
a)TIMER 进程把PCB挂到OSE的TIMESLOT下等待触发。OSE一共有128个
TIMESLOT
b)INT进程,使能中断事件,可以被触发
c)对于PRI进程,则直接挂到其优先级的ready队列中了。
可见所有进程创建后都立刻变为ready状态
P删除
kill_proc
释放PCB记录,释放其signal queue内存,释放其stack pool内存,从ready队列中删除它。
需要把此
P抢占切换的情况
1.任务主动切除的情况:
任务被两种信号量Wait,或者被signal Wait时都会主动切出。在当前的进程中会search 新的最高优先级ready状态的进程,并进程SW AP运行。
2.任务主动要求切入的情况:
在两种信号量Send时,在Send的进程中都会判断目录进程的优先级是否大于本进程优先级,如果是则会强制切换到目标进程;如果不是则会把目标进程设置为ready状态。
semaphore
Fast semaphore
get_fsem-n
signal_fsem++
Normal semaphore
Signal
Signal相对与信号量有以下区别:
1.也是进程的一种运行控制方式,但更是进程间通信的一种方式。它可以携带大量的用户
信息。
2.Signal可以进行不同CPU间的通信,而信号量不可以。
3.在进程Kill是,必须把其中所有的Signal取完,否则会Kill失败。而信号量没有这个
要求。
在每个PCB中,会有一个Signal链表。
当一个进程收到一个Signal时,会把这个Signal的指针挂到此链表上。
当进程接收时,则返回此Signal的指针。所以接收进程需要释放Signal的内存。
sigbuf_s结构是一个单向链表。
Receive
CPU内进程间通信:
用户可以指定接收几个Signal一次。
一般现在接收一个,然后For循环。
如果接收多个,则返回的是一个sigbuf_s结构单向链表。
如果用户一个Signal都没有接收到,则会被WAIT。
被W AIT的用户需要等待Send函数的Swap操作。
Send
CPU内信号发送:
//参数检查
//设置内存被OSE接管标志
//获取目标PCB
//把Signal放到目标PCB的Signal链表后面
//WAKEUP或者SWAP目标进程
中断
中断接收
Tick:Timer中断的顶层函数
中断对原有P的抢占
中断完成后P的恢复
常用过程
Running P由于事件等待变为W aiting
odo_wait
完成以下步骤:
1.把本进程从ready队列中删除RQUEUE_REMOVE_FIRST
2.判断本优先级的ready队列是否还有有效进程,没有清除本队列的标识
3.调用odo_do_swap,查找新的最高优先级的进程切换到CPU
4.odo_swap_context是真正切换进程的函数,它把新的context装载到CPU中,并把老的
context保存下来
Waiting P收到事件后变为Ready
进程管理使用的链表
定时器TIMER进程处理
Timer进程都是中断进程,但是触发方式有两种。一种是软TIMER进程,一种是硬件TIMER 进程
1.软Timer中断进程PRTYPE_TIMER:是OSE内部根据CPU频率计算的TIMESLOT。
OSE有128个TIMESLOT。OSE把要触发的TIMER进程挂到这些SLOTS上,然后等待软件触发。
2.硬件Timer中断进行PRTYPE_INT:它就是一个普通的硬件中断触发进程。只是它的触
发时CPU硬件周期性地触发。CPU可以根据用户的设置,以多少个CPU TICK为周期触发一个中断事件。
3.硬件中断的触发方式更准。一般系统都是定制一个系统需要的最小时钟周期的
PRTYPE_INT进程。然后在此进程上,模拟建立各种周期的TIMER进程。
a)在这种模拟建立的TIMER进程中,相当于接管了OSE的PRTYPE_TIMER进程相
关的TIMERSLOT管理。
强制start切入
Start
把指定进程PCB强制切入(但是对进程的类型有要求)
OSE MAGIC NUMBER
0xFAAFU(POOL_MAGIC_STACK 4B): 进程调用栈空间起始标识
42 (STACK_CHECK_MARK 1B):进程调用栈空间结尾标识
0xF55FU(POOL_MAGIC_PCB 4B): 进程PCB的起始标识