⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ucos.c

📁 各种硬件平台上的us OS移植实例(arm6)
💻 C
📖 第 1 页 / 共 3 页
字号:
		OS_EXIT_CRITICAL();		*err = OS_NO_ERR;		return(msg);		/* return mailbox content */		}		/* ELSE */		/* message not available, task will pend (sleep on mailbox) */		OSTCBCur->OSTCBStat = OS_STAT_MBOX;	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;	OS_EXIT_CRITICAL();	OSSched();			/* find next task ready to run */	OS_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;		/* set status to ready */		OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;	/* no longer waiting for event */		msg = (void *)0;		/* set message content to null */		OS_EXIT_CRITICAL();		*err = OS_TIMEOUT;		/* signal time'ed out */		}	else		{		msg = pevent->OSEventPtr;		/* message received */		pevent->OSEventPtr = (void *)0;	/* clear the mailbox */		OS_EXIT_CRITICAL();		*err = OS_NO_ERR;		} return(msg);}/* * O S M b o x P o s t * * post mbox message */uint	OSMboxPost(OS_EVENT *pevent, void *msg){	OS_ENTER_CRITICAL();		/* make sure mailbox doesn't contain a message */	if (pevent->OSEventPtr != (void *)0)		{		OS_EXIT_CRITICAL();		return(OS_MBOX_FULL);		}			/* ELSE */		pevent->OSEventPtr = msg;	/* place message in mailbox */		if (pevent->OSEventGrp)		/* see if any task is pending on the mailbox */		{		OS_EXIT_CRITICAL();	/* resume highest priority task pending on mailbox */		OSEventTaskResume(pevent);		OSSched();			/* Find highest priority task ready to run */		}	else		{		OS_EXIT_CRITICAL();		} return(OS_NO_ERR);}/* * I R Q M b o x P o s t * * post mbox message */uint	IRQMboxPost(OS_EVENT *pevent, void *msg){ OS_TCB	*ptcb; uint	 x; uint	 y; uint	 bitx; uint	 bity; uint	 p;	if (pevent->OSEventPtr != (void *)0)		{		return(OS_MBOX_FULL);		}			/* ELSE */		pevent->OSEventPtr = msg;	/* place message in mailbox */		if (pevent->OSEventGrp)		/* see if any task is pending on the mailbox */		{		y	 = OSUnMapTbl[pevent->OSEventGrp];	/* find highest priority task pending on event */		bity = OSMapTbl[y];		x	 = OSUnMapTbl[pevent->OSEventTbl[y]];		bitx = OSMapTbl[x];		p	 = (y << 3) + x;				if ((pevent->OSEventTbl[y] &= ~bitx) == 0)	/* remove this task from waiting list */			{			pevent->OSEventGrp &= ~bity;			}				ptcb				= OSTCBPrioTbl[p];	/* pointer to new task */ 		ptcb->OSTCBDly		= 0;				/* reset timeout */		ptcb->OSTCBStat		= OS_STAT_RDY;		/* task is ready to run */		ptcb->OSTCBEventPtr = (OS_EVENT *)0;	/* unlink control block */				OSRdyGrp		|= bity;				/* put task in ready to run list */		OSRdyTbl[y]		|= bitx;		}	 return(OS_NO_ERR);}/* * O S Q C r e a t e * * create a queue */OS_EVENT	*OSQCreate(void **start, uint size){ OS_EVENT	*pevent; OS_Q		*pq;	OS_ENTER_CRITICAL();		pevent = OSEventFreeList;	/* get next free event control block */	if (OSEventFreeList)		/* update free list */		{		OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;		}			if (pevent == (OS_EVENT *)0)		{		OS_EXIT_CRITICAL();		/* ran out of event CB */		return(pevent);			}			/* ELSE */		pq = OSQFreeList;			/* get a free queue control block */		if (OSQFreeList != (OS_Q *)0)		{		OSQFreeList = OSQFreeList->OSQPtr;		}		if (pq == (OS_Q *)0)		/* was there a free block ? */		{		pevent->OSEventPtr = (void *)OSEventFreeList;	/* NO */		OSEventFreeList = pevent;	/* ran out of queue CB return event CB to free list */		OS_EXIT_CRITICAL();		return((OS_EVENT *)0);		}		/* ELSE */		OS_EXIT_CRITICAL();	pq->OSQStart		  = start;			/* initialize the queue */	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; return(pevent);}/* * O S Q P e n d * * pend for message from a queue */void	*OSQPend(OS_EVENT *pevent, uint timeout, uint *err){ void	*msg; OS_Q	*pq;	OS_ENTER_CRITICAL();	pq = (OS_Q *)pevent->OSEventPtr;	if (pq->OSQEntries != 0)	/* check if the queue already has a message */		{		msg = *pq->OSQOut++;	/* extract the message */		pq->OSQEntries--;		/* update message counter */		if (pq->OSQOut == pq->OSQEnd)	/* wrap around Out pointer if reached end */			{			pq->OSQOut = pq->OSQStart;			}		OS_EXIT_CRITICAL();		*err = OS_NO_ERR;		return(msg);		}			/* ELSE */		/* 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;	/* put task in waiting list */	pevent->OSEventGrp					 |= OSTCBCur->OSTCBBitY;		OS_EXIT_CRITICAL();		OSSched();			/* find next highest priority task ready to run */	OS_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;		/* set status to ready */		OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;	/* no longer waiting for event */		msg = (void *)0;		/* set message content to null */		OS_EXIT_CRITICAL();		*err = OS_TIMEOUT;		/* signal time'ed out */		}	else		{		msg = *pq->OSQOut++;			/* message received */		pq->OSQEntries--;				/* update message counter */		if (pq->OSQOut == pq->OSQEnd)	/* wrap around Out pointer if reached end */			{			pq->OSQOut = pq->OSQStart;			}		OS_EXIT_CRITICAL();		*err = OS_NO_ERR;		}		return(msg);}/* * O S Q P o s t * * post a message to a queue */uint	OSQPost(OS_EVENT *pevent, void *msg){ OS_Q	*pq;	OS_ENTER_CRITICAL();	pq = (OS_Q *)pevent->OSEventPtr;	/* point to queue control block */	if (pq->OSQEntries >= pq->OSQSize)	/* make sure the queue is not full */		{		OS_EXIT_CRITICAL();		return(OS_Q_FULL);		}			/* ELSE */	*pq->OSQIn++ = msg;				/* insert message into queue */	pq->OSQEntries++;				/* update number of entries in queue */	if (pq->OSQIn == pq->OSQEnd)		{		pq->OSQIn = pq->OSQStart;	/* wrap around In pointer if reached end */		}	if (pevent->OSEventGrp)		/* see if any task is pending on the mailbox */		{		OS_EXIT_CRITICAL();		OSEventTaskResume(pevent);	/* resume highest priority task pending on mailbox */		OSSched();					/* find highest priority task pending on queue */		}	else		{		OS_EXIT_CRITICAL();		} return(OS_NO_ERR);}/* * O S E v e n t T a s k R e s u m e */void	OSEventTaskResume(OS_EVENT *pevent){ OS_TCB	*ptcb; uint	 x; uint	 y; uint	 bitx; uint	 bity; uint	 p;	OS_ENTER_CRITICAL(); 	y	 = OSUnMapTbl[pevent->OSEventGrp];	/* find highest priority task pending on event */	bity = OSMapTbl[y];	x	 = OSUnMapTbl[pevent->OSEventTbl[y]];	bitx = OSMapTbl[x];	p	 = (y << 3) + x;	if ((pevent->OSEventTbl[y] &= ~bitx) == 0)	/* remove this task from waiting list */		{		pevent->OSEventGrp &= ~bity;		}	ptcb				= OSTCBPrioTbl[p];	/* pointer to new task */ 	ptcb->OSTCBDly		= 0;				/* reset timeout */	ptcb->OSTCBStat		= OS_STAT_RDY;		/* task is ready to run */	ptcb->OSTCBEventPtr = (OS_EVENT *)0;	/* unlink control block */	OSRdyGrp		|= bity;				/* put task in ready to run list */	OSRdyTbl[y]		|= bitx;	OS_EXIT_CRITICAL(); }/* * O S T a s k C r e a t e * * create a task * *   This differs from the code in manual because the 1st four parameters are * passed in a1-a4 respectively. Therefore pdata is NOT passed on the stack * but in register a1. *   Also TASK's are created so that the LR contains the "return" location, * which allows the context switch to do the same for starting a new task as * well as continuing with a preempted one. */int		OSTaskCreate(PTV task, void *pdata, void *ptsk, uint prio){ void	*stk; int	 err;	OS_ENTER_CRITICAL(); 	if (OSTCBPrioTbl[prio] != (OS_TCB *)0)		{		OS_EXIT_CRITICAL(); 		return(OS_PRIO_EXIST);	/* only one task allowed at its priority */		}			/* ELSE build a context for the new task */		OS_EXIT_CRITICAL(); 		stk = InitTask(ptsk, pdata, task);	/* initialise the task at pstk */	err = OSTCBInit(prio, (void *)stk);	if ((err == OS_NO_ERR) && OSRunning) 		{		OSSched();		} return(err);}/* * A R M I n s t a l l I R Q H a n d l e r * * This routine allows a uC/OS IRQ source bit ISR to be installed in * the handler vector table. NOTE: The vector table is *TOTALLY* * seperate from the C-Demon IRQ vector table, and is a uC/OS * resource. */IRQHandlerFn ARMInstallIRQHandler(int slot,IRQHandlerFn newfn){ IRQHandlerFn old = NULL ; if ((slot >= 0) && (slot < NUMIRQS))  {   old = IRQvectors[slot] ;   IRQvectors[slot] = newfn ;  } return(old) ;}/* * A R M I n s t a l l F I Q H a n d l e r * * This routine allows a uC/OS FIQ source bit ISR to be installed in * the handler vector table. NOTE: The vector table is *TOTALLY* * seperate from the C-Demon FIQ vector table, and is a uC/OS * resource. */FIQHandlerFn ARMInstallFIQHandler(int slot,FIQHandlerFn newfn){ FIQHandlerFn old = NULL ; if ((slot >= 0) && (slot < NUMFIQS))  {   old = FIQvectors[slot] ;   FIQvectors[slot] = newfn ;  } return(old) ;}/*> EOF ucos.c <*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -