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

📄 os.c

📁 UCSO在三星S3C44B0X CPU上的移植。ejoy it
💻 C
📖 第 1 页 / 共 2 页
字号:
	OSTCBCur->OSTCBDly = ticks;	EXIT_CRITICAL();	/* find a new task to run */	OSSched();} /* OSTimeDly *//* set system time */void	OSTimeSet(uint ticks){	ENTER_CRITICAL();	OSTime = ticks;	EXIT_CRITICAL();} /* OSTimeSet *//* get system time */uint	OSTimeGet(void){	return(OSTime);} /* OSTimeGet *//* create a semaphore */OS_EVENT*OSSemCreate(int value){	OS_EVENT	*pevent;	ENTER_CRITICAL();	/* get next available event CB */	pevent = OSEventFreeList;	/* update free list */	if (OSEventFreeList)		OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;	EXIT_CRITICAL();	if (pevent == (OS_EVENT *)0)		return((OS_EVENT *)0);	/* ran out of event CB */	if (value < 0) {		/* semaphore cannot start negative */		ENTER_CRITICAL();		/* return event CB back to the free list */		pevent->OSEventPtr = (void *)OSEventFreeList;		OSEventFreeList = pevent;		EXIT_CRITICAL();		return((OS_EVENT *)0);	}	/* 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;	return(pevent);} /* OSSemCreate */static voidOSEventTaskResume(OS_EVENT *pevent){	uint	x, y, bitx, bity, p;	OS_TCB	*ptcb;	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(); } /* OSEventTaskResume *//* signal semaphore */uint		OSSemPost(OS_EVENT *pevent){	ENTER_CRITICAL();	if (INT_MAX == pevent->OSEventCnt) {		/* semaphore overflow */		EXIT_CRITICAL();		return(OS_SEM_OVF);	}	if (pevent->OSEventCnt++ < 0) {		/* negative semaphore means tasks pending */		if (pevent->OSEventGrp) {			EXIT_CRITICAL();  			/* resume highest priority task pending on semaphore */			OSEventTaskResume(pevent);			OSSched();		}	} else		EXIT_CRITICAL();	return(OS_NO_ERR);} /* OSSemPost *//* wait semaphore */void		OSSemPend(OS_EVENT *pevent, uint timeout, uint *err){	ENTER_CRITICAL();	if (pevent->OSEventCnt-- > 0) {		/* resource available */		EXIT_CRITICAL();		*err = OS_NO_ERR;		return;	}	/* resource not available, sleep on semaphore */	OSTCBCur->OSTCBStat = OS_STAT_SEM;	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();	/* find next task ready to run */	OSSched();	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;		EXIT_CRITICAL();		/* signal timeout */		*err = OS_TIMEOUT;	}	else {		OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;		EXIT_CRITICAL();		*err = OS_NO_ERR;	}} /* OSSemPend *//* create mailbox */OS_EVENT*OSMboxCreate(void *msg){	OS_EVENT	*pevent;	ENTER_CRITICAL();	/* get next available event CB */	pevent = OSEventFreeList;	/* update free list */	if (OSEventFreeList)		OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;	EXIT_CRITICAL();	if (pevent == (OS_EVENT *)0)		return((OS_EVENT *)0);	/* ran out of event CB */	/* 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;	return(pevent);} /* OSMBoxCreate *//* post mbox message */uint		OSMboxPost(OS_EVENT *pevent, void *msg){	ENTER_CRITICAL();	/* make sure mailbox doesn't contain a message */	if (pevent->OSEventPtr != (void *)0) {		EXIT_CRITICAL();		return(OS_MBOX_FULL);	}	/* place message in mailbox */	pevent->OSEventPtr = msg;	/* see if any task is pending on the mailbox */	if (pevent->OSEventGrp) {		EXIT_CRITICAL();		/* resume highest priority task pending on mailbox */		OSEventTaskResume(pevent);		OSSched();	} else		EXIT_CRITICAL();	return(OS_NO_ERR);} /* OSMboxPost *//* pend for mbox message */void*OSMboxPend(OS_EVENT *pevent, uint timeout, uint *err){	void	*msg;	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();		*err = OS_NO_ERR;		/* return mailbox content */		return(msg);	}	/* resource not available, 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;	EXIT_CRITICAL();	/* find next task ready to run */	OSSched();	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;                EXIT_CRITICAL();                /* signal timeout */                *err = OS_TIMEOUT;	}	else {		/* message received */		msg = pevent->OSEventPtr;		/* clear the mailbox */		pevent->OSEventPtr = (void *)0;		EXIT_CRITICAL();		*err = OS_NO_ERR;	}	return(msg);} /* OSMBoxPend *//* create a queue */OS_EVENT*OSQCreate(void **start, uint size){	OS_EVENT	*pevent;	OS_Q		*pq;	ENTER_CRITICAL();	/* get next available event CB */	pevent = OSEventFreeList;	/* update free list */	if (OSEventFreeList)		OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;	if (pevent == (OS_EVENT *)0) {		/* ran out of event CB */		EXIT_CRITICAL();		return((OS_EVENT *)0);		}		pq = OSQFreeList;	if (OSQFreeList != (OS_Q *)0)		OSQFreeList = OSQFreeList->OSQPtr;		if (pq == (OS_Q *)0) {		/* ran out of queue CB return event CB to free list */		pevent->OSEventPtr = (void *)OSEventFreeList;		OSEventFreeList = pevent;		EXIT_CRITICAL();		return((OS_EVENT *)0);	}	EXIT_CRITICAL();	/* 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;	return(pevent);} /* OSQCreate *//* post a message to a queue */uint		OSQPost(OS_EVENT *pevent, void *msg){	OS_Q	*pq;	ENTER_CRITICAL();	pq = (OS_Q*)(pevent->OSEventPtr);	/* make sure the queue is not full */	if (pq->OSQEntries >= pq->OSQSize) {		EXIT_CRITICAL();		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 mailbox */	if (pevent->OSEventGrp) {		EXIT_CRITICAL();		/* resume highest priority task pending on mailbox */		OSEventTaskResume(pevent);		OSSched();	} else		EXIT_CRITICAL();	return(OS_NO_ERR);} /* OSQPost *//* pend for message from a queue */void*OSQPend(OS_EVENT *pevent, uint timeout, uint *err){	void	*msg;	OS_Q	*pq;	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();		*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();        /* find next task ready to run */        OSSched();        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;		EXIT_CRITICAL();		/* signal timeout */		*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;		EXIT_CRITICAL();		*err = OS_NO_ERR;	}		return(msg);} /* OSQPend *//* exit from interrupt */intOSIntExit(void){	uint	y;	ENTER_CRITICAL();	/* balanced by restoring PSR in IRQTrap */	if (--OSIntNesting == 0 && OSLockNesting == 0) {		/* reschedule if all ISR completed and not locked */		y = OSUnMapTbl[OSRdyGrp];		OSTCBHighRdy = OSTCBPrioTbl[(y << 3) + OSUnMapTbl[OSRdyTbl[y]]];		if (OSTCBHighRdy == OSTCBCur) {			/* the highest priority task is the current task */			return(FALSE);		}		else {			/* signal preemption to IRQTrap */			return(TRUE);		}	}	return(FALSE);} /* OSIntExit */

⌨️ 快捷键说明

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