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毫秒