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

📄 ucos.c

📁 各种硬件平台上的us OS移植实例(arm6)
💻 C
📖 第 1 页 / 共 3 页
字号:
		return(OS_PRIO_EXIST);		}	/* ELSE */	/* check if old priority task exists */	if (OSTCBPrioTbl[oldp] == (OS_TCB *)0)		{		OS_EXIT_CRITICAL();		return(OS_PRIO_ERR);	/* Task to change didn't exist */		}	/* ELSE */	ptcb = OSTCBPrioTbl[oldp];			/* get the ptcb first! GIC 94Jul11 */ 	OSTCBPrioTbl[oldp] = (OS_TCB *)0;	/* Remove TCB from old priority */	pevent = ptcb->OSTCBEventPtr;		/* Get pointer to event control block */	if (OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX)	/* if task is ready make it not ready */		{		if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)			{			OSRdyGrp &= ~(ptcb->OSTCBBitY);			}		rdy = TRUE;		}	else 		{		rdy = FALSE;		if (pevent != (OS_EVENT *)0)	/* remove from event wait list */			{			if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)				{				pevent->OSEventGrp &= ~ptcb->OSTCBBitY;				}			}		}	if (ptcb->OSTCBPrev == (OS_TCB *)0)	/* remove from TCB linked list */		{		ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;		OSTCBList = ptcb->OSTCBNext;		}	else		{		ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;		ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;		}	OS_EXIT_CRITICAL();	ptcb->OSTCBPrio	= newp;		/* setup task control block with new values */	ptcb->OSTCBY	= newp >> 3;	ptcb->OSTCBBitY = OSMapTbl[newp >> 3];	ptcb->OSTCBX	= newp & 0x07;	ptcb->OSTCBBitX = OSMapTbl[newp & 0x07];	OS_ENTER_CRITICAL();	/* make new priority ready to run if old one was ready */	if (rdy)		/* if task was ready ... */		{		OSRdyGrp |= ptcb->OSTCBBitY;	/* ...make new priority ready to run */		OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;		}	else		{		if (pevent != (OS_EVENT *)0)	/* wait for event if old was waiting */			{			pevent->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;			pevent->OSEventGrp				 |= ptcb->OSTCBBitY;			}		}	OSTCBPrioTbl[newp]	 = ptcb;	/* place TCB pointer at the new priority */	OSTCBList->OSTCBPrev = ptcb;	/* link TCB to the top of the list */	OSTCBList			 = ptcb;	/* assuming the idle task is in the list */	OS_EXIT_CRITICAL();	OSSched();				/* run highest priority task ready */ return(OS_NO_ERR);} /* OSTaskChangePrio *//* * O S T a s k D e l * * delete a task * * NOTE: VLSI rearrange the logic so that the ELSE is implied */int		OSTaskDel(uint prio){ OS_EVENT	*pevent;	/* VLSI org prefixed with 'register' */ OS_TCB		*ptcb;		/* VLSI org prefixed with 'register' */ 	if (prio == OS_LO_PRIO)		{		return(OS_TASK_DEL_IDLE);	/* not allowed to delete idle task */		}		/* ELSE */		OS_ENTER_CRITICAL();		if (OSTCBPrioTbl[prio] == (OS_TCB *)0)	/* does task to delete exist ? */		{		OS_EXIT_CRITICAL();		return(OS_TASK_DEL_ERR);	/* NO */		}		/* ELSE task exists */	ptcb = OSTCBPrioTbl[prio];	OSTCBPrioTbl[prio] = (OS_TCB *)0;	/* clear old TCB entry */	if ((OSRdyTbl[ptcb->OSTCBY] &= ~(ptcb->OSTCBBitX)) == 0)		{		OSRdyGrp &= ~(ptcb->OSTCBBitY);		/* make task not ready */		}	if (ptcb->OSTCBPrev == (OS_TCB *)0)		{		ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;	/* remove from TCB linked list */		OSTCBList = ptcb->OSTCBNext;		}	else		{		ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;		ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;		}	/* if task waiting on event remove it from event control block */	if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0)		{		if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)			{			pevent->OSEventGrp &= ~(ptcb->OSTCBBitY);			}		}	ptcb->OSTCBNext = OSTCBFreeList;	/* return TCB to the free list */	OSTCBFreeList = ptcb;	OS_EXIT_CRITICAL();	OSSched();				/* find new highest priority task */ return(OS_NO_ERR);} /* OSTaskDel *//* * O S T i m e D l y * * delay the current task */void	OSTimeDly(uint ticks){	if( ticks > 0 )		/* GIC 94Jul11 restored as per manual */		{		OS_ENTER_CRITICAL();		/* suspend the current task */		if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)			{			OSRdyGrp &= ~OSTCBCur->OSTCBBitY;	/* then group not ready */			}		OSTCBCur->OSTCBDly = ticks;		/* load number of ticks in TCB */		OS_EXIT_CRITICAL();			OSSched();			/* find a new task to run */		}} /* OSTimeDly *//****************************************************************************** * O S T i m e T i c k * * This is an IRQ interrupt routine. Only FIQ might be enabled. * * process system tick * * The code here differs from the manual in that if you are using a Timer * and it is an IRQ then a context switch is set up and the code to change * context has been added here. In the ARM one normally finds that the natural * order is USER mode (except for system calls) which can be interrupted by * IRQ which in turn could be interrupted by an FIQ. On a PID the FIQ is not * used except with an extender board. An IRQ is NOT normally nestable. Upon * entry the I bit is set. If you reset this bit prior to removing the cause * of the IRQ your program will lock up in an endless loop. If you reset this * bit prior to saving your context (or at least your lr_irq) your program * will get lost. */void	OSTimeTick(void){ OS_TCB		   *ptcb;		/* VLSI org prefixed with 'register' */ uint			y;				/* VLSI org is 'register UBYTE y' */#if 0 /* see the comment in the OSIntEnter routine */ OS_ENTER_CRITICAL();#endif	OSTime++;					/* Always increment on a TICK */	if( OSRunning )	/* scan all TCB in list */		{		for (ptcb = OSTCBList; ptcb->OSTCBPrio != OS_LO_PRIO; ptcb = ptcb->OSTCBNext)			{			if (ptcb->OSTCBDly > 0)				{				if (--ptcb->OSTCBDly == 0)					{					/* make task ready to run */					OSRdyGrp				|= ptcb->OSTCBBitY;	/* be sure group is ready */					OSRdyTbl[ptcb->OSTCBY]	|= ptcb->OSTCBBitX;	/* and task is ready */					}				}			}		if (OSLockNesting == 0 && OSIntNesting == 0) /* VLSI task scheduling enabled and not interrupt level */			{			y				= OSUnMapTbl[OSRdyGrp];	/* get pointer to highest task ready to run */				OSTCBHighRdy	= OSTCBPrioTbl[(y << 3) + OSUnMapTbl[OSRdyTbl[y]]];			if (OSTCBHighRdy != OSTCBCur)			/* make sure this is not the current running task */				{				OSCtxSwCtr++;						/* increment context switch counter */				}			}		}#if 0 /* see the comment in the OSIntEnter routine */ OS_EXIT_CRITICAL();#endif} /* OSTimeTick *//* * O S T i m e S e t * * set system time */void	OSTimeSet(uint ticks){	OS_ENTER_CRITICAL();	OSTime = ticks;	OS_EXIT_CRITICAL();}/* * O S T i m e G e t * * get system time * * NOTE:	The manual suggests that OS_ENTER_CRITICAL and OS_EXIT_CRITICAL be used *			but unless a process is setting the time while this one is trying *			to read it (or even then?), it seems like one should be able to *			read without using CRITICAL macros. */uint	OSTimeGet(void){ return(OSTime);}/* * O S S e m C r e a t e * * create a semaphore * * NOTE: VLSI rearrange the logic so that the ELSE is implied */OS_EVENT	*OSSemCreate(int cnt){ OS_EVENT	*pevent;		/* VLSI org prefixed with 'register' */	OS_ENTER_CRITICAL();	pevent = OSEventFreeList;	/* get next available event CB */								/* update free list */	if (OSEventFreeList)		/* See if pool of free ECB pool was empty */		{		OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;		}	OS_EXIT_CRITICAL();	if (pevent == (OS_EVENT *)0)		{		return((OS_EVENT *)0);	/* ran out of event CB */		}			/* ELSE */		if (cnt < 0)				/* semaphore cannot start negative */		{		OS_ENTER_CRITICAL();		/* return event CB back to the free list */		pevent->OSEventPtr = (void *)OSEventFreeList;		OSEventFreeList = pevent;		OS_EXIT_CRITICAL();		return((OS_EVENT *)0);		}	/* ELSE */		/* set semaphore values */	pevent->OSEventCnt 	  = cnt;	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 S e m P e n d * * wait semaphore * * NOTE: VLSI rearrange the logic so that the ELSE is implied */void	OSSemPend(OS_EVENT *pevent, uint timeout, uint *err){	OS_ENTER_CRITICAL();	if (pevent->OSEventCnt-- > 0)		{		OS_EXIT_CRITICAL();	/* resource available */		*err = OS_NO_ERR;		return;		}	/* ELSE resource not available, sleep on semaphore */		OSTCBCur->OSTCBStat = OS_STAT_SEM;	/* pend on semaphore */	OSTCBCur->OSTCBDly = timeout;		/* store pend timeout in TCB */		/* suspend task */	if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)		{		OSRdyGrp &= ~OSTCBCur->OSTCBBitY;	/* Task no longer ready */		}		pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;	/* put task in waiting list */	pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;	OS_EXIT_CRITICAL();	OSSched();				/* find next task ready to run */	OS_ENTER_CRITICAL();	if (OSTCBCur->OSTCBStat == OS_STAT_SEM)	/* must have timed out if still waiting for event */		{		/* still pending on semaphore: 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 */		OS_EXIT_CRITICAL();		*err = OS_TIMEOUT;	/* signal time'ed out */		}	else		{		OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;		OS_EXIT_CRITICAL();		*err = OS_NO_ERR;		}}/* * O S S e m P o s t * * signal semaphore */uint	OSSemPost(OS_EVENT *pevent){	OS_ENTER_CRITICAL();	if (pevent->OSEventCnt >= INT_MAX)	/* VLSI INT_MAX defined in OSDEFS.H */		{		OS_EXIT_CRITICAL();		/* semaphore overflow */		return(OS_SEM_OVF);		}			/* ELSE */	if (pevent->OSEventCnt++ >= 0)		{		OS_EXIT_CRITICAL();		}	else		/* negative semaphore means tasks pending */		{		if (pevent->OSEventGrp)	/* see if any task pending on semaphore */			{			OS_EXIT_CRITICAL();  			OSEventTaskResume(pevent);	/* resume highest priority task pending on semaphore */			OSSched();					/* find highest priority task ready to run */			}		}	return(OS_NO_ERR);}/* * O S M b o x C r e a t e * * create mailbox */OS_EVENT	*OSMboxCreate(void *msg){ OS_EVENT	*pevent;	OS_ENTER_CRITICAL();	pevent = OSEventFreeList;	/* get next available event CB */								/* update free list */	if (OSEventFreeList)		/* see if pool of free ECB pool was empty */		{		OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;		}	OS_EXIT_CRITICAL();	if (pevent != (OS_EVENT *)0)		{		pevent->OSEventPtr		= msg;	/* set mailbox values */		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 M b o x P e n d * * pend for mbox message */void	*OSMboxPend(OS_EVENT *pevent, uint timeout, uint *err){ void	*msg;	OS_ENTER_CRITICAL();		/* check if the mailbox already has a message */	if ((msg = pevent->OSEventPtr) != (void *)0)	/* already a message ? */		{		pevent->OSEventPtr = (void *)0;	/* clear the mailbox */

⌨️ 快捷键说明

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