📄 os_kernel.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 + -