void OSInit (void)
{
INT16U i;
/*****/
/*****/
OSTime = 0L; /* Clear the 32-bit system clock */
OSIntNesting = 0; /**中断嵌套层数计数,>0时候禁止任务调度***/ /* Clear the interrupt nesting counter */
OSLockNesting = 0; /**锁定嵌套计数器,>0时候禁止任务调度***/ /* Clear the scheduling lock counter */
OSTaskCtr = 0; /* 任务计数器Clear the number of tasks */
OSRunning = FALSE; /* 指出多任务是否开始Indicate that multitasking not started */
OSIdleCtr = 0L; /* 空闲任务计数器,Clear the 32-bit idle counter */
OSCtxSwCtr = 0; /* 统计计数器=任务切换的次数,Clear the context switch counter */
OSRdyGrp = 0; /*任务就绪组,任何时候只有一个bit位是置1的,和优先级有关 Clear the ready list */
for (i = 0; i < OS_RDY_TBL_SIZE; i++) {
OSRdyTbl[i] = 0; /**每个任务的就绪任务表**/
}
OSPrioCur = 0; /***存放应用任务的优先级***/
OSPrioHighRdy = 0;
OSTCBHighRdy = (OS_TCB *)0; /* TCB Initialization */
OSTCBCur = (OS_TCB *)0;
OSTCBList = (OS_TCB *)0;
for (i = 0; i < (OS_LOWEST_PRIO + 1); i++) { /**初始化任务优先级表(清零)*//* Clear the priority table */
OSTCBPrioTbl[i] = (OS_TCB *)0; /**全部的控制模块清成空闲状态**/
}
/**任务链表数组--**/
for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) { /* Init. list of free TCBs */
OSTCBTbl[i].OSTCBNext = &OSTCBTbl[i + 1]; /**将任务链表的TCB地址记录**/
}
OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS - 1].OSTCBNext = (OS_TCB *)0; /* Last OS_TCB */
OSTCBFreeList = &OSTCBTbl[0]; /**空任务块控制指针:初始化时候指向的是第一个任务**/
/*第一个任务是系统任务--空闲任务,还有一个统计任务(OS_N_SYS_TASKS=2时)**/
/**事件链表数组***/
for (i = 0; i < (OS_MAX_EVENTS - 1); i++) { /* Init. list of free EVENT control blocks */
OSEventTbl[i].OSEventPtr = (OS_EVENT *)&OSEventTbl[i + 1];
}
OSEventTbl[OS_MAX_EVENTS - 1].OSEventPtr = (OS_EVENT *)0;/**最后的事件表**/
OSEventFreeList = &OSEventTbl[0];
#if OS_STK_GROWTH == 1 /***由高地址向低地址方向***/
OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], OS_IDLE_PRIO);
#else /****栈的方向由低地址到高地址***/
OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[0], OS_IDLE_PRIO); // mand by jk 2007-8-16
// OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], OS_IDLE_PRIO);
#endif
}
void OSSemPend (OS_EVENT *pevent, INT16U timeout,
INT8U *err)reentrant
INT8U OSSemPost (OS_EVENT *pevent)reentrant
消息通信函数:OSSemPend(A)期待A事件的发生,如果事件A还没有发生,那么就被挂起(pending)等待,并且下一个优先级获得CPU的控制权,进行下一个任务。相应的OSSemPost();就是通知给OSSemPend()事件发生了,那么如果在下一个任务中执行了OSSemPost(A),则上面的任务就知道了事件A的发生,那么系统将CPU控制权交给了原来的优先级更高的任务运行。相应的函数有
OSFlagPend(),OSSemPend(),OSMutexPend(),OSMboxPend(),OSQPend()都是peng挂起等待某个事件的产生,否则进入到等待状态。
例子:
void TaskA()
{
OSSemPend(Event,5,err); //A任务等待系统里面
Event
事件的发生
}
void TaskB()
{
OSSemPost(
Event
); //B事件告示了
Event事件的发生
}
/***以下为内核中最重要的几个函数***/
INT8U OSTaskCreate(void (*task)(void *pd)reentrant,//任务函数
void *dataptr, //任务中需要使用的数据参数:万能指针类型
OS_STK *ptos, //任务栈顶指针:指向一开始申请的堆栈数组
INT8U prio)reentrant // 定义任务的优先级
{
void *psp; //堆栈任务指针
INT8U err;
if(prio>OS_LOWEST_PRIO) { //确保优先级在合法使用区域内
return (OS_PRIO_INVALID)
} //优先级错误则返回一个不合法的优先级错误代码
OS_ENTER_CRITICAL();//进入临界区域--关中断
if(OSTCBPrioTbl[prio]==(OS_TCB *)0) ///**是否有清空当前任务块的优先级链表**/
{
OSTCBPrioTbl[prio]==(OS_TCB *)1;
//提升系统性能,先开中断,离开临界区
OS_EXIT_CRITICAL();
//初始化任务堆栈,包含了任务执行首地址,数据,堆栈顶
/**初始化堆栈:在建立的堆栈区域存放相应的内容**/
psp=(void *)OSTaskStkInit(task,dataptr,ptos,0);
//初始化TCB任务控制模块函数:
err=OSTCBInit(prio,psp,(void *)0,0,0,(void *)0,0);
if (err == OS_NO_ERR)
{ /**没有error:说明建立的任务控制模块一切正常**/
OS_ENTER_CRITICAL();
OSTaskCtr++; /**增加任务数**/
OSTaskCreateHook(OSTCBPrioTbl[prio]); /**当OSTaskCreateHook( )被调用的时,它会收到指向已建立任务的任务控制块的指针,这样就可以调用里面的所有成员**/ /* Call user defined hook */
OS_EXIT_CRITICAL();
if (OSRunning) {
OSSched(); /****/
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0;
OS_EXIT_CRITICAL();
}
return (err);
}
else {
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
}
关于OSTaskCreate()函数内部调用的一些说明:
函数OSTCBInit(INT8U prio,OS_STK *ptos,OS_STK *pbos,INT16U id,INT16U stk_size,void *pext,INT16U opt)reentrant
分别为 优先级 栈顶指针 栈末尾 任务号 栈大小 用户使用堆栈区 任务扩展在OSTaskCreateExt()用
/**初始化最新创建的任务控制模块**
优先级、堆栈的起始地址、堆栈的结束地址、任务编号、任务堆栈大小....
****/
static OS_TCB *ptcb11;
INT8U OSTCBInit (INT8U prio,
OS_STK *ptos,
OS_STK *pbos,
INT16U id,
INT16U stk_size,
void *pext,
INT16U opt)reentrant
{
OS_ENTER_CRITICAL();
ptcb11 = OSTCBFreeList; /**首先赋值给空闲TCB指针**/ /* Get a free TCB from the free TCB list */
if (ptcb11 != (OS_TCB *)0)
{ /**检查TCB是否为空**/
OSTCBFreeList = ptcb11->OSTCBNext; /* Update pointer to free TCB list */
OS_EXIT_CRITICAL();
ptcb11->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */
ptcb11->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */
ptcb11->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */
ptcb11->OSTCBDly = 0; /* Task is not delayed */
#if OS_TASK_CREATE_EXT_EN
ptcb11->OSTCBExtPtr = pext; /* Store pointer to TCB extension */
ptcb11->OSTCBStkSize = stk_size; /* Store stack size */
ptcb11->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */
ptcb11->OSTCBOpt = opt; /* Store task options */
ptcb11->OSTCBId = id; /* Store task ID */
#else
pext = pext; /* Prevent compiler warning if not used */
stk_size = stk_size;
pbos = pbos;
opt = opt;
id = id;
#endif
#if OS_TASK_DEL_EN
ptcb11->OSTCBDelReq = OS_NO_ERR;
#endif
/**任务表的计算:当知优先级时就可以优先定义**/
ptcb11->OSTCBY = prio >> 3; /* Pre-compute X, Y, BitX and BitY */
ptcb11->OSTCBBitY = OSMapTbl[ptcb11->OSTCBY];
ptcb11->OSTCBX = prio & 0x07;
ptcb11->OSTCBBitX = OSMapTbl[ptcb11->OSTCBX];
#if OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_Sem_EN
ptcb11->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on an event */
#endif
#if OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2))
ptcb11->OSTCBMsg = (void *)0; /* No message received */
#endif
OS_ENTER_CRITICAL();
/***加入TCB链表:前后插入法***/
OSTCBPrioTbl[prio] = ptcb11;
ptcb11->OSTCBNext = OSTCBList; /* Link into TCB chain */
ptcb11->OSTCBPrev = (OS_TCB *)0;
if (OSTCBList != (OS_TCB *)0) {
OSTCBList->OSTCBPrev = ptcb11;
}
/**任务模块控制链表建立**/
OSTCBList = ptcb11;
/**任务成员变量:方便任务上下文切换**/
OSRdyGrp |= ptcb11->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb11->OSTCBY] |= ptcb11->OSTCBBitX;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
else {
OS_EXIT_CRITICAL();
return (OS_NO_MORE_TCB);
}
}