s3c44b0移植ucos的一个实例[最新]
工程有三个文件夹,sample,startup,ucos
Startup为板子的公版函数,44blib.c,44BINIT.S,TARGET.C ucos为UCOS的公版函数
Sample里面只有一个文件,main.c:
MAIN.C:声明堆栈,声明任务函数,声明事件和MAIN()
#define STACKSIZE 512
OS_STK StartTaskStk[STACKSIZE];
OS_STK Led1TaskStk[STACKSIZE];
OS_STK Led2TaskStk[STACKSIZE];
OS_STK Led3TaskStk[STACKSIZE];
char *s1="\n led1 on !";
char *s2="\n led2 on !";
char *s3="\n led3 on !";
INT8U err;
OS_FLAG_GRP *Sem_F;
void StartTask(void *data);
void Led1Task(void *data);
void Led2Task(void *data);
void Led3Task(void *data);
一.初始化过程: int Main(int argc, char **argv)
{
ARMTargetInit(); //运行环境初始化
OSInit(); //OS初始化
Sem_F=OSFlagCreate(0,&err); //创建信号量集
OSTaskCreate(StartTask,(void *)0,&StartTaskStk[STACKSIZE-1],0);//创建起始任务
OSStart();
return 0;
}
void StartTask(void *pdata)
{
pdata=pdata;
ARMTargetStart(); //中断和TICK的设置
OSTaskCreate(Led1Task,(void *)s1,&Led1TaskStk[STACKSIZE-1],3);
OSTaskCreate(Led2Task,(void *)s2,&Led2TaskStk[STACKSIZE-1],4);
OSTaskCreate(Led3Task,(void *)s3,&Led3TaskStk[STACKSIZE-1],5);
do{
OSTaskDel(0);
}while(1);
}
1(ARMTargetInit(),MAIN()刚开始的运行环境初始化
void ARMTargetInit(void)
{
Port_Init();
Uart_Init(0,115200);
Uart_Select(0);
Uart_Printf("\r\nHello!uCOS-II Systerm !\r\n");
InitInterrupts(); //非向量中断,IRQ,禁止所有中断
InitTimers(); //设TICK为20ms
}
void InitInterrupts(void)
{
unsigned int cc;
for(cc=_RAM_STARTADDRESS;cc<(_RAM_STARTADDRESS+0x20);cc+=4)
{
*((volatile unsigned *)cc)=0xEA000000+((unsigned int)Image$$RO$$Base-0x0c000000-8)/4;
}
rINTCON=0x5;
rINTMOD=0x0;
rINTMSK=0X7FFFFFF;
}
2(ARMTargetStart(),开始任务中的tick设置,以及
OSTimeTick()
void ARMTargetStart(void)
{
RequestSystemTimer();
InstallSystemTimer(); //就是开了全局和T0中断
}
void RequestSystemTimer(void)
{
pISR_TIMER0= (unsigned)Timer0_Exception;
}
void Timer0_Exception(void)
{
rI_ISPC=BIT_TIMER0;
OSTimeTick();
}
就是把OSTimeTick()放进了T0的ISR里,每20ms执行一次. void OSTimeTick (void)
{
if (OSRunning == TRUE) {
ptcb = OSTCBList;
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) //依次检索所有的TCB,直到空闲任务
{
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) {//若这个TCB的dly值不为0则:
if (--ptcb->OSTCBDly == 0) {//dly自减,若为1则检索下个TCB,若为0则:
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {
//若TCB的等待状态为:就绪则:
OSRdyGrp|= ptcb->OSTCBBitY; //rdy组里增加这个TCB
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;//rdy表里增加..
}
else {
ptcb->OSTCBDly = 1; //若状态为未就绪,则在DLY值里写1
}
}
}
ptcb = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
}
}
}
中断的过程
在中断发生时,并不是像以前那样直接运行ISRIRQ,在启动代码里改了:
ldr r0,=HandleIRQ
ldr r1,=OSIRQISR
str r1,[r0]
OSIRQISR函数会在一系列的stack周转后,比较intnesting的值,若非1,我看不懂下面的汇编代码……若1,跳入ISRIRQ,然后跳入OSIntExit(退出系统中断函数,内容为:OSINTNESTING减1.若为0且当前任务不是最高优先级,则调用中断级调度OSIntCtxSw(),
将PC弹栈离开ISR)。若没有在上述过程离开ISR(即没有调度),则再计算intnesting,若0,则再一系列的STACK周转后把PC弹栈.若1,下面的汇编代码我仍看不懂..
3(OSInit(),MAIN()中的OS初始化,包括全局变量们,rdy
表,TCB表,EVENT表,以及建立IDLE和STAT任务
void OSInit (void)
{
OS_InitMisc();
OS_InitRdyList();
OS_InitTCBList();
OS_InitEventList();
OS_FlagInit();
OS_MemInit();
OS_QInit();
OS_InitTaskIdle();
OS_InitTaskStat();
}
大体过程和初始化的全局变量如下:
OSIntNesting = 0;
OSLockNesting = 0;
OSTaskCtr = 0;
OSRunning = FALSE;
OSCtxSwCtr = 0;
OSIdleCtr = 0L;
OSIdleCtrRun = 0L;
OSIdleCtrMax = 0L;
OSStatRdy = FALSE;
OSRdyGrp = 0x00;
prdytbl = &OSRdyTbl[0];
for (i = 0; i < OS_RDY_TBL_SIZE; i++) {
*prdytbl++ = 0x00;
}
OSPrioCur = 0;
OSPrioHighRdy = 0;
OSTCBHighRdy = (OS_TCB *)0;
OSTCBCur = (OS_TCB *)0;
OS_InitTCBList()
(void)memset(&OSTCBTbl[0], 0, sizeof(OSTCBTbl)); //OSTCBTBL为OSTCB类型数组 OS_TCB OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS].
(void)memset(&OSTCBPrioTbl[0], 0, sizeof(OSTCBPrioTbl)); //OSTCBPRIOTBL为指针数组 OS_TCB *OSTCBPrioTbl[OS_LOWEST_PRIO + 1]
ptcb1 = &OSTCBTbl[0];
ptcb2 = &OSTCBTbl[1];
for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {
ptcb1->OSTCBNext = ptcb2;
ptcb1++;
ptcb2++;
}//OSTCBTBL元素穿成单向链表
ptcb1->OSTCBNext = (OS_TCB *)0;
OSTCBList = (OS_TCB *)0;
OSTCBFreeList = &OSTCBTbl[0];
OS_InitEventList()
(void)memset(&OSEventTbl[0], 0, sizeof(OSEventTbl));
pevent1 = &OSEventTbl[0];
pevent2 = &OSEventTbl[1];
for (i = 0; i < (OS_MAX_EVENTS - 1); i++) {
pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent1->OSEventPtr = pevent2;
pevent1++;
pevent2++;
}
pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent1->OSEventPtr = (OS_EVENT *)0;
OSEventFreeList = &OSEventTbl[0];
OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED;
OSEventFreeList->OSEventPtr = (OS_EVENT *)0;
4(OSStart(),MAIN()中建立第一个任务后,开始操作系统
void OSStart (void)
{
INT8U y;
INT8U x;
if (OSRunning == FALSE) {
y = OSUnMapTbl[OSRdyGrp];
x = OSUnMapTbl[OSRdyTbl[y]];
OSPrioHighRdy = (INT8U)((y << 3) + x);
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy();
}
}
给四个指示当前和最高的PRIO和TCB的全局变量赋值,并运行OSStartHighRdy()函数
(大体内容为将OSRunning置一并调度)
二.任务的建立 OSTaskCreate(StartTask,(void *)0,&StartTaskStk[STACKSIZE-1],0);这是开始任务
1(OSTaskCreate()以及其中的STK和TCB初始化函数
OSTaskCreate():在TCBPRIO表中占位,初始化堆栈和TCB,若OS已运行则调度.
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
OS_STK *psp;
INT8U err;
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) {
OSTCBPrioTbl[prio] = (OS_TCB *)1;
OS_EXIT_CRITICAL();
psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); //初始化堆栈,获得堆栈指针
err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);//初始化TCB
这两个函数将传递的参数计入STACK和TCB,并初始化之.
if (err == OS_NO_ERR) {
OS_ENTER_CRITICAL();
OSTaskCtr++;
OS_EXIT_CRITICAL();
if (OSRunning == TRUE) {
OS_Sched();
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0;
OS_EXIT_CRITICAL();
}
return (err);
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
OSTaskStkInit(),在MAIN文件一开始,就声明了所有任务的STK(512B).这里传递的是这个任务的STK的最高字节,即满递减堆栈的栈底.堆栈在初始化时,存入所有REG和CPSR
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
OS_STK *stk;
opt = opt;
stk = ptos;
*--stk = (OS_STK) task; /* pc */
*--stk = (OS_STK) task; /* lr */
--stk = 0; /* r12 */ *
*--stk = 0; /* r11 */
*--stk = 0; /* r10 */
*--stk = 0; /* r9 */
*--stk = 0; /* r8 */
*--stk = 0; /* r7 */
*--stk = 0; /* r6 */
*--stk = 0; /* r5 */
*--stk = 0; /* r4 */
*--stk = 0; /* r3 */
*--stk = 0; /* r2 */
*--stk = 0; /* r1 */
*--stk = (unsigned int) pdata; /* r0,用以传递第一个参数 */
*--stk = (USER_USING_MODE|0x00); /* cpsr */
return (stk);
}
OS_TCBInit(),从OSTCBFreeList单向链表中申请TCB并写入SP,PRIO,STAT,DLY和TCB索引值XY,加入OSTCBList双向链表首.并在全局变量PRIO表和RDY表中写入此TCB
INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U
stk_size, void *pext, INT16U opt)
{
OS_ENTER_CRITICAL();
ptcb = OSTCBFreeList;
if (ptcb != (OS_TCB *)0) {
OSTCBFreeList = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
ptcb->OSTCBStkPtr = ptos;
ptcb->OSTCBPrio = (INT8U)prio;
ptcb->OSTCBStat = OS_STAT_RDY;
ptcb->OSTCBDly = 0;
ptcb->OSTCBY = prio >> 3;
ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX = prio & 0x07;
ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
#if OS_EVENT_EN > 0
ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on
an event */
#endif
#if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0))
ptcb->OSTCBMsg = (void *)0; /* No message received
*/
#endif
OS_EXIT_CRITICAL();
OSTCBPrioTbl[prio] = ptcb;
ptcb->OSTCBNext = OSTCBList;
ptcb->OSTCBPrev = (OS_TCB *)0;
if (OSTCBList != (OS_TCB *)0) {
OSTCBList->OSTCBPrev = ptcb;
}
OSTCBList = ptcb;
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_NO_MORE_TCB);
}
2(开始任务StartTask()
开始任务的建立在OSINIT()后,在OSSTART()之前,此时OSRunning并未置一,所以其不占据TCBPRIO表的位置.
int Main(int argc, char **argv)
{
ARMTargetInit();
OSInit();
Sem_F=OSFlagCreate(0,&err);
OSTaskCreate(StartTask,(void *)0,&StartTaskStk[STACKSIZE-1],0);
OSStart();
return 0;
}
开始任务中,打开中断,使能TICK,建立其他的任务,并将自己删除.这个任务在OS运行时是不允许进入的,因为其不占据TCBPRIO表的位置. void StartTask(void *pdata)
{
pdata=pdata;
ARMTargetStart();
OSTaskCreate(Led1Task,(void *)s1,&Led1TaskStk[STACKSIZE-1],3);
OSTaskCreate(Led2Task,(void *)s2,&Led2TaskStk[STACKSIZE-1],4);
OSTaskCreate(Led3Task,(void *)s3,&Led3TaskStk[STACKSIZE-1],5);
do{
OSTaskDel(0);
}while(1);
}
3(其他任务
可见正常任务与开始任务不同的是,这是个死循环,并且每个循环中总会将自己dly一段时间
void Led1Task(void *pdata)
{
for(;;)
{
OSFlagPend(Sem_F,(OS_FLAGS)3,OS_FLAG_WAIT_SET_ALL,0,&err);
rPDATC=0x02;
Uart_Printf(pdata);
OSTimeDlyHMSM(0,0,1,0);
}
}
三.标志组
1(早在MAIN文件声明变量时,就声明了这个标志组: OS_FLAG_GRP *Sem_F;
typedef struct {
INT8U OSFlagType;
void *OSFlagWaitList;
//指向等待表首,这个双向链表穿起了和这个FLAG相关的所有NODE
OS_FLAGS OSFlagFlags;
} OS_FLAG_GRP; .
2。在MAIN()中,使Sem_F=OSFlagCreate(0,&err); OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, INT8U *err) {
OS_FLAG_GRP *pgrp;
if (OSIntNesting > 0) {
*err = OS_ERR_CREATE_ISR;
return ((OS_FLAG_GRP *)0);
} //是不能在ISR中建立标志组的
OS_ENTER_CRITICAL();
pgrp = OSFlagFreeList; //从FREELIST里申请一个FLAG
if (pgrp != (OS_FLAG_GRP *)0) {
OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList;
pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; //初始化PGRP->TYPE
pgrp->OSFlagFlags = flags; //初始化PGRP->FLAG
pgrp->OSFlagWaitList = (void *)0; //初始化PGRP->等代表为(void*)0
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
} else {
OS_EXIT_CRITICAL();
*err = OS_FLAG_GRP_DEPLETED;
}
return (pgrp);
}
3(调用OSFlagPend(Sem_F,(OS_FLAGS)0x11,OS_FLAG_WAIT_SET_ALL,0,&err);来等待标志….在每次调用FLAGPEND时,若因未满足标志要求而陷入等待态,都会在当前任务堆栈里建立一个OS_FLAG_NODE结构,来保存TCB和等待的标志的信息..这个结构会加入pgrp->OSFlagWaitList双向链表首….在超时返回或满足返回后,会删除这个结构.因为结构是在任务堆栈中分配空间,因此会自动消失,空间会返回给堆栈,所以对于任务来说,他根本不知道这个OS_FLAG_NODE结构的存在.
PEND类型可为SETALL,SETANY,CLRALL,CLRANY
typedef struct {
void *OSFlagNodeNext; //等待表中下一个节点
void *OSFlagNodePrev; //等待表中上一个节点
void *OSFlagNodeTCB; //指向等待任务的TCB
void *OSFlagNodeFlagGrp; //指向事件标志组
OS_FLAGS OSFlagNodeFlags; //指向要等待的标志
INT8U OSFlagNodeWaitType; //等待种类:SETALL,SETANY,CLRALL,CLRANY
} OS_FLAG_NODE;
OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type,
INT16U timeout, INT8U *err)
{
OS_FLAG_NODE node;
OS_FLAGS flags_cur;
OS_FLAGS flags_rdy;
BOOLEAN consume;
if (OSIntNesting > 0) {
*err = OS_ERR_PEND_ISR;
return ((OS_FLAGS)0);
}
if (wait_type & OS_FLAG_CONSUME) {
wait_type &= ~OS_FLAG_CONSUME;
consume = TRUE;
} else consume = FALSE;//是否要求恢复标志,若是,则将consume置一
OS_ENTER_CRITICAL();
switch (wait_type) {
case OS_FLAG_WAIT_SET_ALL:
flags_rdy = pgrp->OSFlagFlags & flags;//分离出需要的位
if (flags_rdy == flags) { //若满足SETALL
if (consume == TRUE) {
pgrp->OSFlagFlags &= ~flags_rdy;//若要求恢复,就清除那几个位
}
flags_cur = pgrp->OSFlagFlags;//返回当前的FLAG位
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (flags_cur);
} else { //若不满足SETALL,将TCB加入等待链表
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);//
OS_EXIT_CRITICAL();
}
break;
case OS_FLAG_WAIT_SET_ANY:
flags_rdy = pgrp->OSFlagFlags & flags;
if (flags_rdy != (OS_FLAGS)0) { //满足SETANY
if (consume == TRUE) {
pgrp->OSFlagFlags &= ~flags_rdy; //若要求恢复,就清除那几个位
}
flags_cur = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (flags_cur);
} else {
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
case OS_FLAG_WAIT_CLR_ALL:
flags_rdy = ~pgrp->OSFlagFlags & flags;//分离出需要的位,将这些位取反
if (flags_rdy == flags) {
if (consume == TRUE) {
pgrp->OSFlagFlags |= flags_rdy; //若要求恢复,就置位那几个位
}
flags_cur = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (flags_cur);
} else {
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
case OS_FLAG_WAIT_CLR_ANY:
flags_rdy = ~pgrp->OSFlagFlags & flags;
if (flags_rdy != (OS_FLAGS)0) {
if (consume == TRUE) {
pgrp->OSFlagFlags |= flags_rdy;
}
flags_cur = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (flags_cur);
} else {
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
default: //其他情况返回错误信息:错误的类型
OS_EXIT_CRITICAL();
flags_cur = (OS_FLAGS)0;
*err = OS_FLAG_ERR_WAIT_TYPE;
return (flags_cur);
}
OS_Sched(); //调度!!下面的情况是超时返回或满足条件返回
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBStat & OS_STAT_FLAG) {//若等待标志还置位着(即超时返回)
OS_FlagUnlink(&node); //则从等待链表去除
OSTCBCur->OSTCBStat = OS_STAT_RDY;
OS_EXIT_CRITICAL();
flags_cur = (OS_FLAGS)0;
*err = OS_TIMEOUT; //返回超时信息
} else {
if (consume == TRUE) {
switch (wait_type) {
case OS_FLAG_WAIT_SET_ALL:
case OS_FLAG_WAIT_SET_ANY:
pgrp->OSFlagFlags &= ~OSTCBCur->OSTCBFlagsRdy;
break;
case OS_FLAG_WAIT_CLR_ALL:
case OS_FLAG_WAIT_CLR_ANY:
pgrp->OSFlagFlags |= OSTCBCur->OSTCBFlagsRdy;
break;
default:
OS_EXIT_CRITICAL();
*err = OS_FLAG_ERR_WAIT_TYPE;
return ((OS_FLAGS)0);
}
}
flags_cur = pgrp->OSFlagFlags; //返回值为当前FLAG
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
}
return (flags_cur);
}
static void OS_FlagBlock (OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS
flags, INT8U wait_type, INT16U timeout)
这个函数,将参数的node加入pgrp->OSFlagWaitList双向链表首,在OSTCBCur->OSTCBFlagNode中写入NODE的指针, 并从rdy表去除当前TCB
OS_FlagUnlink (OS_FLAG_NODE *pnode)
这个函数,将参数的node从pgrp->OSFlagWaitList双向链表去除,并由NODE的*OSFlagNodeTCB成员找到这个TCB,从ptcb->OSTCBFlagNode中去除这个NODE
.4. 调用OSFlagPost(Sem_F,(OS_FLAGS)2,OS_FLAG_SET,&err)
POST类型可为SET和CLR
OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err)
{
OS_FLAG_NODE *pnode;
BOOLEAN sched;
OS_FLAGS flags_cur;
OS_FLAGS flags_rdy;
BOOLEAN rdy;
OS_ENTER_CRITICAL();
switch (opt) { //先根据POST类型修改FLAG
case OS_FLAG_CLR:
pgrp->OSFlagFlags &= ~flags;
break;
case OS_FLAG_SET:
pgrp->OSFlagFlags |= flags;
break;
default:
OS_EXIT_CRITICAL();
*err = OS_FLAG_INVALID_OPT;
return ((OS_FLAGS)0);
}
sched = FALSE;
pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;//找到等待表
while (pnode != (OS_FLAG_NODE *)0) { //遍历等待表以查看是否已满足
switch (pnode->OSFlagNodeWaitType) {
case OS_FLAG_WAIT_SET_ALL:
flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;//分离
if (flags_rdy == pnode->OSFlagNodeFlags) { //全置位
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == TRUE) { //若rdy表发生过改变,则将sched置一
sched = TRUE;
}
}
break;
case OS_FLAG_WAIT_SET_ANY:
flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
if (flags_rdy != (OS_FLAGS)0) {
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == TRUE) {
sched = TRUE;
}
}
break;
case OS_FLAG_WAIT_CLR_ALL:
flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
if (flags_rdy == pnode->OSFlagNodeFlags) {
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == TRUE) {
sched = TRUE;
}
}
break;
case OS_FLAG_WAIT_CLR_ANY:
flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
if (flags_rdy != (OS_FLAGS)0) {
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == TRUE) {
sched = TRUE;
}
}
break;
default:
OS_EXIT_CRITICAL();
*err = OS_FLAG_ERR_WAIT_TYPE;
return ((OS_FLAGS)0);
}
pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
}
OS_EXIT_CRITICAL();
if (sched == TRUE) {
OS_Sched(); //若sched置一,则调度
}
OS_ENTER_CRITICAL();
flags_cur = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (flags_cur);
}
bolean OS_FlagTaskRdy (OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy)
这个函数, 由NODE的*OSFlagNodeTCB成员找到这个TCB,将其加入rdy表,并调用
OS_FlagUnlink (OS_FLAG_NODE *pnode)
本文档为【s3c44b0移植ucos的一个实例[最新]】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。