📄 os.c
字号:
} /* OSTimeGet */
static void
OSEventTaskResume(OS_EVENT *pevent)
{
unsigned int intFlagsSave;
uint x, y, bitx, bity, p;
OS_TCB *ptcb;
intFlagsSave = ENTER_CRITICAL();
/* find highest priority task pending on event */
y = OSUnMapTbl[pevent->OSEventGrp];
bity = OSMapTbl[y];
x = OSUnMapTbl[pevent->OSEventTbl[y]];
bitx = OSMapTbl[x];
p = (y << 3) + x;
/* remove task from waiting list */
if ((pevent->OSEventTbl[y] &= ~bitx) == 0)
pevent->OSEventGrp &= ~bity;
/* pointer to new task */
ptcb = OSTCBPrioTbl[p];
/* reset timeout */
ptcb->OSTCBDly = 0;
/* task is ready to run */
ptcb->OSTCBStat = OS_STAT_RDY;
/* unlink control block */
ptcb->OSTCBEventPtr = (OS_EVENT *)0;
/* put task in ready to run list */
OSRdyGrp |= bity;
OSRdyTbl[y] |= bitx;
EXIT_CRITICAL(intFlagsSave);
} /* OSEventTaskResume */
/* create a semaphore */
OS_EVENT*
OSSemCreate(int value)
{
unsigned int intFlagsSave;
OS_EVENT *pevent;
if (value < 0) /* semaphore cannot start negative */
return((OS_EVENT*)0);
intFlagsSave = ENTER_CRITICAL();
/* get next available event CB */
if ((pevent = OSEventFreeList) != 0)
{
/* update free list */
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
/* set semaphore values */
pevent->OSEventCnt = value;
pevent->OSEventGrp = 0;
pevent->OSEventTbl[0] = 0;
pevent->OSEventTbl[1] = 0;
pevent->OSEventTbl[2] = 0;
pevent->OSEventTbl[3] = 0;
pevent->OSEventTbl[4] = 0;
pevent->OSEventTbl[5] = 0;
pevent->OSEventTbl[6] = 0;
pevent->OSEventTbl[7] = 0;
}
EXIT_CRITICAL(intFlagsSave);
return(pevent);
} /* OSSemCreate */
/* signal semaphore */
uint
OSSemPost(OS_EVENT *pevent)
{
unsigned int intFlagsSave;
intFlagsSave = ENTER_CRITICAL();
if (pevent->OSEventCnt >= OS_INT_MAX) {
/* semaphore overflow */
EXIT_CRITICAL(intFlagsSave);
return(OS_SEM_OVF);
}
/* negative semaphore means tasks pending */
if ((pevent->OSEventCnt++ < 0) && (pevent->OSEventGrp)) {
/* resume highest priority task pending on semaphore */
OSEventTaskResume(pevent);
if (intFlagsSave & IRQ_INT)
{
/* This routine has been called within ISR */
taskReSched = 1; /* Need to do task re-schedule later */
EXIT_CRITICAL(intFlagsSave);
}
else
{
EXIT_CRITICAL(intFlagsSave);
OSSched();
}
} else {
EXIT_CRITICAL(intFlagsSave);
}
return(OS_NO_ERR);
} /* OSSemPost */
/* wait semaphore */
void
OSSemPend(OS_EVENT *pevent, uint timeout, uint *err)
{
unsigned int intFlagsSave;
intFlagsSave = ENTER_CRITICAL();
if (pevent->OSEventCnt-- > 0) {
/* resource available */
EXIT_CRITICAL(intFlagsSave);
if (err != 0)
*err = OS_NO_ERR;
return;
}
/* resource not available, sleep on semaphore */
OSTCBCur->OSTCBStat = OS_STAT_SEM;
OSTCBCur->OSTCBDly = timeout;
OSTCBCur->OSTCBEventPtr = pevent;
/* suspend task */
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
EXIT_CRITICAL(intFlagsSave);
/* find next task ready to run */
OSSched();
intFlagsSave = ENTER_CRITICAL();
if (OSTCBCur->OSTCBStat == OS_STAT_SEM) {
/* still pending on semaphore: timeout */
if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &=
~OSTCBCur->OSTCBBitX) ==0)
pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
OSTCBCur->OSTCBStat = OS_STAT_RDY;
/* no longer waiting for event */
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
/* signal timeout */
if (err != 0)
*err = OS_TIMEOUT;
}
else {
if (err != 0)
*err = OS_NO_ERR;
}
EXIT_CRITICAL(intFlagsSave);
} /* OSSemPend */
/* create mailbox */
OS_EVENT*
OSMboxCreate(void *msg)
{
unsigned int intFlagsSave;
OS_EVENT *pevent;
intFlagsSave = ENTER_CRITICAL();
/* get next available event CB */
if ((pevent = OSEventFreeList) != 0)
{
/* update free list */
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
/* set mailbox values */
pevent->OSEventPtr = msg;
pevent->OSEventGrp = 0;
pevent->OSEventTbl[0] = 0;
pevent->OSEventTbl[1] = 0;
pevent->OSEventTbl[2] = 0;
pevent->OSEventTbl[3] = 0;
pevent->OSEventTbl[4] = 0;
pevent->OSEventTbl[5] = 0;
pevent->OSEventTbl[6] = 0;
pevent->OSEventTbl[7] = 0;
}
EXIT_CRITICAL(intFlagsSave);
return(pevent);
} /* OSMBoxCreate */
/* post mbox message */
uint
OSMboxPost(OS_EVENT *pevent, void *msg)
{
unsigned int intFlagsSave;
intFlagsSave = ENTER_CRITICAL();
/* make sure mailbox doesn't contain a message */
if (pevent->OSEventPtr != (void *)0) {
EXIT_CRITICAL(intFlagsSave);
return(OS_MBOX_FULL);
}
/* place message in mailbox */
pevent->OSEventPtr = msg;
/* see if any task is pending on the mailbox */
if (pevent->OSEventGrp) {
/* resume highest priority task pending on mailbox */
OSEventTaskResume(pevent);
if (intFlagsSave & IRQ_INT)
{
/* This routine has been called within ISR */
taskReSched = 1; /* Need to do task re-schedule later */
EXIT_CRITICAL(intFlagsSave);
}
else
{
EXIT_CRITICAL(intFlagsSave);
OSSched();
}
} else {
EXIT_CRITICAL(intFlagsSave);
}
return(OS_NO_ERR);
} /* OSMboxPost */
/* pend for mbox message */
void*
OSMboxPend(OS_EVENT *pevent, uint timeout, uint *err)
{
unsigned int intFlagsSave;
void *msg;
intFlagsSave = ENTER_CRITICAL();
/* check if the mailbox already has a message */
if ((msg = pevent->OSEventPtr) != (void *)0) {
/* clear the mailbox */
pevent->OSEventPtr = (void *)0;
EXIT_CRITICAL(intFlagsSave);
if (err != 0)
*err = OS_NO_ERR;
/* return mailbox content */
return(msg);
}
/* resource not available, sleep on mailbox */
OSTCBCur->OSTCBStat = OS_STAT_MBOX;
OSTCBCur->OSTCBDly = timeout;
OSTCBCur->OSTCBEventPtr = pevent;
/* suspend task */
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
EXIT_CRITICAL(intFlagsSave);
/* find next task ready to run */
OSSched();
intFlagsSave = ENTER_CRITICAL();
if (OSTCBCur->OSTCBStat == OS_STAT_MBOX) {
/* still pending on mailbox: timeout */
if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &=
~OSTCBCur->OSTCBBitX) == 0)
pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
OSTCBCur->OSTCBStat = OS_STAT_RDY;
/* no longer waiting for event */
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
/* set message content to null */
msg = (void *)0;
/* signal timeout */
if (err != 0)
*err = OS_TIMEOUT;
}
else {
/* message received */
msg = pevent->OSEventPtr;
/* clear the mailbox */
pevent->OSEventPtr = (void *)0;
if (err != 0)
*err = OS_NO_ERR;
}
EXIT_CRITICAL(intFlagsSave);
return(msg);
} /* OSMBoxPend */
/* create a queue */
OS_EVENT*
OSQCreate(void **start, uint size)
{
unsigned int intFlagsSave;
OS_EVENT *pevent;
OS_Q *pq;
intFlagsSave = ENTER_CRITICAL();
/* get next available event CB */
if ((pevent = OSEventFreeList) == (OS_EVENT*)0) {
/* ran out of event CB */
EXIT_CRITICAL(intFlagsSave);
return((OS_EVENT *)0);
}
/* get next available queue CB */
if ((pq = OSQFreeList) == (OS_Q *)0) {
/* ran out of queue CB */
EXIT_CRITICAL(intFlagsSave);
return((OS_EVENT *)0);
}
/* update free list */
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
OSQFreeList = OSQFreeList->OSQPtr;
/* initialize the queue */
pq->OSQStart = start;
pq->OSQEnd = &start[size];
pq->OSQIn = start;
pq->OSQOut = start;
pq->OSQSize = size;
pq->OSQEntries = 0;
pevent->OSEventPtr = pq;
pevent->OSEventGrp = 0;
pevent->OSEventTbl[0] = 0;
pevent->OSEventTbl[1] = 0;
pevent->OSEventTbl[2] = 0;
pevent->OSEventTbl[3] = 0;
pevent->OSEventTbl[4] = 0;
pevent->OSEventTbl[5] = 0;
pevent->OSEventTbl[6] = 0;
pevent->OSEventTbl[7] = 0;
EXIT_CRITICAL(intFlagsSave);
return(pevent);
} /* OSQCreate */
/* post a message to a queue */
uint
OSQPost(OS_EVENT *pevent, void *msg)
{
unsigned int intFlagsSave;
OS_Q *pq;
intFlagsSave = ENTER_CRITICAL();
pq = (OS_Q*)(pevent->OSEventPtr);
/* make sure the queue is not full */
if (pq->OSQEntries >= pq->OSQSize) {
EXIT_CRITICAL(intFlagsSave);
return(OS_Q_FULL);
}
/* insert message into queue */
*pq->OSQIn++ = msg;
pq->OSQEntries++;
if (pq->OSQIn == pq->OSQEnd)
/* wrap around In pointer if reached end */
pq->OSQIn = pq->OSQStart;
/* see if any task is pending on the queue */
if (pevent->OSEventGrp) {
/* resume highest priority task pending on queue */
OSEventTaskResume(pevent);
if (intFlagsSave & IRQ_INT)
{
/* This routine has been called within ISR */
taskReSched = 1; /* Need to do task re-schedule later */
EXIT_CRITICAL(intFlagsSave);
}
else
{
EXIT_CRITICAL(intFlagsSave);
OSSched();
}
} else {
EXIT_CRITICAL(intFlagsSave);
}
return(OS_NO_ERR);
} /* OSQPost */
/* pend for message from a queue */
void*
OSQPend(OS_EVENT *pevent, uint timeout, uint *err)
{
unsigned int intFlagsSave;
void *msg;
OS_Q *pq;
intFlagsSave = ENTER_CRITICAL();
pq = (OS_Q *)(pevent->OSEventPtr);
/* check if the queue already has a message */
if (pq->OSQEntries != 0) {
/* extract the message */
msg = *pq->OSQOut++;
/* update message counter */
pq->OSQEntries--;
/* wrap around Out pointer if reached end */
if (pq->OSQOut == pq->OSQEnd)
pq->OSQOut = pq->OSQStart;
EXIT_CRITICAL(intFlagsSave);
if (err != 0)
*err = OS_NO_ERR;
return(msg);
}
/* no messages available, sleep on the queue */
OSTCBCur->OSTCBStat = OS_STAT_Q;
OSTCBCur->OSTCBDly = timeout;
/* suspend task */
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
EXIT_CRITICAL(intFlagsSave);
/* find next task ready to run */
OSSched();
intFlagsSave = ENTER_CRITICAL();
if (OSTCBCur->OSTCBStat == OS_STAT_Q) {
/* still pending on queue: timeout */
if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &=
~OSTCBCur->OSTCBBitX) == 0)
pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;
OSTCBCur->OSTCBStat = OS_STAT_RDY;
/* no longer waiting for event */
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
/* set message content to null */
msg = (void *)0;
/* signal timeout */
if (err != 0)
*err = OS_TIMEOUT;
}
else {
/* message received */
msg = *pq->OSQOut++;
/* update message counter */
pq->OSQEntries--;
/* wrap around Out pointer if reached end */
if (pq->OSQOut == pq->OSQEnd)
pq->OSQOut = pq->OSQStart;
if (err != 0)
*err = OS_NO_ERR;
}
EXIT_CRITICAL(intFlagsSave);
return(msg);
} /* OSQPend */
/*******************************************************************************
*
* sysMemVirtSize - get sizes of virtual memory regions
*
* This routine returns sizes of virtual memory regions.
*
* void sysMemVirtSize
* (
* unsigned int* sys, // Size of memory mapped at zero for uC/OS
* unsigned int* sys_all, // Size of memory mapped at zero and usable by uC/OS
* unsigned int* sdram, // Size of memory mapped at C0000000 and usable by HW
* unsigned int* sram, // Size of sram
* unsigned int* flash // Size of Flash
* )
*
* SYS_ALL is the actual amount of memory mapped to virtual address
* zero from the SDRAM. Some amount of the top end of this may be
* reserved by users, so the amount actually available to uC/OS
* is given by SYS. The size SDRAM which is available to the HW and
* not used by uC/OS (mapped with virt addr == phys addr) is given
* by SDRAM.
*
*
* RETURNS: N/A
*/
void sysMemVirtSize(unsigned int* sys, unsigned int* sys_all, unsigned int* sdram,
unsigned int* sram, unsigned int* flash)
{
/* Size of memory mapped at zero for UCOS */
// 32 - 24 mBytes (24 is for MEngine communications)
*sys_all = DRAM_SIZE;
/* Size of memory mapped at zero and usable by UCOS */
*sys = DRAM_SIZE;
/* Size of memory mapped at C0000000 and usable by HW */
// 24 MB for MEngine communications
*sdram = DRAMBaseForUEngSize;
/* Size of sram **/
// 0x200000 (2 mb)
*sram = SRAM_SIZE;
/* Size of Flash */
// 0x4000
*flash = FLASH_SIZE;
}
/* end of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -