Published 03 Dec 2010, by
Eric Ebert
CoOS,
rtos
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <coocox.h>
00019
00020
00021
00022
00023 OSTCB TCBTbl [CFG_MAX_USER_TASKS +SYS_TASK_NUM ] = {{0}};
00024
00025
00026 OS_STK idle_stk[CFG_IDLE_STACK_SIZE ] = {0};
00027
00028 P_OSTCB FreeTCB = 0;
00029 P_OSTCB TCBRdy = 0;
00030 P_OSTCB TCBNext = 0;
00031 P_OSTCB TCBRunning = 0;
00032 U64 OSCheckTime = 0;
00033
00034 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00035 OS_TID PriNum;
00036 U8 ActivePri[CFG_MAX_USER_TASKS +SYS_TASK_NUM ];
00037 U8 TaskNumPerPri[CFG_MAX_USER_TASKS +SYS_TASK_NUM ];
00038 OS_TID RdyTaskPri[CFG_MAX_USER_TASKS +SYS_TASK_NUM ] = {0};
00039 U32 RdyTaskPriInfo[(CFG_MAX_USER_TASKS +SYS_TASK_NUM +31)/32];
00040 #endif
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 void CreateTCBList(void)
00056 {
00057 U8 i;
00058 P_OSTCB ptcb1,ptcb2;
00059
00060 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00061 PriNum = 0;
00062 #endif
00063
00064 ptcb1 = &TCBTbl[0];
00065 ptcb2 = &TCBTbl[1];
00066 for(i=0;i< (CFG_MAX_USER_TASKS +SYS_TASK_NUM -1);i++ )
00067 {
00068 ptcb1->taskID = i;
00069 ptcb1->state = TASK_DORMANT ;
00070 ptcb1->TCBnext = ptcb2;
00071 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00072 RdyTaskPri[i] = INVALID_ID;
00073 ActivePri[i] = INVALID_ID;
00074 #endif
00075 ptcb1++;
00076 ptcb2++;
00077 }
00078 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00079 ActivePri[i] = INVALID_ID;
00080 #endif
00081
00082 ptcb1->taskID = i;
00083 ptcb1->TCBnext = 0;
00084 FreeTCB = &TCBTbl[0];
00085 }
00086
00087
00088
00089 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 static BOOL GetPriSeqNum(U8 pri,OS_TID* SequenceNum)
00105 {
00106 OS_TID seqNum;
00107 OS_TID num,tmpNum;
00108 num = 0;
00109 seqNum = PriNum;
00110 while(num != seqNum)
00111 {
00112 tmpNum = num;
00113 num = (num+seqNum)/2;
00114 if(pri == ActivePri[num])
00115 {
00116 *SequenceNum = num;
00117 return TRUE;
00118 }
00119 else if (pri < ActivePri[num])
00120 {
00121 seqNum = num;
00122 num = tmpNum;
00123 }
00124 else
00125 {
00126 num++;
00127 }
00128 }
00129 *SequenceNum = num;
00130 return FALSE;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 static U8 GetRdyPriSeqNum(U8 seqNum)
00148 {
00149 U32 tmp;
00150 U8 i,j,num;
00151 S8 cnt;
00152 i = seqNum/32;
00153 j = seqNum%32;
00154
00155 do
00156 {
00157 tmp = RdyTaskPriInfo[i];
00158 if(tmp != 0)
00159 {
00160 num = j/8;
00161 do
00162 {
00163 if((tmp&(0xff<<(num*8))) !=0 )
00164 {
00165 if((tmp&(0xf0<<(num*8))) !=0)
00166 {
00167 for(cnt=j; cnt >=(num*8+4); cnt--)
00168 {
00169 if( (tmp&(1<<cnt)) !=0)
00170 {
00171 return (32*i+cnt);
00172 }
00173 }
00174 }
00175
00176 if((j&0x4)==4)
00177 j = (j|0x3) -4;
00178
00179 for(cnt=j; cnt >=num*8; cnt--)
00180 {
00181 if( (tmp&(1<<cnt)) !=0)
00182 {
00183 return (32*i+cnt);
00184 }
00185 }
00186 }
00187 j = num*8 -1;
00188 }while((num--)!=0);
00189 }
00190 j=31;
00191 }while((i--)!=0);
00192 return INVALID_ID;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 static void PrioRemap(OS_TID seqNum)
00209 {
00210 U8 i,j;
00211 U32 tmp;
00212 tmp = j = 0;
00213 j = seqNum/32;
00214 for(i=0;i<seqNum%32;i++)
00215 {
00216 tmp |= 1<<i;
00217 }
00218 tmp &= RdyTaskPriInfo[j];
00219
00220 for(i=seqNum; i<PriNum; i++)
00221 {
00222 if((i%32==0)&&(i!=seqNum))
00223 {
00224 RdyTaskPriInfo[j++] = tmp;
00225 tmp = 0;
00226 }
00227 if(RdyTaskPri[i] != INVALID_ID)
00228 {
00229 tmp = tmp | (1<<(i%32));
00230 }
00231 }
00232 RdyTaskPriInfo[j++] = tmp;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 static BOOL GetPrioSeqNumStatus(U8 seqNum)
00250 {
00251 if( (RdyTaskPriInfo[seqNum/32] & (1<<(seqNum%32))) == 0)
00252 {
00253 return FALSE;
00254 }
00255 return TRUE;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 static void SetPrioSeqNumStatus(U8 seqNum, BOOL isRdy)
00273 {
00274 U32 tmp;
00275 tmp = RdyTaskPriInfo[seqNum/32];
00276 tmp &= ~(1<<(seqNum%32));
00277 tmp |= isRdy<<(seqNum%32);
00278 RdyTaskPriInfo[seqNum/32] = tmp;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 void ActiveTaskPri(U8 pri)
00297 {
00298 OS_TID seqNum,num;
00299 if(GetPriSeqNum(pri,&seqNum) == FALSE)
00300 {
00301 for(num=PriNum;num>seqNum;num--)
00302 {
00303 ActivePri[num] = ActivePri[num-1];
00304 TaskNumPerPri[num] = TaskNumPerPri[num-1];
00305 RdyTaskPri[num] = RdyTaskPri[num-1];
00306 }
00307 ActivePri[seqNum] = pri;
00308 TaskNumPerPri[seqNum] = 1;
00309 RdyTaskPri[seqNum] = INVALID_ID;
00310 PriNum++;
00311 PrioRemap(seqNum);
00312 }
00313 else
00314 {
00315 TaskNumPerPri[seqNum]++;
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void DeleteTaskPri(U8 pri)
00336 {
00337 OS_TID seqNum,num;
00338
00339 GetPriSeqNum(pri,&seqNum);
00340 TaskNumPerPri[seqNum]--;
00341 if(TaskNumPerPri[seqNum]==0)
00342 {
00343 for(num=seqNum; num<(PriNum-1); num++)
00344 {
00345 ActivePri[num] = ActivePri[num+1];
00346 TaskNumPerPri[num] = TaskNumPerPri[num+1];
00347 RdyTaskPri[num] = RdyTaskPri[num+1];
00348 }
00349 PriNum--;
00350 PrioRemap(seqNum);
00351 }
00352 }
00353
00354 #endif
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 void InsertToTCBRdyList(P_OSTCB tcbInsert)
00369 {
00370 P_OSTCB ptcbNext,ptcb;
00371 U8 prio;
00372 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00373 U8 seqNum;
00374 U8 RdyTaskSeqNum;
00375 #endif
00376
00377 prio = tcbInsert->prio ;
00378 tcbInsert->state = TASK_READY ;
00379
00380 #if CFG_ROBIN_EN >0
00381 ptcb = TCBRunning ;
00382
00383 if(prio == ptcb->prio )
00384 {
00385 if(ptcb != tcbInsert)
00386 {
00387 if(ptcb != 0)
00388 {
00389 if(OSCheckTime < OSTickCnt )
00390 {
00391 OSCheckTime = OSTickCnt + ptcb->timeSlice;
00392 }
00393 }
00394 }
00395 }
00396 #endif
00397
00398
00399 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00400 GetPriSeqNum(prio,&seqNum);
00401 if(GetPrioSeqNumStatus(seqNum) == TRUE)
00402 {
00403 ptcb = &TCBTbl[RdyTaskPri[seqNum]];
00404 RdyTaskPri[seqNum] = tcbInsert->taskID ;
00405 }
00406 else
00407 {
00408 RdyTaskPri[seqNum] = tcbInsert->taskID ;
00409 RdyTaskSeqNum = GetRdyPriSeqNum(seqNum);
00410 SetPrioSeqNumStatus(seqNum, 1);
00411 if(RdyTaskSeqNum == INVALID_ID)
00412 {
00413 ptcb = TCBRdy ;
00414 TaskSchedReq = TRUE;
00415 if(ptcb == 0)
00416 {
00417 TCBRdy = tcbInsert;
00418 }
00419 else
00420 {
00421 tcbInsert->TCBnext = ptcb;
00422 ptcb->TCBprev = tcbInsert;
00423 TCBRdy = tcbInsert;
00424 }
00425 return;
00426 }
00427 else
00428 {
00429 ptcb = &TCBTbl[RdyTaskPri[RdyTaskSeqNum]];
00430 }
00431 }
00432
00433 ptcbNext = ptcb->TCBnext ;
00434 tcbInsert->TCBnext = ptcbNext;
00435 ptcb->TCBnext = tcbInsert;
00436 tcbInsert->TCBprev = ptcb;
00437 if(ptcbNext != 0)
00438 {
00439 ptcbNext->TCBprev = tcbInsert;
00440 }
00441
00442
00443 #else
00444 ptcb = TCBRdy ;
00445 if (ptcb == 0)
00446 {
00447 TaskSchedReq = TRUE;
00448 TCBRdy = tcbInsert;
00449 }
00450 else if (prio < ptcb->prio)
00451 {
00452 TaskSchedReq = TRUE;
00453 tcbInsert->TCBnext = ptcb;
00454 ptcb->TCBprev = tcbInsert;
00455 TCBRdy = tcbInsert;
00456 }
00457 else
00458 {
00459 ptcbNext = ptcb->TCBnext ;
00460 while(ptcbNext != 0)
00461 {
00462 if(prio < ptcbNext->prio)
00463 break;
00464 ptcb = ptcbNext;
00465 ptcbNext = ptcbNext->TCBnext ;
00466 }
00467 tcbInsert->TCBnext = ptcbNext;
00468 ptcb->TCBnext = tcbInsert;
00469 tcbInsert->TCBprev = ptcb;
00470 if(ptcbNext != 0)
00471 {
00472 ptcbNext->TCBprev = tcbInsert;
00473 }
00474 }
00475 #endif
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 void RemoveFromTCBRdyList(P_OSTCB ptcb)
00492 {
00493
00494 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00495 U8 prio;
00496 U8 seqNum;
00497 BOOL isChange;
00498 isChange = FALSE;
00499 prio = ptcb->prio ;
00500 GetPriSeqNum(prio,&seqNum);
00501 #endif
00502
00503
00504 if((ptcb->TCBnext == 0) && (ptcb->TCBprev == 0) )
00505 {
00506 TCBRdy = 0;
00507 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00508 isChange = TRUE;
00509 #endif
00510 }
00511 else if(ptcb->TCBprev == 0)
00512 {
00513
00514 TCBRdy = ptcb->TCBnext ;
00515 ptcb->TCBnext = 0;
00516 TCBRdy->TCBprev = 0;
00517 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00518 if(TCBRdy->prio != prio)
00519 isChange = TRUE;
00520
00521 #endif
00522 }
00523 else if( ptcb->TCBnext == 0)
00524 {
00525 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00526 if(ptcb->TCBprev ->prio != prio)
00527 isChange = TRUE;
00528 else
00529 RdyTaskPri[seqNum] = ptcb->TCBprev ->taskID ;
00530 #endif
00531 ptcb->TCBprev ->TCBnext = 0;
00532 ptcb->TCBprev = 0;
00533 }
00534 else
00535 {
00536 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00537 if((ptcb->TCBprev ->prio != prio) && (ptcb->TCBnext ->prio != prio))
00538 isChange = TRUE;
00539 else if((ptcb->TCBprev ->prio == prio) && (ptcb->TCBnext ->prio != prio))
00540 RdyTaskPri[seqNum] = ptcb->TCBprev ->taskID ;
00541 #endif
00542 ptcb->TCBprev ->TCBnext = ptcb->TCBnext ;
00543 ptcb->TCBnext ->TCBprev = ptcb->TCBprev ;
00544 ptcb->TCBnext = 0;
00545 ptcb->TCBprev = 0;
00546 }
00547 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00548 if(isChange == TRUE)
00549 {
00550 RdyTaskPri[seqNum] = INVALID_ID;
00551 SetPrioSeqNumStatus(seqNum, 0);
00552 }
00553 #endif
00554 }
00555
00556
00557 #if CFG_MUTEX_EN > 0
00558 #define CFG_PRIORITY_SET_EN (1)
00559 #endif
00560 #if CFG_PRIORITY_SET_EN >0
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 StatusType CoSetPriority(OS_TID taskID,U8 priority)
00576 {
00577 P_OSTCB ptcb;
00578 #if CFG_MUTEX_EN >0
00579 U8 prio;
00580 P_MUTEX pMutex;
00581 #endif
00582 #if CFG_EVENT_EN >0
00583 P_ECB pecb;
00584 #endif
00585
00586 if(taskID == 0)
00587 {
00588 return E_PROTECTED_TASK;
00589 }
00590
00591 #if CFG_PAR_CHECKOUT_EN >0
00592 if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM )
00593 {
00594 return E_INVALID_ID;
00595 }
00596 #endif
00597 ptcb = &TCBTbl[taskID];
00598 #if CFG_PAR_CHECKOUT_EN >0
00599 if(ptcb->state == TASK_DORMANT )
00600 {
00601 return E_INVALID_ID;
00602 }
00603 if(priority > CFG_LOWEST_PRIO )
00604 {
00605 return E_INVALID_ID;
00606 }
00607 #endif
00608
00609 if(ptcb->prio != priority)
00610 {
00611 #if CFG_MUTEX_EN >0
00612 if(ptcb->mutexID != INVALID_ID)
00613 {
00614 pMutex = &MutexTbl[ptcb->mutexID];
00615 if(pMutex->taskID == ptcb->taskID )
00616 {
00617 pMutex->originalPrio= priority;
00618 if(ptcb->prio < priority)
00619 {
00620 return E_OK;
00621 }
00622 }
00623 }
00624
00625 #endif
00626
00627 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00628 DeleteTaskPri(ptcb->prio );
00629 ActiveTaskPri(priority);
00630 #endif
00631
00632 ptcb->prio = priority;
00633 if(ptcb->state == TASK_READY )
00634 {
00635 OsSchedLock ();
00636 RemoveFromTCBRdyList(ptcb);
00637 InsertToTCBRdyList(ptcb);
00638 OsSchedUnlock();
00639 }
00640 else if(ptcb->state == TASK_RUNNING )
00641 {
00642 if(ptcb->prio > TCBRdy->prio )
00643 {
00644 OsSchedLock ();
00645 TaskSchedReq = TRUE;
00646 OsSchedUnlock();
00647 }
00648 }
00649 else
00650 {
00651 #if CFG_MUTEX_EN >0
00652 if(ptcb->mutexID != INVALID_ID)
00653 {
00654
00655 OsSchedLock ();
00656 pMutex = &MutexTbl[ptcb->mutexID];
00657 ptcb = pMutex->waittingList;
00658 prio = pMutex->originalPrio;
00659 pMutex->hipriTaskID = pMutex->taskID ;
00660 while(ptcb != 0)
00661 {
00662 if(ptcb->prio < prio)
00663 {
00664 prio = ptcb->prio ;
00665 pMutex->hipriTaskID = ptcb->taskID ;
00666 }
00667 ptcb = ptcb->TCBnext ;
00668 }
00669 OsSchedUnlock();
00670 if(pMutex->originalPrio != prio)
00671 {
00672 CoSetPriority(pMutex->taskID,prio);
00673 }
00674 }
00675 #endif
00676
00677 #if CFG_EVENT_EN >0
00678 ptcb = &TCBTbl[taskID];
00679 if(ptcb->eventID != INVALID_ID)
00680 {
00681 pecb = &EventTbl [ptcb->eventID];
00682
00683
00684 if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
00685 {
00686
00687 RemoveEventWaittingList(ptcb);
00688 EventTaskToWait(pecb,ptcb);
00689 }
00690 }
00691 #endif
00692 }
00693 }
00694 return E_OK;
00695 }
00696 #endif
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 void Schedule(void)
00711 {
00712 U8 RunPrio,RdyPrio;
00713 P_OSTCB pRdyTcb,pCurTcb;
00714
00715
00716 pCurTcb = TCBRunning ;
00717 pRdyTcb = TCBRdy ;
00718
00719 if((pRdyTcb==0) || (pCurTcb != TCBNext) || (OSSchedLock >1) || (OSIntNesting >0))
00720 {
00721 return;
00722 }
00723
00724 TaskSchedReq = FALSE;
00725 RunPrio = pCurTcb->prio ;
00726 RdyPrio = pRdyTcb->prio ;
00727
00728
00729 if(pCurTcb->state != TASK_RUNNING )
00730 {
00731 TCBNext = pRdyTcb;
00732 pRdyTcb->state = TASK_RUNNING ;
00733 RemoveFromTCBRdyList(pRdyTcb);
00734 }
00735
00736 else if(RdyPrio < RunPrio )
00737 {
00738 TCBNext = pRdyTcb;
00739 InsertToTCBRdyList(pCurTcb);
00740 RemoveFromTCBRdyList(pRdyTcb);
00741 pRdyTcb->state = TASK_RUNNING ;
00742 }
00743
00744 #if CFG_ROBIN_EN >0
00745 else if((RunPrio == RdyPrio) && (OSCheckTime == OSTickCnt ))
00746 {
00747 TCBNext = pRdyTcb;
00748 InsertToTCBRdyList(pCurTcb);
00749 RemoveFromTCBRdyList(pRdyTcb);
00750 pRdyTcb->state = TASK_RUNNING ;
00751 }
00752 #endif
00753 else
00754 {
00755 return;
00756 }
00757
00758 #if CFG_ROBIN_EN >0
00759 if(TCBNext->prio == TCBRdy->prio )
00760 OSCheckTime = OSTickCnt + TCBNext->timeSlice;
00761 #endif
00762
00763
00764 #if CFG_STK_CHECKOUT_EN > 0
00765 if((pCurTcb->stkPtr < pCurTcb->stack)||(*(U32*)(pCurTcb->stack) != MAGIC_WORD))
00766 {
00767 CoStkOverflowHook(pCurTcb->taskID );
00768 }
00769 #endif
00770
00771 SwitchContext();
00772 }
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 static P_OSTCB AssignTCB(void)
00789 {
00790 P_OSTCB ptcb;
00791
00792 OsSchedLock ();
00793 if(FreeTCB == 0)
00794 {
00795 OsSchedUnlock();
00796 return 0;
00797 }
00798 ptcb = FreeTCB ;
00799
00800 FreeTCB = FreeTCB->TCBnext ;
00801 OsSchedUnlock();
00802 return ptcb;
00803 }
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 OS_TID CreateTask(FUNCPtr task,void *argv,U32 parameter,OS_STK *stk)
00823 {
00824 OS_STK* stkTopPtr;
00825 P_OSTCB ptcb;
00826 U8 prio;
00827 #if CFG_ROBIN_EN >0
00828 U16 timeSlice;
00829 #endif
00830
00831 #if CFG_STK_CHECKOUT_EN >0
00832 U16 sktSz;
00833 sktSz = (parameter&0xfff00)>>8;
00834 #endif
00835 prio = parameter&0xff;
00836
00837 #if CFG_PAR_CHECKOUT_EN >0
00838 if(task == 0)
00839 {
00840 return E_CREATE_FAIL;
00841 }
00842 if(stk == 0)
00843 {
00844 return E_CREATE_FAIL;
00845 }
00846 if(prio > CFG_LOWEST_PRIO )
00847 {
00848 return E_CREATE_FAIL;
00849 }
00850 #if CFG_STK_CHECKOUT_EN >0
00851 if(sktSz < 20)
00852 {
00853 return E_CREATE_FAIL;
00854 }
00855 #endif // CFG_STK_CHECKOUT_EN
00856 #endif // CFG_PAR_CHECKOUT_EN
00857
00858 #if CFG_TASK_SCHEDULE_EN == 0
00859 if(TCBRunning != 0)
00860 return E_CREATE_FAIL;
00861 #endif
00862
00863 stkTopPtr = InitTaskContext(task,argv,stk);
00864
00865 ptcb = AssignTCB();
00866
00867 if(ptcb == 0)
00868 {
00869 return E_CREATE_FAIL;
00870 }
00871
00872 ptcb->stkPtr = stkTopPtr;
00873 ptcb->prio = prio;
00874 #if CFG_STK_CHECKOUT_EN >0
00875 ptcb->stack = stk+1 - sktSz;
00876 *(U32*)(ptcb->stack) = MAGIC_WORD;
00877 #endif
00878
00879 #if CFG_TASK_WAITTING_EN >0
00880 ptcb->delayTick = INVALID_VALUE;
00881 #endif
00882
00883 #if CFG_TASK_SCHEDULE_EN == 0
00884 ptcb->taskFuc = task;
00885 ptcb->taskStk = stk;
00886 #endif
00887 ptcb->TCBnext = 0;
00888 ptcb->TCBprev = 0;
00889
00890 #if CFG_ROBIN_EN >0
00891 timeSlice = (parameter&0x7fff0000)>>20;
00892 if(timeSlice == 0)
00893 {
00894 timeSlice = CFG_TIME_SLICE;
00895 }
00896 ptcb->timeSlice = timeSlice;
00897 #endif
00898
00899 #if CFG_FLAG_EN > 0
00900 ptcb->pnode = 0;
00901 #endif
00902
00903 #if CFG_EVENT_EN > 0
00904 ptcb->eventID = INVALID_ID;
00905 ptcb->pmail = 0;
00906 ptcb->waitNext = 0;
00907 ptcb->waitPrev = 0;
00908 #endif
00909
00910 #if CFG_MUTEX_EN > 0
00911
00912 ptcb->mutexID = INVALID_ID;
00913 #endif
00914
00915 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
00916 ActiveTaskPri(prio);
00917 #endif
00918
00919 if((parameter>>31) == 0)
00920 {
00921 OsSchedLock ();
00922 InsertToTCBRdyList(ptcb);
00923 OsSchedUnlock();
00924 }
00925 else
00926 {
00927 ptcb->state = TASK_WAITING ;
00928 }
00929 return ptcb->taskID ;
00930 }
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 StatusType CoDelTask(OS_TID taskID)
00947 {
00948 P_OSTCB ptcb;
00949
00950 #if CFG_PAR_CHECKOUT_EN >0
00951 if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM )
00952 {
00953 return E_INVALID_ID;
00954 }
00955 #endif
00956 ptcb = &TCBTbl[taskID];
00957 #if CFG_PAR_CHECKOUT_EN >0
00958 if(ptcb->state == TASK_DORMANT )
00959 {
00960 return E_INVALID_ID;
00961 }
00962 #endif
00963 if(taskID == 0)
00964 {
00965 return E_PROTECTED_TASK;
00966 }
00967
00968 if(ptcb->state == TASK_RUNNING )
00969 {
00970 if(OSSchedLock != 0)
00971 {
00972 return E_OS_IN_LOCK;
00973 }
00974 }
00975
00976 #if CFG_MUTEX_EN >0
00977 if(ptcb->mutexID != INVALID_ID)
00978 {
00979 if(MutexTbl[ptcb->mutexID].taskID == ptcb->taskID )
00980 {
00981 CoLeaveMutexSection(ptcb->mutexID);
00982 }
00983 }
00984
00985 #endif
00986
00987 OsSchedLock ();
00988
00989 if(ptcb->state == TASK_READY )
00990 {
00991 RemoveFromTCBRdyList(ptcb);
00992 }
00993
00994 #if CFG_TASK_WAITTING_EN > 0
00995 else if(ptcb->state == TASK_WAITING )
00996 {
00997
00998 if(ptcb->delayTick != INVALID_VALUE)
00999 {
01000 RemoveDelayList(ptcb);
01001 }
01002
01003 #if CFG_EVENT_EN > 0
01004 if(ptcb->eventID != INVALID_ID)
01005 {
01006
01007 RemoveEventWaittingList(ptcb);
01008 }
01009 #endif
01010
01011 #if CFG_FLAG_EN > 0
01012 if(ptcb->pnode != 0)
01013 {
01014
01015 RemoveLinkNode((P_FLAG_NODE)ptcb->pnode);
01016 }
01017 #endif
01018
01019 #if CFG_MUTEX_EN >0
01020 if(ptcb->mutexID != INVALID_ID)
01021 {
01022 RemoveMutexList(ptcb);
01023 }
01024 #endif
01025 }
01026 #endif
01027 ptcb->state = TASK_DORMANT ;
01028 TaskSchedReq = TRUE;
01029
01030 #if CFG_ORDER_LIST_SCHEDULE_EN ==0
01031 DeleteTaskPri(ptcb->prio );
01032 #endif
01033
01034 #if CFG_TASK_SCHEDULE_EN >0
01035 ptcb->TCBnext = FreeTCB ;
01036 FreeTCB = ptcb;
01037 #endif
01038 OsSchedUnlock();
01039 return E_OK;
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 void CoExitTask(void)
01055 {
01056 CoDelTask(TCBRunning->taskID );
01057 }
01058
01059
01060 #if CFG_TASK_SCHEDULE_EN ==0
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 StatusType CoActivateTask(OS_TID taskID,void *argv)
01075 {
01076 P_OSTCB ptcb;
01077 OS_STK* stkTopPtr;
01078 #if CFG_PAR_CHECKOUT_EN >0
01079 if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM )
01080 {
01081 return E_INVALID_ID;
01082 }
01083 #endif
01084 ptcb = &TCBTbl[taskID];
01085 #if CFG_PAR_CHECKOUT_EN >0
01086 if(ptcb->stkPtr == 0)
01087 return E_INVALID_ID;
01088 #endif
01089 if(ptcb->state != TASK_DORMANT )
01090 return E_OK;
01091
01092
01093
01094 stkTopPtr = InitTaskContext(ptcb->taskFuc,argv,ptcb->taskStk);
01095
01096 ptcb->stkPtr = stkTopPtr;
01097 OsSchedLock ();
01098 InsertToTCBRdyList(ptcb);
01099 OsSchedUnlock();
01100 return E_OK;
01101 }
01102 #endif
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 OS_TID CoGetCurTaskID(void)
01117 {
01118 return (TCBRunning->taskID );
01119 }
01120
01121 #if CFG_TASK_SUSPEND_EN >0
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137 StatusType CoSuspendTask(OS_TID taskID)
01138 {
01139 P_OSTCB ptcb;
01140
01141 if(taskID == 0)
01142 {
01143 return E_PROTECTED_TASK;
01144 }
01145 #if CFG_PAR_CHECKOUT_EN >0
01146 if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM )
01147 {
01148 return E_INVALID_ID;
01149 }
01150 #endif
01151 ptcb = &TCBTbl[taskID];
01152 #if CFG_PAR_CHECKOUT_EN >0
01153 if(ptcb->state == TASK_DORMANT )
01154 {
01155 return E_INVALID_ID;
01156 }
01157 #endif
01158 if(OSSchedLock != 0)
01159 {
01160 return E_OS_IN_LOCK;
01161 }
01162 if(ptcb->state == TASK_WAITING )
01163 {
01164 return E_ALREADY_IN_WAITING;
01165 }
01166
01167 OsSchedLock ();
01168 if(ptcb != TCBRunning)
01169 {
01170 RemoveFromTCBRdyList(ptcb);
01171 }
01172 else
01173 {
01174 TaskSchedReq = TRUE;
01175 }
01176
01177 ptcb->state = TASK_WAITING ;
01178 OsSchedUnlock();
01179 return E_OK;
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 StatusType CoAwakeTask(OS_TID taskID)
01199 {
01200 P_OSTCB ptcb;
01201
01202 if(taskID == 0)
01203 {
01204 return E_PROTECTED_TASK;
01205 }
01206 #if CFG_PAR_CHECKOUT_EN >0
01207 if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM )
01208 {
01209 return E_INVALID_ID;
01210 }
01211 #endif
01212 ptcb = &TCBTbl[taskID];
01213 #if CFG_PAR_CHECKOUT_EN >0
01214 if(ptcb->state == TASK_DORMANT )
01215 {
01216 return E_INVALID_ID;
01217 }
01218 #endif
01219
01220 if(ptcb->state != TASK_WAITING )
01221 {
01222 return E_TASK_NOT_WAITING;
01223 }
01224
01225 #if CFG_TASK_WAITTING_EN > 0
01226 if(ptcb->delayTick != INVALID_VALUE)
01227 {
01228 return E_TASK_WAIT_OTHER;
01229 }
01230
01231 #if CFG_FLAG_EN > 0
01232 if(ptcb->pnode != 0)
01233 {
01234 return E_TASK_WAIT_OTHER;
01235 }
01236 #endif
01237
01238 #if CFG_EVENT_EN>0
01239 if(ptcb->eventID != INVALID_ID)
01240 {
01241 return E_TASK_WAIT_OTHER;
01242 }
01243 #endif
01244
01245 #if CFG_MUTEX_EN > 0
01246 if(ptcb->mutexID != INVALID_ID)
01247 {
01248 return E_TASK_WAIT_OTHER;
01249 }
01250 #endif
01251
01252 #endif //CFG_TASK_WAITTING_EN
01253
01254
01255 OsSchedLock ();
01256 InsertToTCBRdyList(ptcb);
01257 OsSchedUnlock();
01258 return E_OK;
01259 }
01260 #endif