微型抢占式多任务实时内核设计
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
《微型抢占式多任务实时内核设计(第3页)》