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

📄 os.c

📁 UCSO在三星S3C44B0X CPU上的移植。ejoy it
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: os.c * * uC/OS Real-time multitasking kernel for the ARM processor. * * Kernel functions. * * Created by Jean J. Labrosse.  * ARM port by Marco Graziano (marcog@crl.com). * */#include	"ucos.h"#include	"pid.h"#include	"osdefs.h"#pragma         no_check_stack/* let's stay on the safe side */#pragma         no_optimise_crossjump#pragma         no_optimise_multiple_loads#pragma         no_optimise_cse/* mapping table to map bit position to bit mask */uint const OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };/* priority resolution table */uint 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,};/* global variables */uint    OSCtxSwCtr;             /* context switches counter */uint    OSIdleCtr;              /* idle counter */uint    OSRunning = 0;              /* kernel running flag */uint	OSIntNesting;		/* interrupt nesting level */OS_TCB  *OSTCBCur;              /* current running TCB pointer */OS_TCB  *OSTCBHighRdy;          /* highest priority TCB ready to run */OS_TCB  *OSTCBPrioTbl[64];	/* table of pointers to created TCBs */ /* local variables */static	OS_TCB	*OSTCBList;	/* TCBs doubled linked list */static	uint	OSRdyGrp;	/* ready list group */static	uint	OSRdyTbl[8];	/* table of ready to run tasks */static	uint	OSLockNesting;	/* multitasking lock nesting level */static	OS_TCB	*OSTCBFreeList;	/* free TCBs list */static	OS_EVENT *OSEventFreeList;	/* free EVENT CB list */static	OS_Q	*OSQFreeList;		/* free QUEUE CB list */static	uint	OSTime;			/* system time in ticks */static	uint	OSIdleStk[OS_IDLE_STK_SIZE];	/* idle task stack */static	OS_TCB	OSTCBTbl[OS_MAX_TASKS + 1];	/* TCBs table */static	OS_EVENT OSEventTbl[OS_MAX_EVENTS];	/* EVENT CBs table */static	OS_Q	OSQTbl[OS_MAX_QS];		/* QUEUE CBs table *//* idle task */static voidOSTaskIdle(void *data){	for (;;) {		ENTER_CRITICAL();		OSIdleCtr++;		EXIT_CRITICAL();	}} /* OSTaskIdle *//* process system tick */static voidOSTimeTick(void){	OS_TCB	*ptcb = OSTCBList;	/* define PIDLED if you would like to see the PID leds */#ifdef	PIDLED	static int Counter = 0;	static int Timer = 0;	extern	void SetLED(uint);#endif	/* PIDLED */	ENTER_CRITICAL();	OSTime++;	EXIT_CRITICAL();#ifdef	PIDLED	/* every second change LEDs */	if (Timer++ == 100) {		if (++Counter > 0x0F)			Counter= 0;		SetLED(Counter);		Timer = 0;	}#endif /* PIDLED */	/* scan all TCB in list */	ENTER_CRITICAL(); 	for ( ; ptcb->OSTCBPrio != OS_LO_PRIO; ptcb = ptcb->OSTCBNext) { 		if (ptcb->OSTCBDly)			if (--ptcb->OSTCBDly == 0) {				/* task is now ready to run */				OSRdyGrp |= ptcb->OSTCBBitY;				OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;			}	}	EXIT_CRITICAL(); } /* OSTimeTick *//* initialize uC/OS */void	OSInit(void){	static void __swi(OSEnterSWI) OSEnter(void);	extern	void PIDInit(void);	int	i;	/* initialize PID hardware */	PIDInit();	/* enter supervisor mode and disable interrupts */	OSEnter(); 	/* initialize variables */	OSTime = 0;	OSTCBHighRdy = (OS_TCB *)0;	OSTCBCur = (OS_TCB *)0;	OSTCBList = (OS_TCB *)0;	OSIntNesting = 0;	OSLockNesting = 0;	OSRunning = FALSE;	OSRdyGrp = 0;	OSIdleCtr = 0;	OSCtxSwCtr = 0;	for (i = 0; i < 8; i++) 		OSRdyTbl[i] = 0;	for (i = 0; i < 64; i++) 		OSTCBPrioTbl[i] = (OS_TCB *)0;	for (i = 0; i < OS_MAX_TASKS; i++)		OSTCBTbl[i].OSTCBNext = &OSTCBTbl[i + 1];	OSTCBTbl[OS_MAX_TASKS].OSTCBNext = (OS_TCB *)0;	OSTCBFreeList = &OSTCBTbl[0];	for (i = 0; i < OS_MAX_EVENTS - 1; i++)		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++)		OSQTbl[i].OSQPtr = &OSQTbl[i + 1];	OSQTbl[OS_MAX_QS - 1].OSQPtr = (OS_Q *)0;	OSQFreeList = &OSQTbl[0];	/* create the idle task */	OSTaskCreate(OSTaskIdle, (void *)0, 		(void *)&OSIdleStk[OS_IDLE_STK_SIZE], OS_LO_PRIO);} /* OSInit *//* start multitasking */void	OSStart(void){	extern void OSStartHighRdy(void);	/* defined in subr.s */	extern  PFV IRQInstall(int, PFV);	uint	y, x, p;	/* find the highest priority task */	y = OSUnMapTbl[OSRdyGrp];	x = OSUnMapTbl[OSRdyTbl[y]];	p = (y << 3) + x;	OSTCBHighRdy = OSTCBPrioTbl[p];	/* install timer interrupt routine */	IRQInstall(TimerIRQNum, OSTimeTick);    	OSRunning = 1;	/* enable interrupts and run the highest priority task */	OSStartHighRdy();} /* OSStart *//* uC/OS scheduler */static voidOSSched(void){	extern void OSCtxSw(void);	/* defined in subr.s */	uint	y;	ENTER_CRITICAL();   	if (OSLockNesting == 0 && OSIntNesting == 0) {		/* task scheduling enabled and not interrupt level */		y = OSUnMapTbl[OSRdyGrp];		OSTCBHighRdy = OSTCBPrioTbl[(y << 3) + OSUnMapTbl[OSRdyTbl[y]]];		/* make sure this is not the current running task */		if (OSTCBHighRdy != OSTCBCur) {			OSCtxSwCtr++;			OSCtxSw();	/* context switch */		}	}	EXIT_CRITICAL();   } /* OSSched *//* prevent scheduling */void	OSSchedLock(void){	ENTER_CRITICAL();	OSLockNesting++;	EXIT_CRITICAL();} /* OSSchedLock *//* allow scheduling */void	OSSchedUnlock(void){	ENTER_CRITICAL();	if (OSLockNesting == 0) {		EXIT_CRITICAL();		return;	}	OSLockNesting--;	if (OSLockNesting == 0 && OSIntNesting == 0) {		/* scheduling re-enabled and not an ISR */		EXIT_CRITICAL();		/* check if a higher priority task became ready */		OSSched();	} else		EXIT_CRITICAL();} /* OSSchedUnlock *//* find and initialize a TCB */static intOSTCBInit(uint	prio, void *pstk){	OS_TCB	*ptcb;	ENTER_CRITICAL(); 	if ((ptcb = OSTCBFreeList) == (OS_TCB *)0) {		/* no TCB available */		EXIT_CRITICAL(); 		return(OS_NO_MORE_TCB);	}	OSTCBFreeList = ptcb->OSTCBNext;	/* link to the next free */	OSTCBPrioTbl[prio] = ptcb;	ptcb->OSTCBStkPtr = pstk;		/* top of private stack */	ptcb->OSTCBPrio = prio;			/* task priority */	ptcb->OSTCBStat = OS_STAT_RDY;		/* task is ready to run */	ptcb->OSTCBDly = 0;	ptcb->OSTCBX = prio & 0x07;	ptcb->OSTCBBitX = OSMapTbl[prio & 0x07];	ptcb->OSTCBY = prio >> 3;	ptcb->OSTCBBitY = OSMapTbl[prio >> 3];	ptcb->OSTCBEventPtr = (OS_EVENT *)0;	ptcb->OSTCBNext = OSTCBList;	if (OSTCBList)		ptcb->OSTCBPrev = ptcb;	else		ptcb->OSTCBPrev = (OS_TCB *)0;	OSTCBList = ptcb;	OSRdyGrp |= OSMapTbl[prio >> 3];	OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];	EXIT_CRITICAL(); 	return(OS_NO_ERR);} /* OSTCBInit *//* create a task */int	OSTaskCreate(PTV task, void *pdata, void *ptsk, uint prio){	uint	*stk;	int	Ret;	ENTER_CRITICAL(); 	if (OSTCBPrioTbl[prio] != (OS_TCB *)0) {		/* only one task allowed at its priority */		EXIT_CRITICAL(); 		Ret = OS_PRIO_EXIST;	}	else {		EXIT_CRITICAL(); 		stk = (uint *)ptsk;		/* build a context for the new task */	   	*--stk = (uint)task;	/* lr */		*--stk = 0;    		/* r12 */		*--stk = 0;		/* r11 */		*--stk = 0;		/* r10 */		*--stk = 0;		/* r9 */		*--stk = 0;		/* r8 */		*--stk = 0;		/* r7 */		*--stk = 0;		/* r6 */		*--stk = 0;		/* r5 */		*--stk = 0;		/* r4 */		*--stk = 0;		/* r3 */		*--stk = 0;		/* r2 */		*--stk = 0;		/* r1 */		*--stk = (uint)pdata;   /* r0 */		*--stk = SVC32MODE;  	/* spsr YYY+ */		*--stk = SVC32MODE;  	/* psr */		Ret = OSTCBInit(prio, (void *)stk);		if (Ret == OS_NO_ERR && OSRunning) 			OSSched();	}	return(Ret);} /* OSCreateTask *//* delete a task */int	OSTaskDel(uint prio){	OS_EVENT	*pevent;	OS_TCB	*ptcb;	if (prio == OS_LO_PRIO)		return(OS_TASK_DEL_IDLE);	ENTER_CRITICAL();	if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) {		EXIT_CRITICAL();		return(OS_TASK_DEL_ERR);	}	/* clear old TCB entry */	OSTCBPrioTbl[prio] = (OS_TCB *)0;	/* make task not ready */	if ((OSRdyTbl[ptcb->OSTCBY] &= ~(ptcb->OSTCBBitX)) == 0)		OSRdyGrp &= ~(ptcb->OSTCBBitY);	/* remove from TCB linked list */	if (ptcb->OSTCBPrev == (OS_TCB *)0) {		ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;		OSTCBList = ptcb->OSTCBNext;	}	else {		ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;		ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;	}	/* if task waiting on event remove it from event CB */	if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0) 		if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)			pevent->OSEventGrp &= ~(ptcb->OSTCBBitY);	/* return TCB to the free list */	ptcb->OSTCBNext = OSTCBFreeList;	OSTCBFreeList = ptcb;	EXIT_CRITICAL();	/* find new highest priority task */	OSSched();	return(OS_NO_ERR);} /* OSTaskDel *//* change task priority */int	OSTaskChangePrio(uint oldp, uint newp){	OS_EVENT	*pevent;	OS_TCB	*ptcb;	int	rdy;	ENTER_CRITICAL();	/* check if new priority not in use */	if (OSTCBPrioTbl[newp] != (OS_TCB *)0) {		EXIT_CRITICAL();		return(OS_PRIO_EXIST);	}	/* check if old priority task exists */	if (OSTCBPrioTbl[oldp] == (OS_TCB *)0) {		EXIT_CRITICAL();		return(OS_PRIO_ERR);	}	/* remove TCB from old priority */	OSTCBPrioTbl[oldp] = (OS_TCB *)0;	/* if task is ready make it not ready */	if (OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) {		if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)			OSRdyGrp &= ~(ptcb->OSTCBBitY);		rdy = TRUE;	} else 		rdy = FALSE;	/* remove from event list */	if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0)		if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)			pevent->OSEventGrp &= ~ptcb->OSTCBBitY;	/* remove from TCB linked list */	if (ptcb->OSTCBPrev == (OS_TCB *)0) {		ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;		OSTCBList = ptcb->OSTCBNext;	}	else {		ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;		ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;	}	EXIT_CRITICAL();	/* setup task control block with new values */	ptcb->OSTCBPrio = newp;	ptcb->OSTCBY = newp >> 3;	ptcb->OSTCBBitY = OSMapTbl[newp >> 3];	ptcb->OSTCBX = newp & 0x07;	ptcb->OSTCBBitX = OSMapTbl[newp & 0x07];	ENTER_CRITICAL();	/* make new priority ready to run if old one was ready */	if (rdy) {		OSRdyGrp |= ptcb->OSTCBBitY;		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;		}	}	/* place TCB pointer at the new priority */	OSTCBPrioTbl[newp] = ptcb;	/* link TCB to the top of the list */	OSTCBList->OSTCBPrev = ptcb;	OSTCBList = ptcb;	/* at least the idle task is in the list */	EXIT_CRITICAL();	/* run highest priority task ready */	OSSched();	return(OS_NO_ERR);} /* OSTaskChangePrio *//* delay the current task */void	OSTimeDly(uint ticks){	ENTER_CRITICAL();	/* suspend the current task */	if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)		OSRdyGrp &= ~OSTCBCur->OSTCBBitY;	/* load number of ticks in TCB */

⌨️ 快捷键说明

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