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

📄 os_kernel.cpp

📁 易能嵌入式操作系统E_LAND1.0.0_LPC2106_DS12.rar
💻 CPP
字号:
//==========================================================================================
//--文件名:OS_KERNEL.cpp
//--
//--功  能:完成系统内核的功能
//--
//--作  者:陈  斌
//--
//--版本号:v1.00
//--
//--时  间:2006.12.31
//==========================================================================================
#ifndef	OS_KERNEL_CPP
#define OS_KERNEL_CPP
#include <E_LAND.H>
void OS_PRITAB::operator=(UINT8 i)
{
	UINT8 j;
	for(j=0; j<DOS_PTAB; j++)
	{
		PriTB[j] = i;
	}
	PriTA = i;
}
OS_PCB::OS_PCB()
{
}
void OS_PCB::operator=(OS_PID i)
{
	Prio = i;
	A = (i>>3)&0x0007;
	BitA = 1<<A;
	B =  i&0x0007;
	BitB = 1<<B;
}
void OS_PCB::Recur()
{
	pOSTcbRun[Prio] = pOSTcbRun[Prio]->pTaskN;
	OSSched();
}
OS_TCB::OS_TCB(void(*pTask)(void *pd),void* pData,STACK* pStack,STASIZE SizeStack,OS_PID Pri,CCBMD Mod,UINT8 Usu)
{
	ASSERT((pTask != 0),(pStack != 0),(Pri < DOS_PMAX),(SizeStack != 0),ERR_CCB_CREA);
	Init();
	pTime = NULL;
	Attri = 0;
	Mode = Mod;
	pPcb = &OSPri[Pri];
	#if (DOS_STACHE == EN)
	pTop = pStack;
	StackFree = SizeStack;
	#endif
	Usuf = Tick = Usu;
	pContext = CPUCcbStkInit(pStack+SizeStack, pTask, pData, Mod);
	OS_ENTER_CRITICAL();
	ppCcb = &(pOSTcbRun[pPcb->Prio]);
	Shift(NULL, ppCcb);
	Ready();
	OS_EXIT_CRITICAL();
}
void OS_TCB::Init()
{
	#if DOS_STACHE == EN
	StackFree = NULL;
	#endif
	#if (DOS_STACHE == EN)
	pTop = NULL;
	#endif
	ppCcb = NULL;
	pTaskF = NULL;
	pTaskN = NULL;
	pPcb = NULL;
	pPritab = &OSPriReady;
	DelayTime = NULL;
	Deep = NULL;
	Tick = NULL;
	Usuf = NULL;
	TcbErr = NULL;
	CRITCOU = NULL;
	pCcb = pOSTcbCur;
}
void OS_TCB::Shift(OS_TCB** pTcbS, OS_TCB** pTcbD)
{
	if(pTcbS != NULL)
	{
		if(pTaskF != NULL)
		{
			{
				if(pTaskF != this)
				{
					if(*pTcbS == this)
					{
						*pTcbS = pTaskN;
					}
					pTaskF->pTaskN = pTaskN;
					pTaskN->pTaskF = pTaskF;
				}
				else
				{
					*pTcbS = NULL;
				}
			}
		}
	}
	if(pTcbD != NULL)
	{
		if(*pTcbD == NULL)
		{
			pTaskF = pTaskN = this;
			*pTcbD = this;
		}
		else
		{
			pTaskN = *pTcbD;
			pTaskF = (*pTcbD)->pTaskF;
			(*pTcbD)->pTaskF->pTaskN = this;
			(*pTcbD)->pTaskF = this;
		}
	}
	else
	{
		pTaskF = NULL;
	}
}
void OS_TCB::ChangPri(OS_PID Pid)
{
	OS_TCB** pptccb;
	OS_PID d;
	ASSERT((Pid<DOS_PMAX),1,1,1,ERR_PRI_OVE);
	if((&OSPri[Pid]) != pPcb)
	{
		OS_ENTER_CRITICAL();
		if(pPcb->Prio > Pid)
		{
			d = pPcb->Prio - Pid;
			pptccb = ppCcb - d;
		}
		else
		{
			d = Pid - pPcb->Prio;
			pptccb = ppCcb + d;
		}
		if(pTaskF != NULL)
		{
			Shift(ppCcb, pptccb);
			Unready();
		}
		pPcb = &OSPri[Pid];
		ppCcb = pptccb;
		Ready();
		OSSched();
		OS_EXIT_CRITICAL();
	}
}
void OS_TCB::Sleep()
{
	OS_ENTER_CRITICAL();
	if(Deep++ == 0)
	{
		Shift(ppCcb,NULL);
		Unready();
		if(DelayTime != 0)
		{
			DelayTime -= OSDelayTick;
		}
		if(this == pOSTcbCur)
		{
			OSSched();
		}
	}
	OS_EXIT_CRITICAL();
}
void OS_TCB::Wake()
{
	if(Deep != 0)
	{
		OS_ENTER_CRITICAL();
		if(--Deep == 0)
		{
			{
				Shift(ppCcb,ppCcb);
				Ready();
				{
					Delay(DelayTime);
				}
				OSSched();
			}
		}
		OS_EXIT_CRITICAL();
	}
}
void OS_TCB::Delay(UINT16 h,UINT16 m,UINT16 s,UINT16 ms)
{
	TIMETYPE time;
	time = ((TIMETYPE)h*3600+(TIMETYPE)m*60+(TIMETYPE)s)*1000+ms;
	Delay(time/(1000/DOS_SECTICK)+(time%(1000/DOS_SECTICK)+5)/10);
}
void OS_TCB::Delay(TIMETYPE time)
{
	if((STIMETYPE)time > 0)
	{
		OS_ENTER_CRITICAL();
		{
			if(Deep == NULL)
			{
				TcbErr = ERR_NONE;
				if(pTime == 0)
				{
					Shift(ppCcb, NULL);
					Unready();
					DelayOper(time);
					goto delaybreak;
				}
				else
				{
					time += OSDelayTick;
				}
			}
		}
		if(time > DelayTime)
		{
			DelayTime = time;
		}
		delaybreak:
		OS_EXIT_CRITICAL();
	}
}
void OS_TCB::Delayms(TIMETYPE time)
{
	Delay(time/(1000/DOS_SECTICK)+
		(time%(1000/DOS_SECTICK)+5*(100/DOS_SECTICK))/10);
}
void OS_TCB::DelayOper(TIMETYPE time)
{
	if(pTime == NULL)
	{
		pTime = pOSDelayCcb;
		pOSDelayCcb = this;
	}
	DelayTime = time+OSDelayTime-OSDelayTick;
	if(DelayTime < OSDelayTick || OSDelayTime == 0)
	{
		OSDelayTime = DelayTime;
		OSDelayTick = time;
	}
	OSSched();
}
void OS_TCB::Ready()
{
	if(*ppCcb != 0)
	{
		pPritab->PriTA |= pPcb->BitA;
		pPritab->PriTB[pPcb->A] |= pPcb->BitB;
	}
}
void OS_TCB::Unready()
{
	if(*ppCcb == 0)
	{
		#if DOS_PMAX > 64
		pPritab->PriTC[pPcb->A][pPcb->B] &= ~(pPcb->BitC);
		if(pPritab->PriTC[pPcb->A][pPcb->B] == NULL)
		{
			pPritab->PriTB[pPcb->A]&= ~(pPcb->BitB);
		}
		if(pPritab->PriTB[pPcb->A] == NULL)
		{
			pPritab->PriTA &= ~(pPcb->BitA);
		}
		#else
		#if DOS_PMAX > 8
		pPritab->PriTB[pPcb->A] &= ~(pPcb->BitB);
		if(pPritab->PriTB[pPcb->A] == NULL)
		{
			pPritab->PriTA &= ~(pPcb->BitA);
		}
		#else
		pPritab->PriTA &= ~(pPcb->BitA);
		#endif
		#endif
	}
}
void OS_TCB::ExitDelay()
{
	OS_ENTER_CRITICAL();
	DelayTime = NULL;
	if(Deep == NULL)
	{
		{
			Shift(NULL,ppCcb);
			Ready();
			OSSched();
		}
	}
	OS_EXIT_CRITICAL();
}
#if DOS_EVENT == EN
OS_ETCB::OS_ETCB(void(*pTask)(void *pd),void* pData,STACK* pStack,STASIZE SizeStack,OS_PID Pri,CCBMD Mod,UINT16 Usu)
:OS_TCB(pTask,pData,pStack,SizeStack,Pri,Mod,Usu)
{
	Attri = 1;
}
void OS_ETCB::WaitEve(OS_ECB*pTEcb,TIMETYPE Time)
{
	TcbErr = DEF_EVE_WAITE;
	OS_TCB** ppccb;
	pEcb = pTEcb;
	ppccb = &(pTEcb->ppAppTab[pPcb->Prio]);
	Shift(ppCcb,ppccb);
	Unready();
	ppCcb = ppccb;
	pPritab = &(pTEcb->Pritab);
	Ready();
	if(Time != DOS_UNLIMIT)
	{
		if(pTime == 0)
		{
			DelayOper(Time);
			return;
		}
	}
	OSSched();
}
#if DOS_MUTEX == EN
UINT8 OS_ETCB::AppMutex(OS_EID Eid, TIMETYPE Time)
{
	UINT8 i;
	OS_FLAGS TPrio;
	OS_ECB* pTEcb = &OSEcb[Eid];
	ASSERT(pTEcb->EStat==EVE_MUTEX, 1, 1, 1, ERR_EVE_MAPP);
	ASSERT(CPUintTst() != 0, 1, 1, 1, ERR_EVE_MAPP);
	TcbErr = ERR_NONE;
	OS_ENTER_CRITICAL();
	do
	{
		if(pTEcb->pMixed == 0)
		{
			pTEcb->pMixed = this;
			pTEcb->Flags = pPcb->Prio;
			i = 1;
			break;
		}
		TPrio = ((OS_ETCB*)(pTEcb->pMixed))->pPcb->Prio;
		if((pPcb->Prio) < TPrio)
		{
			((OS_ETCB*)(pTEcb->pMixed))->ChangPri(pPcb->Prio);
		}
		if(Time == 0)
		{
			i = 0;
			break;
		}
		ASSERT(Attri > 0, 1, 1, 1, ERR_EVE_CCB);
		WaitEve(pTEcb, Time);
	}
	while(TcbErr == DEF_EVE_WAITE);
	OS_EXIT_CRITICAL();
	return i;
}
#endif
#if DOS_SEM == EN
OS_FLAGS OS_ETCB::AppSem(OS_EID Eid, TIMETYPE Time)
{
	OS_FLAGS i;
	OS_ECB* pTEcb = &OSEcb[Eid];
	ASSERT(pTEcb->EStat == EVE_SEM, 1, 1, 1, ERR_EVE_SAPP);
	ASSERT(CPUintTst() != 0, 1, 1, 1, ERR_EVE_MAPP);
	TcbErr = ERR_NONE;
	OS_ENTER_CRITICAL();
	do
	{
		i = pTEcb->Flags;
		if(i != 0)
		{
			pTEcb->Flags--;
			break;
		}
		if(Time == 0)
		{
			break;
		}
		ASSERT(Attri > 0, 1, 1, 1, ERR_EVE_CCB);
		WaitEve(pTEcb, Time);
	}
	while(TcbErr == DEF_EVE_WAITE);
	OS_EXIT_CRITICAL();
	return i;
}
#endif
#if DOS_MESSAGE == EN
void* OS_ETCB::AppMessage(OS_EID Eid, TIMETYPE Time)
{
	void* pMes;
	OS_ECB* pTEcb = &OSEcb[Eid];
	ASSERT(pTEcb->EStat == EVE_MESSAGE, 1, 1, 1, ERR_EVE_MEAPP);
	ASSERT(CPUintTst() != 0, 1, 1, 1, ERR_EVE_MAPP);
	TcbErr = ERR_NONE;
	OS_ENTER_CRITICAL();
	do
	{
		if(pTEcb->pMixed != 0)
		{
			pMes = pTEcb->pMixed;
			OS_EXIT_CRITICAL();
			pTEcb->pMixed = 0;
			return pMes;
		}
		if(Time == 0)
		{
			break;
		}
		ASSERT(Attri > 0, 1, 1, 1, ERR_EVE_CCB);
		WaitEve(pTEcb, Time);
	}
	while(TcbErr == DEF_EVE_WAITE);
	OS_EXIT_CRITICAL();
	return 0;
}
#endif
void OS_ECB::operator=(char i)
{
	char j;
	if(i == 0)
	{
		if(pOSEcbFree == NULL)
		{
			EidF = EidN = Eid;
		}
		else
		{
			EidN = pOSEcbFree->Eid;
			EidF = pOSEcbFree->EidF;
			pOSEcbFree->EidF = Eid;
			OSEcb[EidF].EidN = Eid;
		}
		pOSEcbFree = this;
		for(j = 0; j < DOS_PMAX; j++)
		{
			ppAppTab[j] = NULL;
		}
		EStat = 0;
		Flags = 0;
		Pritab = 0;
		pMixed = 0;
	}
}
void OS_ECB::ReadyEccb()
{
	OS_ETCB* peccb;
	OS_TCB** ppccb;
	OS_PID pid;
	pid = OSInde(&Pritab);
	if(pid != DOS_PMAX)
	{
		peccb = (OS_ETCB*)(ppAppTab[pid]);
		ppccb = &(pOSTcbRun[pid]);
		peccb->Shift(peccb->ppCcb,ppccb);
		peccb->Unready();
		peccb->ppCcb = ppccb;
		peccb->pPritab = &OSPriReady;
		peccb->Ready();
		OSSched();
	}
}
#if DOS_MUTEX == EN
void OS_ECB::EcbSendMutex()
{
	OS_PID i;
	OS_TCB* p;
	ASSERT(EStat == EVE_MUTEX, 1, 1, 1, ERR_EVE_MSEND);
	if((OS_TCB*)pMixed == pOSTcbCur)
	{
		i = (OS_PID) Flags;
		p = (OS_TCB*)pMixed;
		pMixed = NULL;
		OS_ENTER_CRITICAL();
		ReadyEccb();
		p->ChangPri(i);
		OS_EXIT_CRITICAL();
	}
}
#endif
#if DOS_SEM == EN
void OS_ECB::EcbSendSem()
{
	ASSERT(EStat == EVE_SEM, 1, 1, 1, ERR_EVE_SSEND);
	OS_ENTER_CRITICAL();
	Flags++;
	ReadyEccb();
	OS_EXIT_CRITICAL();
}
void OS_ECB::SetSem(OS_FLAGS Max)
{
	ASSERT(EStat == EVE_SEM, 1, 1, 1, ERR_EVE_SSEND);
	if(EStat == EVE_SEM)
	{
		Flags = Max;
	}
}
#endif
#if DOS_MESSAGE == EN
void OS_ECB::EcbSendMessage(void *pMes)
{
	ASSERT(EStat == EVE_MESSAGE, 1, 1, 1, ERR_EVE_MESEND);
	OS_ENTER_CRITICAL();
	pMixed = pMes;
	ReadyEccb();
	OS_EXIT_CRITICAL();
}
#endif
#endif
#endif

⌨️ 快捷键说明

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