首 页 用户登录 | ![]() |
|||
|
|||
按字母检索 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
按声母检索 | A | B | C | D | E | F | G | H | J | K | L | M | N | O | P | Q | R | S | T | W | X | Y | Z | 数字 | 符号 |
|
![]() |
您的位置: 5VAR论文频道 → 论文中心 → 理工论文 → 电子通信 |
|
|||||
微型抢占式多任务实时内核设计 | |||||
收集整理:佚名 来源:本站整理 时间:2009-01-11 00:02:12 点击数:[] ![]() |
|||||
好可用一个16位的二进制数来标识。休眠态用os_slpState来表示,从高位算起,第N位为0表示静态优先级为N的任务处于休眠态。等待态是依据“事件驱动”观念而专为消息和信号而设计的,用os_rdyhState和os_rdyState两个16位的变量来记录。只有当os_rdyhState和os_rdyState的第N位均为0时,才表示静态优先级为N的任务处于等待态。如果任务处于非等待状态,意味着任务已在处理事件或者有事件要处理(可以认为任务一开始就处理“启动”这个“虚拟事件”),这时,才有动态优先级的概念。如果os_rdyhState中的第N位为1,表示静态优先级为N的任务的动态优先级为紧急级;如果os_rdyhState第N位为0,则表示静态优先级为N的任务的动态优先级为普通级。要求实时处理的事件发生后,内核简单将os_rdyhState相应位置1,提升任务的动态优先级;当前事件处理完毕后,如果已无实时性要求较高的事件等待处理,简单地将os_rdyhState相应位清0,降低任务的动态优先级。由此,即可实现优先级的动态可调。只有当任务既不处在休眠态也不处在等待态时,任务才是可以调度的。 2 任务管理 2.1 任务控制块 多任务系统中用任务控制块(TCB)来记录任务的各种属性。在这些属性中,最重要的是任务堆栈栈顶地址。进行上下文切换(context switch)时,被停止执行的任务的所有寄存器状态、下一条代码的地址都要入栈保护,因而这个属性是必需的。如果允许修改任务的优先级,优先级属性也是必需的。所以,将任务控制块简化如下: typedef struct{ uint_16 msg[2]; /*消息接收区*/ int * sp; /*堆栈栈顶指针*/ uchar priority; /*静态优先级*/ uchar reserved; /*保留 */ }TCB,*PTCB; TCB os_tcbs[ USER_TASK_NUM +1 ]; /*用户任务数最多为15个*/ msg用来存储发送给任务的消息,两个16位的二进制可按位存放32个消息。sp指向任务堆栈栈顶。priority记录任务的静态优先级。数组os_tcbs用来记录系统所有任务的信息,其下标与任务的ID号相对应,即ID号为N的任务的控制块为os_tcbs[N]。 2.2 任务的创建 os_CreateTask函数用来创建一个任务: void os_CreateTask( TASKPROC task, //任务函数的指针 uchar taskId, //任务的ID号 uchar priority, //优先级 int * pStack, //任务堆栈栈底地址 void * param //任务函数的入口参数 ); typedef void (*TASKPROC)( void * param); 创建任务时,内核要做以下几方面的工作:① 初始化任务控制块;② 初始化任务堆栈,使其如同被其它任务抢断时的情形;③ 将任务状态置为就绪态。该函数是依赖于处理器的,图1是较为通用的描述。 中断程序中,在高优先级任务剥夺低优先级任务之前,内核将断点时的各寄存器状态入栈保护,这部分区域即为寄存器映像区。将任务退出函数os_Exit的地址先于任务函数MyTask入栈,以使MyTask函数退出后返回到os_Exit中去,由此来实现任务的自动删除。 2.3 任务切换 与任务创建一样,任务切换代码与硬件相关。在PC机上,代码和步骤如下: void interrupt os_Schedule( ) …………(1) { if( os_nLayers )return; os_nLayers++; …………(2) _DX = (int)os_pCurTCB; /*os_pCurTCB指向当前任务的控制块*/ *(int*)(_DX+4) = _SP; *(int*)(_DX+6) = _SS; …………(3) os_GetReadyTask( ); …………(4) _DX = (int)os_pCurTCB; _SP = *(int*)(_DX+4); _DX = *(int*)(_DX+6); _SS = _DX; …………(5) os_nLayers--;? …………(6) UNLOCK_INT( ); } …………(7) (1)利用C语言interrupt关键字使各寄存器入栈保护。(2)锁定调度器,不允许重调度。(3)将当前任务的栈顶地址(由堆栈段寄存器SS和栈指针寄存器SP组成)保存在os_pCurTCB->sp中(PC机下,TCB中的sp定义为远指针类型)。(4)选出优先级最高的就绪任务(方法类似于μC/OS),并将os_pCurTCB指向新任务的控制块。(5)栈寄存器指向新任务的栈顶地址。(6)解锁调度器。(7)各寄存器出栈,恢复到上次被中断时的情形。 3 消息与信号 为很好地支持事件驱动编程,MicroStar借鉴了Windows的“基于消息,事件驱动”观念,并加以扩展。在MicroStar中,事件不仅可以触发消息、信号,而且由事件触发的消息或信号是有优先级的,这是因为不同事件对处理的实时性要求是不同的。内核正是根据消息、信号的优先级来动态调整任务的动态优先级的。 3.1 消 息 消息是一种很友好的通信方式。考虑中低档单片机的内存容量和需求,将消息简化为一个0~31的值。采用固定位图存储格式,将这32个值映射到任务控制块的msg域,这大大减小了存储空间。可将msg域看作一个32位的二进制变量,第i位为1,表示有值为i的消息,因此消息的存取只需通过简单的“与”、“或”运算。消息的优先级依值而定,值越大,优先级越低。在系统范围内,消息优先级又分为两级:紧急级(值0~15)与普通级(值16~31)。当有紧急消息发送给任务时,内核会提升任务的动态优先级,从而提高消息处理的实时性。当任务无紧急 Tags: |
提供人:佚名 | |
【返回上一页】【打 印】【关闭窗口】 |
![]() |
5VAR论文频道 |
![]() |
5VAR论文频道 |
![]() |
关于本站 -
网站帮助 -
广告合作 -
下载声明 -
网站地图
Copyright © 2006-2033 5Var.Com. All Rights Reserved . |