📄 ucos.c
字号:
/*
************************************************************
* UCOS.C
* KERNEL
************************************************************
*/
#define UCOS_C //Required to stop GNU compiler complaining - DJF
#include "INCLUDES.H"
#ifdef TURBOC
#pragma inline
#endif
/*
************************************************************
* TABLES
************************************************************
*/
UBYTE const OSMapTbl[] = {0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80};
UBYTE 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 AND LOCAL VARIABLES
************************************************************
*/
OS_TCB *OSTCBCur;
OS_TCB *OSTCBHighRdy;
OS_TCB *OSTCBList;
OS_TCB *OSTCBPrioTbl[64];
BOOLEAN OSRunning;
UBYTE OSRdyGrp;
UBYTE OSRdyTbl[8];
UBYTE OSLockNesting;
UBYTE OSIntNesting;
OS_TCB *OSTCBFreeList;
/*
************************************************************
* LOCAL FUNCTION PROTOTYPES
************************************************************
*/
static void far OSTaskIdle(void *data);
/*
************************************************************
* uCOS INITIALIZATION
************************************************************
*/
void OSInit(void *idle_task_stk, UBYTE maxtasks)
{
UBYTE i;
OSTCBCur = (OS_TCB *)0;
OSTCBList = (OS_TCB *)0;
OSIntNesting = 0;
OSLockNesting = 0;
OSRunning = 0;
OSRdyGrp = 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 < (maxtasks - 1); i++) {
OSTCBTbl[i].OSTCBNext = &OSTCBTbl[i+1];
}
OSTCBTbl[maxtasks-1].OSTCBNext = (OS_TCB *)0;
OSTCBFreeList = &OSTCBTbl[0];
OSTaskCreate(OSTaskIdle, (void *)0, idle_task_stk, OS_LO_PRIO);
}
/*
************************************************************
* IDLE TASK
************************************************************
*/
static void far OSTaskIdle(void *data)
{
data = data;
while (1)
{
OS_IDLE_LOOP()
}
}
/*
************************************************************
* START MULTITASKING
************************************************************
*/
void OSStart(void)
{
UBYTE x, y, p;
y = OSUnMapTbl[OSRdyGrp];
x = OSRdyTbl[y];
p = (y << 3) + OSUnMapTbl[x];
OSTCBHighRdy = OSTCBPrioTbl[p];
OSTCBCur = OSTCBHighRdy;
OSRunning = 1;
OSStartHighRdy();
}
/*
************************************************************
* RUN HIGHEST PRIORITY TASK
************************************************************
*/
void OSSched(void)
{
UBYTE x, y, p;
OS_ENTER_CRITICAL();
if (OSLockNesting == 0 && OSIntNesting == 0) {
y = OSUnMapTbl[OSRdyGrp];
x = OSRdyTbl[y];
p = (y << 3) + OSUnMapTbl[x];
OSTCBHighRdy = OSTCBPrioTbl[p];
if (OSTCBHighRdy != OSTCBCur) {
OS_TASK_SW();
}
}
OS_EXIT_CRITICAL();
}
/*
************************************************************
* ENTER ISR
************************************************************
*/
void OSIntEnter(void)
{
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
}
/*
************************************************************
* EXIT ISR
************************************************************
*/
void OSIntExit(void)
{
UBYTE x, y, p;
OS_ENTER_CRITICAL();
if (--OSIntNesting == 0 && OSLockNesting == 0) {
y = OSUnMapTbl[OSRdyGrp];
x = OSRdyTbl[y];
p = (y << 3) + OSUnMapTbl[x];
OSTCBHighRdy = OSTCBPrioTbl[p];
if (OSTCBHighRdy != OSTCBCur) {
OSIntCtxSw();
}
}
OS_EXIT_CRITICAL();
}
/*
************************************************************
* DELAY TASK 'n' TICKS (n from 1 to 65535)
************************************************************
*/
void OSTimeDly(UWORD ticks)
{
UBYTE p;
OS_ENTER_CRITICAL();
p = OSTCBCur->OSTCBPrio;
if ((OSRdyTbl[p >> 3] &= ~OSMapTbl[p & 0x07]) == 0) {
OSRdyGrp &= ~OSMapTbl[p >> 3];
}
OSTCBCur->OSTCBDly = ticks;
OS_EXIT_CRITICAL();
OSSched();
}
/*
************************************************************
* PROCESS SYSTEM TICK
************************************************************
*/
void OSTimeTick(void)
{
UBYTE p;
OS_TCB *ptcb;
ptcb = OSTCBList;
while (ptcb->OSTCBPrio != OS_LO_PRIO) {
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) {
if (--ptcb->OSTCBDly == 0) {
p = ptcb->OSTCBPrio;
OSRdyGrp |= OSMapTbl[p >> 3];
OSRdyTbl[p >> 3] |= OSMapTbl[p & 0x07];
}
}
OS_EXIT_CRITICAL();
ptcb = ptcb->OSTCBNext;
}
}
/*
************************************************************
* GET TCB FROM FREE TCB LIST
************************************************************
*/
OS_TCB *OSTCBGetFree(void)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
ptcb = OSTCBFreeList;
OSTCBFreeList = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
return (ptcb);
}
/*
************************************************************
* PREVENT SCHEDULING
************************************************************
*/
void OSLock(void)
{
OS_ENTER_CRITICAL();
OSLockNesting++;
OS_EXIT_CRITICAL();
}
/*
************************************************************
* ENABLE SCHEDULING
************************************************************
*/
void OSUnlock(void)
{
OS_ENTER_CRITICAL();
OSLockNesting--;
OS_EXIT_CRITICAL();
OSSched();
}
/*
************************************************************
* CHANGE PRIORITY OF RUNNING TASK
************************************************************
*/
UBYTE OSChangePrio(UBYTE newp)
{
UBYTE oldp;
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[newp] != (void *)0) {
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
} else {
oldp = OSTCBCur->OSTCBPrio;
if ((OSRdyTbl[oldp >> 3] &= ~OSMapTbl[oldp & 0x07]) == 0) {
OSRdyGrp &= ~OSMapTbl[oldp >> 3];
}
OSRdyGrp |= OSMapTbl[newp >> 3];
OSRdyTbl[newp >> 3] |= OSMapTbl[newp & 0x07];
OSTCBCur->OSTCBPrio = newp;
OSTCBPrioTbl[newp] = OSTCBCur;
OSTCBPrioTbl[oldp] = (void *)0;
OS_EXIT_CRITICAL();
OSSched();
return (OS_NO_ERR);
}
}
/*
************************************************************
* DELETE RUNNING TASK
************************************************************
*/
void OSTaskDelete(void)
{
UBYTE p;
OS_ENTER_CRITICAL();
p = OSTCBCur->OSTCBPrio;
OSTCBPrioTbl[p] = (OS_TCB *)0;
if ((OSRdyTbl[p >> 3] &= ~OSMapTbl[p & 0x07]) == 0) {
OSRdyGrp &= ~OSMapTbl[p >> 3];
}
if (OSTCBCur->OSTCBPrev == (OS_TCB *)0) {
OSTCBCur->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
OSTCBList = OSTCBCur->OSTCBNext; /* Rev. A, This line was missing */
} else {
OSTCBCur->OSTCBPrev->OSTCBNext = OSTCBCur->OSTCBNext;
OSTCBCur->OSTCBNext->OSTCBPrev = OSTCBCur->OSTCBPrev;
}
OSTCBCur->OSTCBNext = OSTCBFreeList;
OSTCBFreeList = OSTCBCur;
OS_EXIT_CRITICAL();
OSSched();
}
/*
************************************************************
* INITIALIZE SEMAPHORE
************************************************************
*/
UBYTE OSSemInit(OS_SEM *psem, WORD cnt)
{
OS_ENTER_CRITICAL();
if (cnt >= 0) {
psem->OSSemCnt = cnt;
psem->OSSemGrp = 0x00;
psem->OSSemTbl[0] = 0x00;
psem->OSSemTbl[1] = 0x00;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -