📄 cxver5.c
字号:
}
#endif
link = (byte *)part + sizeof(byte *); /* address of 1st block */
*(byte **) part = link; /* point head at 1st block */
while (nblocks--)
{
part = link; /* skip to next block */
/* compute addr of next block */
link += bsize; /* compute addr of next block */
*(byte **) part = link; /* create link to it */
}
*(word16 **) part = 0; /* last link in chain is null */
}
/****************************************************************
this function passes a pointer of a free fixed memory block
if one is available, to the caller.
****************************************************************/
byte K_Mem_FB_Get(void *part,byte **addr)
{
byte *link; /* scratch pointer */
K_I_Disable_Sched(); /* prevent interruption by another task */
link = *(byte **) part; /* get head of free memory block */
if (link != NULL) /* exhausted if link is null */
{
*(byte **) part = *(byte **) link; /* update head */
*addr = link; /* load address of memory block to user pointer */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
if (CMXTRACKER_ON)
{
#if (defined(WINTRACKER))
cmxtracker_in1(CXBFGET_K_OK);
#else
cmxtracker_in5(CXBFGET_K_OK,0,link);
#endif
}
#endif
K_I_Func_Return(); /* release task block. */
return(K_OK); /* return good status. */
}
else
{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
if (CMXTRACKER_ON)
{
#if (defined(WINTRACKER))
cmxtracker_in1(CXBFGET_K_ERROR);
#else
cmxtracker_in5(CXBFGET_K_ERROR,0,part);
#endif
}
#endif
K_I_Func_Return(); /* release task block. */
return(K_ERROR); /* Error: no more memory blocks available */
}
}
/****************************************************************
this function releases fixed memory block, back into the fixed block
memory pool.
****************************************************************/
void K_Mem_FB_Release(void *part,byte *addr)
{
byte *link; /* scratch pointer */
K_I_Disable_Sched(); /* set task block. */
link = *(byte **) part; /* save old head of free memory */
*(byte **) addr = link; /* point released block at old head */
*(byte **) part = addr; /* point head at released block */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
if (CMXTRACKER_ON)
{
#if (defined(WINTRACKER))
cmxtracker_in1(CXBFREL_K_OK);
#else
cmxtracker_in5(CXBFREL_K_OK,0,addr);
#endif
}
#endif
K_I_Func_Return(); /* release task block. */
}
void K_OS_Start(void)
{
PROC_DISABLE_INT; /* disable interrupts. */
PREEMPTED; /* set preempted K_I_Scheduler flag. */
CMX_ACTIVE; /* identify that were CMX OS active. */
K_I_Scheduler(); /* invoke K_I_Scheduler */
}
/*******************************************************************
The following is the CMX timer task. This will see if any tasks
need their time counters decremented (because they have specified
a time period, and their waiting). If so then this will use the doubly
linked list of tasks that need their time counters decremented. Once a
task has its time counter decrement to 0, then the task will be place
into the RESUME state, and remove from the linked list.
Also the cyclic timers linked list will be tested to see if any cyclic
timers need their respective time counters decremented. If so then this
will use the doubly linked list of cyclic timers that need their time
counters decremented. Once a cyclic timer has its time counter decrement
to 0, then the cyclic timer will have its K_Event_Signal parameters executed
and also the cyclic time will be reloaded, if non zero.
****************************************************************/
void K_I_Timer_Task(void)
{
tcbpointer x;
struct _tcproc *tpptr;
tpptr = cyclic_lnk->ftlink; /* set pointer to cyclic linked list. */
while (tpptr != (struct _tcproc *)cyclic_lnk) /* test for done of list. */
{
if (!(--tpptr->tproc_timer)) /* decrement time counter and test. */
{
/* if 0, then reload time counter, with cyclic time. */
if ((tpptr->tproc_timer = tpptr->reload_time) == 0)
{
/* if cyclic time period 0, then stop cyclic timer
and remove from linked list. */
tpptr->tproc_start = 0;
tpptr->ftlink->btlink = tpptr->btlink;
tpptr->btlink->ftlink = tpptr->ftlink;
}
/* execute the cyclic timer's K_Event_Signal function parameters. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in2(TIMER_TASK_ACTION,(byte)(tpptr - tcproc));
}
#endif
K_Event_Signal(tpptr->mode,tpptr->tskid_pri,tpptr->event_num);
}
/* adjust pointer to next linked list member. */
tpptr = tpptr->ftlink;
} /* while loop */
/* set pointer to beginning of task timer link list. */
x = tsk_timer_lnk->ftlink;
while (x != (tcbpointer)tsk_timer_lnk) /* if not end of linked list. */
{
if (x->tcbstate & TIME) /* see if task really waiting on time out. */
{
if (!(--x->tcbtimer)) /* yes, go decrement the task time counter. */
{
/* if time expired, test to see if task waiting on resource. */
if (x->tcbstate & (RESOURCE | SEMAPHORE))
{
/* yes, remove task from resource wait linked list. */
x->fwlink->bwlink = x->bwlink;
x->bwlink->fwlink = x->fwlink;
}
/* set the task into the RESUME state. */
x->tcbstate = RESUME | TIME_EXPIRED;
/* indicate we should remove task from link list, this
will be done by the function that place this task
into the wait (sleep) state. This way we do NOT
waste time in here performing this. */
x->tcbtimer = 1;
if (x->priority < active_priority)
PREEMPTED; /* yes, set preempted scheduling flag */
}
}
x = x->ftlink; /* point to next link. */
}
} /* K_I_Timer_Task */
/*****************************************************************
Semaphore stuff
******************************************************************/
/*
Pend on semaphore, if count 0, otherwise return with semaphore
mode 0 : wait if semaphore not present
mode 1 : do NOT wait if semaphore not present, return immediatedly
*/
byte K_I_Semaphore_Get_Common(byte sem_num, word16 timecnt, byte mode)
{
SEM *sem_ptr;
if (sem_num >= MAX_SEMAPHORES)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in3(CXSEMPD_K_ERROR,sem_num,mode);
}
#endif
return(K_ERROR); /* return good status to caller */
}
K_I_Disable_Sched();
sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */
if (sem_ptr->fwlink == NULL)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in3(CXSEMPD_K_ERROR,sem_num,mode);
}
#endif
K_I_Func_Return(); /* release task block */
return(K_ERROR); /* return error status to caller */
}
if (!sem_ptr->sem_count)
{
if (mode)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXSEMPD_K_SEMAPHORE_NONE,sem_num);
}
#endif
K_I_Func_Return(); /* release task block */
return(K_SEMAPHORE_NONE); /* return error that semaphore
had not been posted to */
}
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in4(CXSEMPD_CALL,sem_num,timecnt);
}
#endif
if (sem_ptr->fwlink != (tcbpointer)sem_ptr) /* is at least one task waiting
on is semaphore */
{
activetcb->fwlink = sem_ptr->bwlink->fwlink;
sem_ptr->bwlink->fwlink = activetcb;
activetcb->bwlink = sem_ptr->bwlink;
sem_ptr->bwlink = activetcb;
}
else
{
sem_ptr->fwlink = sem_ptr->bwlink = activetcb;
activetcb->fwlink = activetcb->bwlink = (tcbpointer)sem_ptr;
}
if (K_I_Time_Common(timecnt,SEMAPHORE)) /* go suspend task. */
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in1(CXSEMPD_DELAY_K_TIMEOUT);
}
#endif
return(K_TIMEOUT); /* return the warning: that the time period expired */
}
else
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXSEMPD_K_OK1,sem_num);
}
#endif
return(K_OK);
}
}
--sem_ptr->sem_count;
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
if (mode)
cmxtracker_in4(CXSEMPD_K_OK,sem_num,sem_ptr->sem_count);
else
cmxtracker_in2(CXSEMPD_K_OK1,sem_num);
}
#endif
K_I_Func_Return();
return(K_OK);
} /* K_I_Semaphore_Get_Common */
byte K_Semaphore_Post(byte sem_num)
{
SEM *sem_ptr;
if (sem_num >= MAX_SEMAPHORES)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXSEMPST_K_ERROR,sem_num);
}
#endif
return(K_ERROR); /* return good status to caller */
}
K_I_Disable_Sched();
sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */
if (sem_ptr->fwlink == NULL)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXSEMPST_K_ERROR,sem_num);
}
#endif
K_I_Func_Return(); /* release task block */
return(K_ERROR); /* return error status to caller */
}
++sem_ptr->sem_count;
if (sem_ptr->fwlink != (tcbpointer)sem_ptr) /* does a task own this semaphore */
{
sem_ptr->fwlink->tcbstate = RESUME; /* allow task to run again */
if (sem_ptr->fwlink->priority < active_priority)
PREEMPTED; /* yes, so set the preempted scheduling flag */
if ((sem_ptr->fwlink = sem_ptr->fwlink->fwlink) == (tcbpointer)sem_ptr)
sem_ptr->bwlink = (tcbpointer)sem_ptr;
--sem_ptr->sem_count; /* reduce count again, because this task now
has semaphore */
}
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in4(CXSEMPST_K_OK,sem_num,sem_ptr->sem_count);
}
#endif
K_I_Func_Return(); /* release task block */
return(K_OK); /* return good status to caller */
} /* K_Semaphore_Post */
byte K_Semaphore_Create(byte sem_num, word16 n)
{
SEM *sem_ptr;
if (sem_num >= MAX_SEMAPHORES)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in4(CXSMINIT_K_ERROR,sem_num,n);
}
#endif
return(K_ERROR); /* return error status to caller */
}
K_I_Disable_Sched();
sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */
sem_ptr->fwlink = (tcbpointer)sem_ptr;
sem_ptr->bwlink = (tcbpointer)sem_ptr;
sem_ptr->sem_n = sem_ptr->sem_count = n;
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in4(CXSMINIT_K_OK,sem_num,sem_ptr->sem_count);
}
#endif
K_I_Func_Return(); /* release task block */
return(K_OK); /* return good status to caller */
}
/*
mode = 0 = do not flush if task owns semaphore
mode = 1 = do flush if task owns semaphore
also reset count to original value
*/
byte K_Semaphore_Reset(byte sem_num,byte mode)
{
SEM *sem_ptr;
if (sem_num >= MAX_SEMAPHORES)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in3(CXSEMFSH_K_ERROR,sem_num,mode);
}
#endif
return(K_ERROR); /* return error status to caller */
}
K_I_Disable_Sched();
sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */
if (sem_ptr->fwlink == NULL)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in3(CXSEMFSH_K_ERROR,sem_num,mode);
}
#endif
K_I_Func_Return(); /* release task block */
return(K_ERROR); /* return error status to caller */
}
if (sem_ptr->fwlink != (tcbpointer)sem_ptr) /* see if another task already "owns" this semaphore. */
{
if (!mode)
{
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in3(CXSEMFSH_K_ERROR,sem_num,mode);
}
#endif
K_I_Func_Return(); /* release task block. */
return(K_ERROR);
}
else
{
do {
sem_ptr->fwlink->tcbstate = RESUME | TIME_EXPIRED; /* allow task to run again */
if (sem_ptr->fwlink->priority < active_priority)
PREEMPTED; /* yes, so set the preempted scheduling flag */
if ((sem_ptr->fwlink = sem_ptr->fwlink->fwlink) == (tcbpointer)sem_ptr)
sem_ptr->bwlink = (tcbpointer)sem_ptr;
}
while(sem_ptr->fwlink != (tcbpointer)sem_ptr);
}
}
sem_ptr->sem_count = sem_ptr->sem_n;
#if (defined(WINTRACKER))
if (CMXTRACKER_ON)
{
cmxtracker_in4(CXSEMFSH_K_OK,sem_num,sem_ptr->sem_count);
}
#endif
K_I_Func_Return(); /* release task block. */
return(K_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -