用户登录  |  用户注册
首 页商业源码原创产品编程论坛
当前位置:PB创新网文章中心解决方案电子通信

微型抢占式多任务实时内核设计

减小字体 增大字体 作者:佚名  来源:本站整理  发布时间: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)。当有紧急消息发送给任务时,内核会提升任务的动态优先级,从而提高消息处理的实时性。当任务无紧急

上一页  [1] [2] [3] [4]  下一页

Tags:

作者:佚名

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
PB创新网ourmis.com】Copyright © 2000-2009 . All Rights Reserved .
页面执行时间:5,546.87500 毫秒
Email:ourmis@126.com QQ:2322888 蜀ICP备05006790号