Embedded 版 (精华区)

发信人: Zinux (Linux技工), 信区: Embedded_system
标  题: ucos源码(c file)
发信站: 哈工大紫丁香 (2001年10月26日18:15:01 星期五), 站内信件


(本文转载自水木清精华区)
【 原文由 mot 所发表 】
/*
************************************************************************
****
******************************
*                                                 uC/OS
*                                          The Real-Time Kernel
*                                                 KERNEL
*
*                        (c) Copyright 1992-1995, Jean J. Labrosse, 
Plantati
on, FL
*                                           All Rights Reserved
*
*                                                  V1.08
*
* File : UCOS.C
* By   : Jean J. Labrosse
************************************************************************
****
************************************************************************
****
******************************
*/
#define  OS_GLOBALS
#include "INCLUDES.H"
/*
************************************************************************
****
******************************
*                                              CONSTANTS
************************************************************************
****
******************************
*/
#define  OS_LO_PRIO          63        /* IDLE task priority
                                       /* TASK STATUS
#define  OS_STAT_RDY       0x00        /* Ready to run
#define  OS_STAT_SEM       0x01        /* Pending on semaphore
#define  OS_STAT_MBOX      0x02        /* Pending on mailbox
#define  OS_STAT_Q         0x04        /* Pending on queue
#define  OS_STAT_SUSPEND   0x08        /* Task is suspended
/*$PAGE*/
/*
************************************************************************
****
******************************
******************************
*                              MAPPING TABLE TO MAP BIT POSITION TO 
BIT MASK

*
* Note: Index into table is desired bit position, 0..7
*       Indexed value corresponds to bit mask
************************************************************************
****
******************************
*/
UBYTE const OSMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 
0x80};

/*
************************************************************************
****
******************************
*                                       PRIORITY RESOLUTION TABLE
*
* Note: Index into table is bit pattern to resolve highest priority
*       Indexed value corresponds to highest priority bit position (i.e.
 0..
7)
************************************************************************
****
******************************
*/
UBYTE const OSUnMapTbl[] = {
UBYTE const OSUnMapTbl[] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                            LOCAL VARIABLES
*                                            LOCAL VARIABLES
************************************************************************
****
******************************
*/
static  OS_TCB     *OSTCBList;                 /* Pointer to doubly 
linked l
ist of TCBs                */
static  UBYTE       OSRdyGrp;                  /* Ready list group
static  UBYTE       OSRdyTbl[8];               /* Table of tasks which 
are r
eadyy to run                */
static  UBYTE       OSLockNesting;             /* Multitasking lock 
nesting
leveel                      */
static  OS_TCB     *OSTCBFreeList;             /* Pointer to list of 
free TC
Bs                         */
static  OS_EVENT   *OSEventFreeList;           /* Pointer to list of 
free EV
ENT control blocks         */
static  OS_Q       *OSQFreeList;               /* Pointer to list of 
free QU
EUE control blocks         */
static  ULONG       OSTime;                    /* Current value of 
system ti
me ((in ticks)              */
static  UBYTE       OSIntExitY;                /* Variable used by 
'OSIntExi
t' tto prevent using locals */
static  OS_STK_TYPE OSTaskIdleStk[OS_IDLE_TASK_STK_SIZE];  /* Idle 
task stac
k
k
static  OS_TCB      OSTCBTbl[OS_MAX_TASKS+1];              /* Table of 
TCBs
static  OS_EVENT    OSEventTbl[OS_MAX_EVENTS];             /* Table of 
EVENT
 conntrol blocks            */
static  OS_Q        OSQTbl[OS_MAX_QS];                     /* Table of 
QUEUE
 conntrol blocks            */
/*
************************************************************************
****
******************************
*                                       LOCAL FUNCTION PROTOTYPES
************************************************************************
****
******************************
*/
static  void OS_FAR OSTaskIdle(void *data);
static  void        OSDummy(void);
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                         uC/OS INITIALIZATION
************************************************************************
****
******************************
*/
*/
void OSInit(void)
{
    UBYTE i;
    OSTime        = 0L;
    OSTCBHighRdy  = (OS_TCB *)0;
    OSTCBCur      = (OS_TCB *)0;
    OSTCBList     = (OS_TCB *)0;
    OSIntNesting  = 0;
    OSLockNesting = 0;
    OSRunning     = FALSE;                                 /* Indicate 
that
multtitasking not started   */
    OSIdleCtr     = 0L;
    OSCtxSwCtr    = 0;
    OSRdyGrp      = 0;                                     /* Clear 
the read
y liist                     */
    for (i = 0; i < 8; i++) {
        OSRdyTbl[i] = 0;
    }
    for (i = 0; i < 64; i++) {                             /* Clear 
the prio
rityy table                 */
        OSTCBPrioTbl[i] = (OS_TCB *)0;
    }
    }
    for (i = 0; i < OS_MAX_TASKS; i++) {                   /* Init. list
 of
freee TCBs                  */
        OSTCBTbl[i].OSTCBNext = &OSTCBTbl[i+1];
    }
    OSTCBTbl[OS_MAX_TASKS].OSTCBNext = (OS_TCB *)0;        /* Last 
OS_TCB is
 forr OSTaskIdle()          */
    OSTCBFreeList                    = &OSTCBTbl[0];
    for (i = 0; i < (OS_MAX_EVENTS - 1); i++) {            /* Init. list
 of
freee EVENT control blocks  */
        OSEventTbl[i].OSEventPtr = &OSEventTbl[i+1];
    }
    OSEventTbl[OS_MAX_EVENTS - 1].OSEventPtr = (OS_EVENT *)0;
    OSEventFreeList                          = &OSEventTbl[0];
    for (i = 0; i < (OS_MAX_QS - 1); i++) {                /* Init. list
 of
freee QUEUE control blocks  */
        OSQTbl[i].OSQPtr = &OSQTbl[i+1];
    }
    OSQTbl[OS_MAX_QS - 1].OSQPtr = (OS_Q *)0;
    OSQFreeList                  = &OSQTbl[0];
    OSTaskCreate(OSTaskIdle, (void *)0, (void 
*)&OSTaskIdleStk[OS_IDLE_TASK_
STK__TOP], OS_LO_PRIO);
}
}
/*
************************************************************************
****
******************************
*                                              IDLE TASK
************************************************************************
****
******************************
*/
static void OS_FAR OSTaskIdle(void *data)
{
    data = data;
    while (1) {
        OS_ENTER_CRITICAL();
        OSIdleCtr++;
        OS_EXIT_CRITICAL();
    }
}
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                          START MULTITASKING
************************************************************************
****
************************************************************************
****
******************************
*/
void OSStart(void)
{
    UBYTE y;
    UBYTE x;
    UBYTE prio;
    y             = OSUnMapTbl[OSRdyGrp];        /* Find highest 
priority's
taskk priority number       */
    x             = OSUnMapTbl[OSRdyTbl[y]];
    prio          = (y << 3) + x;
    OSTCBHighRdy  = OSTCBPrioTbl[prio];          /* Point to highest 
priorit
y taask ready to run        */
    OSTCBCur      = OSTCBHighRdy;
    OSRunning     = TRUE;
    OSStartHighRdy();                            /* Execute target 
specific
codee to start task         */
}
/*
************************************************************************
****
******************************
*                                            uC/OS SCHEDULER
*                                            uC/OS SCHEDULER
************************************************************************
****
******************************
*/
void OSSched(void)
{
    UBYTE y;
    OS_ENTER_CRITICAL();
    if ((OSLockNesting | OSIntNesting) == 0) {   /* Task scheduling must
 be
enabbled and not ISR level  */
        y             = OSUnMapTbl[OSRdyGrp];    /* Get pointer to 
highest p
riorrity task ready to run  */
        OSTCBHighRdy  = OSTCBPrioTbl[(y << 3) + 
OSUnMapTbl[OSRdyTbl[y]]];
        if (OSTCBHighRdy != OSTCBCur) {          /* Make sure this is 
not th
e cuurrent task running     */
            OSCtxSwCtr++;                        /* Increment context 
switch
 couunter                   */
            OS_TASK_SW();                        /* Perform a context 
switch

        }
    }
    OS_EXIT_CRITICAL();
}
}
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                          PREVENT SCHEDULING
************************************************************************
****
******************************
*/
void OSSchedLock(void)
{
    if (OSRunning == TRUE) {                     /* Make sure 
multitasking i
s ruunning                  */
        OS_ENTER_CRITICAL();
        OSLockNesting++;                         /* Increment lock 
nesting l
evell                       */
        OS_EXIT_CRITICAL();
    }
}
/*
************************************************************************
****
******************************
*                                          ENABLE SCHEDULING
*                                          ENABLE SCHEDULING
************************************************************************
****
******************************
*/
void OSSchedUnlock(void)
{
    if (OSRunning == TRUE) {                           /* Make sure 
multitas
kingg is running            */
        OS_ENTER_CRITICAL();
        if (OSLockNesting != 0) {                      /* Do not 
decrement i
f allready 0                */
            OSLockNesting--;                           /* Decrement lock
 nes
tingg level                 */
            if ((OSLockNesting | OSIntNesting) == 0) { /* See if 
scheduling
re-eenabled and not an ISR  */
                OS_EXIT_CRITICAL();
                OSSched();                             /* See if a 
higher pr
ioriity task is ready       */
            } else {
                OS_EXIT_CRITICAL();
            }
        } else {
            OS_EXIT_CRITICAL();
            OS_EXIT_CRITICAL();
        }
    }
}
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                            INITIALIZE TCB
************************************************************************
****
******************************
*/
UBYTE OSTCBInit(UBYTE prio, void OS_FAR *stk)
{
    OS_TCB *ptcb;
    OS_ENTER_CRITICAL();
    ptcb = OSTCBFreeList;                                  /* Get a free
 TCB
 froom the free TCB list    */
    if (ptcb != (OS_TCB *)0) {
        OSTCBFreeList           = ptcb->OSTCBNext;         /* Update 
pointer
 to free TCB list          */
        OS_EXIT_CRITICAL();
        ptcb->OSTCBStkPtr       = stk;                     /* Load Stack
 poi
        ptcb->OSTCBStkPtr       = stk;                     /* Load Stack
 poi
nterr in TCB                */
        ptcb->OSTCBPrio         = (UBYTE)prio;             /* Load 
task prio
rityy into TCB              */
        ptcb->OSTCBStat         = OS_STAT_RDY;             /* Task is 
ready
to rrun                     */
        ptcb->OSTCBDly          = 0;
        ptcb->OSTCBDelReq       = OS_NO_ERR;
        ptcb->OSTCBY            = prio >> 3;
        ptcb->OSTCBBitY         = OSMapTbl[ptcb->OSTCBY];
        ptcb->OSTCBX            = prio & 0x07;
        ptcb->OSTCBBitX         = OSMapTbl[ptcb->OSTCBX];
        ptcb->OSTCBEventPtr     = (OS_EVENT *)0;           /* Task is 
not pe
ndinng on an event          */
        ptcb->OSTCBMsg          = (void *)0;               /* No message
 rec
eiveed                      */
        OS_ENTER_CRITICAL();
        OSTCBPrioTbl[prio]      = ptcb;
        ptcb->OSTCBNext         = OSTCBList;               /* Link 
into TCB
chaiin                      */
        ptcb->OSTCBPrev         = (OS_TCB *)0;
        if (OSTCBList != (OS_TCB *)0) {
            OSTCBList->OSTCBPrev = ptcb;
            OSTCBList->OSTCBPrev = ptcb;
        }
        OSTCBList               = ptcb;
        OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make 
task read
y too run                   */
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);
    } else {
        OS_EXIT_CRITICAL();
        return (OS_NO_MORE_TCB);
    }
}
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                               ENTER ISR
************************************************************************
****
******************************
*/
void OSIntEnter(void)
{
{
    OS_ENTER_CRITICAL();
    OSIntNesting++;                              /* Increment ISR 
nesting le
vel                        */
    OS_EXIT_CRITICAL();
}
/*
************************************************************************
****
******************************
*                                               EXIT ISR
************************************************************************
****
******************************
*/
void OSIntExit(void)
{
    OS_ENTER_CRITICAL();
    if ((--OSIntNesting | OSLockNesting) == 0) { /* Reschedule only if 
all I
SRs completed & not locked */
        OSIntExitY   = OSUnMapTbl[OSRdyGrp];
        OSTCBHighRdy = OSTCBPrioTbl[(OSIntExitY << 3) + 
OSUnMapTbl[OSRdyTbl[
OSInntExitY]]];
        if (OSTCBHighRdy != OSTCBCur) {          /* No context switch if
 cur
rentt task is highest ready */
rentt task is highest ready */
            OSCtxSwCtr++;
            OSIntCtxSw();                        /* Perform interrupt 
level
conttext switch             */
        }
    }
    OS_EXIT_CRITICAL();
}
/*$PAGE*/
#if OS_TASK_CHANGE_PRIO_EN
/*
************************************************************************
****
******************************
*                                       CHANGE PRIORITY OF A TASK
************************************************************************
****
******************************
*/
UBYTE OSTaskChangePrio(UBYTE oldprio, UBYTE newprio)
{
    OS_TCB   *ptcb;
    OS_EVENT *pevent;
    UBYTE     x;
    UBYTE     y;
    UBYTE     y;
    UBYTE     bitx;
    UBYTE     bity;
    if (oldprio >= OS_MAX_TASKS || newprio >= OS_MAX_TASKS) {
        return (OS_PRIO_INVALID);
    }
    OS_ENTER_CRITICAL();
    if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) {                 /* New 
prior
ity must not already exist */
        OS_EXIT_CRITICAL();
        return (OS_PRIO_EXIST);
    } else {
        OS_EXIT_CRITICAL();
        y    = newprio >> 3;                                    /* 
Precomput
e too reduce INT. latency   */
        bity = OSMapTbl[y];
        x    = newprio & 0x07;
        bitx = OSMapTbl[x];
        OS_ENTER_CRITICAL();
        if ((ptcb = OSTCBPrioTbl[oldprio]) != (OS_TCB *)0) {    /* 
Task to c
hangge must exist           */
            OSTCBPrioTbl[oldprio] = (OS_TCB *)0;                /* 
Remove TC
B frrom old priority        */
B frrom old priority        */
            if (OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) {     /* If 
task i
s reeady make it not ready  */
                if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) 
{
                    OSRdyGrp &= ~ptcb->OSTCBBitY;
                }
                OSRdyGrp    |= bity;                            /* 
Make new
prioority ready to run      */
                OSRdyTbl[y] |= bitx;
            } else {
                if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0) { 
/* Re
movee from event wait list  */
                    if ((pevent->OSEventTbl[ptcb->OSTCBY] &= 
~ptcb->OSTCBBit
X) === 0) {
                        pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
                    }
                    pevent->OSEventGrp    |= bity;
                    pevent->OSEventTbl[y] |= bitx;
                }
            }
            OSTCBPrioTbl[newprio] = ptcb;                       /* Place
 poi
nterr to TCB @ new priority */
            ptcb->OSTCBPrio       = newprio;                    /* Set 
new t
            ptcb->OSTCBPrio       = newprio;                    /* Set 
new t
ask priority               */
            ptcb->OSTCBY          = y;
            ptcb->OSTCBX          = x;
            ptcb->OSTCBBitY       = bity;
            ptcb->OSTCBBitX       = bitx;
            OS_EXIT_CRITICAL();
            OSSched();                                          /* Run 
highe
st ppriority task ready     */
            return (OS_NO_ERR);
        } else {
            OS_EXIT_CRITICAL();
            return (OS_PRIO_ERR);                               /* 
Task to c
hangge didn't exist         */
        }
    }
}
#endif
/*$PAGE*/
#if OS_TASK_DEL_EN
/*
************************************************************************
****
******************************
******************************
*                                            DELETE A TASK
*
* Notes:
*    1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
*           a) by making it not ready
*           b) by removing it from any wait lists
*           c) by preventing OSTimeTick() from making the task ready 
to run.

*       The task can then be 'unlinked' from the miscellaneous 
structures in
 uC//OS.
*    2) The function OSDummy() is called after OS_EXIT_CRITICAL() 
because, o
n moost processors, the next
*       instruction following the enable interrupt instruction is 
ignored.
You can replace OSDummy()
*       with a macro that basically executes a NO OP (i.e. OS_NOP()).  
The N
O OPP macro would avoid the
*       execution time of the function call and return.
************************************************************************
****
******************************
*/
/*$PAGE*/
UBYTE OSTaskDel(UBYTE prio)
UBYTE OSTaskDel(UBYTE prio)
{
    OS_TCB   *ptcb;
    OS_EVENT *pevent;
    UBYTE     priocur;
    if (prio == OS_LO_PRIO) {                                   /* Not 
allow
ed tto delete idle task     */
        return (OS_TASK_DEL_IDLE);
    }
    if (prio >= OS_MAX_TASKS && prio != OS_PRIO_SELF) {         /* 
Make sure
 tassk priority is valid    */
        return (OS_PRIO_INVALID);
    }
    OS_ENTER_CRITICAL();
    priocur = OSTCBCur->OSTCBPrio;                              /* 
Obtain th
e cuurrent priority         */
    if (prio == OS_PRIO_SELF) {                                 /* See 
if re
quessting to delete self    */
        prio = priocur;                                         /* Set 
prior
ity to delete to current   */
    }
    if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) {           /* 
Task to d
elette must exist           */
elette must exist           */
        OSTCBPrioTbl[prio] = (OS_TCB *)0;                       /* Clear
 old
 priiority entry            */
        if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {/* 
Make task
 nott ready                 */
            OSRdyGrp &= ~ptcb->OSTCBBitY;
        }
        if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0) {  /* If 
task i
s waaiting on event         */
            if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) 
== 0)
 { //* ... remove task from */
                pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
   //* ... event ctrl block */
            }
        }
        ptcb->OSTCBDly = 0;                                     /* 
Prevent O
STimmeTick() from updating  */
        OS_EXIT_CRITICAL();                                     /* 
Enabling
INT.. ignores next instruc. */
        OSDummy();                                              /* ... 
Dummy
 enssures that INTs will be */
        OS_ENTER_CRITICAL();                                    /* ... 
disab
led HERE!                  */
led HERE!                  */
        if (ptcb->OSTCBPrev == (OS_TCB *)0) {                   /* 
Remove fr
om TTCB chain               */
            ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
            OSTCBList                  = ptcb->OSTCBNext;
        } else {
            ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
            ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
        }
        ptcb->OSTCBNext = OSTCBFreeList;                        /* 
Return TC
B too free TCB list         */
        OSTCBFreeList   = ptcb;
        if (prio == priocur) {                                  /* 
Resched.
onlyy if deleting self!     */
            OS_EXIT_CRITICAL();
            OSSched();                                          /* 
Find new
highhest priority task      */
        } else {
            OS_EXIT_CRITICAL();
        }
        return (OS_NO_ERR);
    } else {
        OS_EXIT_CRITICAL();
        OS_EXIT_CRITICAL();
        return (OS_TASK_DEL_ERR);
    }
}
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                   REQUEST THAT A TASK DELETE ITSELF
*
* Description : This function is used to:
*                   a) notify a task to delete itself.
*                   b) to see if a task requested that the current 
task dele
te iitself.
*               This function is a little tricky to understand.  
Basically,
you have a task that needs
*               to be deleted however, this task has resources that it 
has a
lloccated (memory buffers,
*               semaphores, mailboxes, queues etc.).  The task cannot be
 del
etedd otherwise these
*               resources would not be freed.  The requesting task calls
 OST
askDDelReq() to indicate that
*               the task needs to be deleted.  Deleting of the task is 
howev
*               the task needs to be deleted.  Deleting of the task is 
howev
er, deferred to the task to
*               be deleted.  For example, suppose that task #10 needs to
 be
deleeted.  The requesting task
*               example #5, would call OSTaskDelReq(10).  When task 
#10 gets
 to execute, it calls this
*               function by specifying OS_PRIO_SELF and monitors the 
returne
d vaalue.  If the return value
*               is OS_TASK_DEL_REQ, another task requested a task 
delete.  T
ask #10 would look like this:
*
*                   void OS_FAR Task(void *data)
*                   {
*                       .
*                       .
*                       while (1) {
*                           OSTimeDly(1);
*                           if (OSTaskDelReq(OS_PRIO_SELF) == 
OS_TASK_DEL_RE
Q) {
*                               Release any owned resources
*                               De-allocate any dynamic memory
*                               OSTaskDel(OS_PRIO_SELF);
*                           }
*                           }
*                       }
*                   }
*
* Arguments : 'prio'   is the priority of the task to request the delete
 fro
m
*
* Returns   : if 'prio' is OS_PRIO_SELF:
*                 returns OS_TASK_DEL_REQ if a  task requested to delete
 SEL
F
*                 returns OS_NO_ERR       if no task requested to delete
 SEL
F
*             if 'prio' is other than OS_PRIO_SELF:
*                 request that the task be deleted
************************************************************************
****
******************************
*/
/*$PAGE*/
UBYTE OSTaskDelReq(UBYTE prio)
{
    BOOLEAN  stat;
    OS_TCB  *ptcb;
    if (prio == OS_LO_PRIO) {                                   /* Not 
allow
    if (prio == OS_LO_PRIO) {                                   /* Not 
allow
ed tto delete idle task     */
        return (OS_TASK_DEL_IDLE);
    }
    if (prio >= OS_MAX_TASKS && prio != OS_PRIO_SELF) {         /* 
Make sure
 tassk priority is valid    */
        return (OS_PRIO_INVALID);
    }
    if (prio == OS_PRIO_SELF) {                                 /* See 
if ta
sk tto delete is requesting */
        OS_ENTER_CRITICAL();
        stat = OSTCBCur->OSTCBDelReq;                           /* 
Return re
quesst status to caller     */
        OS_EXIT_CRITICAL();
        return (stat);
    } else {
        OS_ENTER_CRITICAL();
        if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) {       /* 
Task to d
elette must exist           */
            ptcb->OSTCBDelReq = OS_TASK_DEL_REQ;                /* Set 
flag
indiicating task to be DEL. */
        }
        OS_EXIT_CRITICAL();
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);
    }
}
#endif
/*$PAGE*/
#if OS_TASK_SUSPEND_EN
/*
************************************************************************
****
******************************
*                                            SUSPEND A TASK
*
* Description : This function is called to suspend a task.  The task can
 be
the calling task if if the
*               priority passed to OSTaskSuspend() is the priority of 
the ca
llinng task.
* Arguments   : 'prio'     is the priority of the task to suspend.  If 
you s
peciify OS_PRIO_SELF, the
*                          calling task will suspend itself and 
rescheduling
 willl occur.
*
* Returns     : OS_NO_ERR                if the requested task is 
suspended
*               OS_TASK_SUSPEND_PRIO     if the task to suspend does not
 exi
*               OS_TASK_SUSPEND_PRIO     if the task to suspend does not
 exi
st
* Note        : You should use this function with great care.  If you 
suspen
d a task that is waiting for
*               a message you will prevent this task from running when 
the m
essaage arrives.
************************************************************************
****
******************************
*/
UBYTE OSTaskSuspend(UBYTE prio)
{
    BOOLEAN   self;
    OS_TCB   *ptcb;
    if (prio == OS_LO_PRIO) {                                   /* Not 
allow
ed tto suspend idle task    */
        return (OS_TASK_SUSPEND_IDLE);
    }
    if (prio >= OS_MAX_TASKS && prio != OS_PRIO_SELF) {         /* 
Make sure
 tassk priority is valid    */
        return (OS_PRIO_INVALID);
    }
    OS_ENTER_CRITICAL();
    if (prio == OS_PRIO_SELF) {                                 /* See 
if su
    if (prio == OS_PRIO_SELF) {                                 /* See 
if su
spennd SELF                 */
        prio = OSTCBCur->OSTCBPrio;
        self = TRUE;
    } else {
        self = FALSE;
    }
    if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) {                
/* Task
 to suspend must exist     */
        OS_EXIT_CRITICAL();
        return (OS_TASK_SUSPEND_PRIO);
    } else {
        if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {     
/* Make
 tassk not ready            */
            OSRdyGrp &= ~ptcb->OSTCBBitY;
        }
        ptcb->OSTCBStat |= OS_STAT_SUSPEND;                          
/* Stat
us oof task is 'SUSPENDED'  */
        OS_EXIT_CRITICAL();
        if (self == TRUE) {                                          
/* Cont
ext switch only if SELF    */
            OSSched();
        }
            OSSched();
        return (OS_NO_ERR);
    }
}
/*$PAGE*/
/*
************************************************************************
****
******************************
*                                      RESUME A SUSPENDED TASK
*
* Description : This function is called to resume a previously suspended
 tas
k.
* Arguments   : 'prio'     is the priority of the task to resume.
*
* Returns     : OS_NO_ERR                if the requested task is 
resumed
*               OS_TASK_RESUME_PRIO      if the task to resume does 
not exis
t
*               OS_TASK_NOT_SUSPENDED    if the task to resume has not 
been
susppended

--

  puke! 
  技工而已

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.239.152]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:605.560毫秒