📄 picoos.c
字号:
next->prev = newlist->prev;
newlist->prev->next = next;
newlist->prev = prev;
prev->next = newlist;
}
#endif
static void pos_listRemove(POSLIST_t *listelem)
{
register POSLIST_t *prev, *next;
prev = listelem->prev;
next = listelem->next;
next->prev = prev;
prev->next = next;
#ifdef _DBG
#if POSCFG_FEATURE_LISTLEN != 0
listelem->head = NULL;
#endif
#endif
}
#endif /* POSCFG_FEATURE_LISTS */
static void pos_idletask(void *arg)
{
POS_LOCKFLAGS;
(void) arg;
for(;;)
{
#if POSCFG_FEATURE_INHIBITSCHED != 0
P_ASSERT("pos_idletask: schedule allowed", posInhibitSched_g == 0);
#endif
POS_SCHED_LOCK;
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_schedule();
POS_SCHED_UNLOCK;
HOOK_IDLETASK
#if POSCFG_FEATURE_IDLETASKHOOK != 0
if (posIdleTaskFuncHook_g != NULL)
(posIdleTaskFuncHook_g)();
#endif
}
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_SOFTINTS != 0
static void pos_execSoftIntQueue(void)
{
register UVAR_t intno;
#ifdef POS_DEBUGHELP
enum PTASKSTATE sst = posCurrentTask_g->deb.state;
#endif
#ifdef HAVE_IRQ_DISABLE_ALL
POS_LOCKFLAGS;
POS_IRQ_DISABLE_ALL;
#endif
++posInInterrupt_g;
do
{
intno = softintqueue_g[sintIdxOut_g].intno;
if (softIntHandlers_g[intno] != NULL)
{
#ifdef HAVE_IRQ_DISABLE_ALL
POS_IRQ_ENABLE_ALL;
#endif
(softIntHandlers_g[intno])(softintqueue_g[sintIdxOut_g].param);
#ifdef HAVE_IRQ_DISABLE_ALL
POS_IRQ_DISABLE_ALL;
#endif
}
if (++sintIdxOut_g > POSCFG_SOFTINTQUEUELEN)
sintIdxOut_g = 0;
}
while (sintIdxIn_g != sintIdxOut_g);
--posInInterrupt_g;
#ifdef HAVE_IRQ_DISABLE_ALL
POS_IRQ_ENABLE_ALL;
#endif
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = sst;
#endif
}
#endif /* POSCFG_FEATURE_SOFTINTS */
/*-------------------------------------------------------------------------*/
static void pos_schedule(void)
{
register UVAR_t ym, xt;
if (posInInterrupt_g == 0)
{
pos_doSoftInts();
#if POSCFG_FEATURE_INHIBITSCHED != 0
if (posInhibitSched_g == 0)
{
#endif
posMustSchedule_g = 0;
#if POSCFG_CTXSW_COMBINE > 1
posCtxCombineCtr_g = 0;
#endif
#if SYS_TASKTABSIZE_Y > 1
ym = POS_FINDBIT(posReadyTasks_g.ymask);
#else
ym = 0;
#endif
xt = POS_FINDBIT_EX(posReadyTasks_g.xtable[ym],
POS_NEXTROUNDROBIN(ym));
#if (SYS_TASKTABSIZE_X > 1) && (POSCFG_ROUNDROBIN != 0)
posNextRoundRobin_g[ym] = (xt + 1) & (SYS_TASKTABSIZE_X - 1);
#endif
posNextTask_g = posTaskTable_g[(ym * SYS_TASKTABSIZE_X) + xt];
if (posCurrentTask_g != posNextTask_g)
{
#ifdef POS_DEBUGHELP
posNextTask_g->deb.state = task_running;
pos_taskHistory(&posNextTask_g->deb);
#endif
p_pos_softContextSwitch();
}
#if POSCFG_FEATURE_INHIBITSCHED != 0
}
#endif
}
#ifdef POS_DEBUGHELP
if (posRunning_g != 0)
posCurrentTask_g->deb.state = task_running;
#endif
}
/*-------------------------------------------------------------------------*/
#if SYS_FEATURE_EVENTS != 0
static VAR_t pos_sched_event(EVENT_t ev)
{
register UVAR_t ym, xt;
register POSTASK_t task;
#if POSCFG_FEATURE_SOFTINTS != 0
if (softIntsPending())
{
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_schedule();
}
#endif
#if SYS_TASKTABSIZE_Y > 1
if (ev->e.pend.ymask != 0)
{
ym = POS_FINDBIT(ev->e.pend.ymask);
xt = POS_FINDBIT_EX(ev->e.pend.xtable[ym],
POS_NEXTROUNDROBIN(ym));
#else
if (ev->e.pend.xtable[0] != 0)
{
ym = 0;
xt = POS_FINDBIT(ev->e.pend.xtable[0]);
#endif
task = posTaskTable_g[(ym * SYS_TASKTABSIZE_X) + xt];
pos_eventRemoveTask(ev, task);
pos_enableTask(task);
posMustSchedule_g = 1;
#if (POSCFG_SOFT_MTASK == 0) || (POSCFG_CTXSW_COMBINE == 1)
pos_schedule();
#else
#if POSCFG_REALTIME_PRIO > 0
#if (POSCFG_ROUNDROBIN != 0) && (SYS_TASKTABSIZE_Y > 1)
if (task->idx_y < (SYS_TASKTABSIZE_Y - POSCFG_REALTIME_PRIO))
{
pos_schedule();
}
else
#endif
#endif
#if POSCFG_CTXSW_COMBINE > 1
if (++posCtxCombineCtr_g >= POSCFG_CTXSW_COMBINE)
{
pos_schedule();
}
else
#endif
do { } while(0);
#endif /* else (POSCFG_SOFT_MTASK == 0) || (POSCFG_CTXSW_COMBINE == 1) */
return 1;
}
return 0;
}
#endif /* SYS_FEATURE_EVENTS */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: ERROR NUMBER VARIABLE
*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_ERRNO != 0
VAR_t* _errno_p(void)
{
return &posCurrentTask_g->error;
}
#endif /* POSCFG_FEATURE_ERRNO */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: INTERRUPT CONTROL
*-------------------------------------------------------------------------*/
void c_pos_intEnter(void)
{
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_LOCKFLAGS;
POS_SCHED_LOCK;
++posInInterrupt_g;
pos_taskHistory(NULL);
POS_SCHED_UNLOCK;
#else
++posInInterrupt_g;
pos_taskHistory(NULL);
#endif
}
/*-------------------------------------------------------------------------*/
void c_pos_intExit(void)
{
register UVAR_t ym, xt;
POS_LOCKFLAGS;
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_SCHED_LOCK;
#endif
if (--posInInterrupt_g == 0)
{
pos_doSoftInts();
#if POSCFG_FEATURE_INHIBITSCHED != 0
if (posInhibitSched_g == 0)
{
#endif
if (posMustSchedule_g != 0)
{
posMustSchedule_g = 0;
#if POSCFG_CTXSW_COMBINE > 1
posCtxCombineCtr_g = 0;
#endif
#if SYS_TASKTABSIZE_Y > 1
ym = POS_FINDBIT(posReadyTasks_g.ymask);
#else
ym = 0;
#endif
xt = POS_FINDBIT_EX(posReadyTasks_g.xtable[ym],
POS_NEXTROUNDROBIN(ym));
#if (SYS_TASKTABSIZE_X > 1) && (POSCFG_ROUNDROBIN != 0)
posNextRoundRobin_g[ym] = (xt + 1) & (SYS_TASKTABSIZE_X - 1);
#endif
posNextTask_g = posTaskTable_g[(ym * SYS_TASKTABSIZE_X) + xt];
if (posCurrentTask_g != posNextTask_g)
{
#if POSCFG_ISR_INTERRUPTABLE == 0
/* all ctx switch functions need to be called with lock acquired */
POS_SCHED_LOCK;
#endif
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
posNextTask_g->deb.state = task_running;
pos_taskHistory(&posNextTask_g->deb);
#endif
/* Note:
* The processor does not return from this function call. When
* this function returns anyway, the architecture port is buggy.
*/
p_pos_intContextSwitch();
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_SCHED_UNLOCK;
#endif
return; /* needed for the thread based ports, eg. x86w32 */
}
}
#if POSCFG_FEATURE_INHIBITSCHED != 0
}
#endif
}
#ifdef POS_DEBUGHELP
pos_taskHistory(&posCurrentTask_g->deb);
#endif
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_SCHED_UNLOCK;
#endif
}
/*-------------------------------------------------------------------------*/
void c_pos_timerInterrupt(void)
{
register POSTASK_t task;
#if SYS_TASKDOUBLELINK == 0
register POSTASK_t last = NULL;
#endif
#if POSCFG_FEATURE_TIMER != 0
register TIMER_t *tmr;
#endif
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_LOCKFLAGS;
#endif
if (posRunning_g == 0)
return;
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_SCHED_LOCK;
#endif
#if POSCFG_FEATURE_JIFFIES != 0
#if POSCFG_FEATURE_LARGEJIFFIES == 0
++jiffies;
#else
++pos_jiffies_g;
#endif
#endif
#if POSCFG_FEATURE_TIMER != 0
tmr = posActiveTimers_g;
while (tmr != NULL)
{
--(tmr->counter);
if (tmr->counter == 0)
{
posSemaSignal(tmr->sema);
#if POSCFG_FEATURE_TIMERFIRED != 0
tmr->fired = 1;
#endif
if (tmr->reload != 0)
{
tmr->counter = tmr->reload;
}
else
{
pos_removeFromTimerList(tmr);
}
}
tmr = tmr->next;
}
#endif
task = posSleepingTasks_g;
while (task != NULL)
{
--tasktimerticks(task);
if (tasktimerticks(task) == 0)
{
pos_enableTask(task);
#if SYS_TASKDOUBLELINK != 0
pos_removeFromSleepList(task);
task->prev = task;
}
task = task->next;
#else
task = task->next;
if (last == NULL)
{
posSleepingTasks_g = task;
}
else
{
last->next = task;
}
}
else
{
last = task;
task = task->next;
}
#endif
}
posMustSchedule_g = 1;
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_SCHED_UNLOCK;
#endif
}
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: TASK CONTROL
*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_YIELD != 0
void posTaskYield(void)
{
#if (POSCFG_ROUNDROBIN == 0) || (SYS_TASKTABSIZE_Y == 1)
POS_LOCKFLAGS;
POS_SCHED_LOCK;
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_schedule();
POS_SCHED_UNLOCK;
#else
register UVAR_t p, ym, xt;
POS_LOCKFLAGS;
POS_SCHED_LOCK;
if (posInInterrupt_g == 0)
{
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_doSoftInts();
#if POSCFG_FEATURE_INHIBITSCHED != 0
if (posInhibitSched_g == 0)
{
#endif
p = posCurrentTask_g->idx_y;
if ((p >= (SYS_TASKTABSIZE_Y - 1)) ||
(posMustSchedule_g != 0))
{
pos_schedule();
POS_SCHED_UNLOCK;
return;
}
#if POSCFG_CTXSW_COMBINE > 1
posCtxCombineCtr_g = 0;
#endif
ym = POS_FINDBIT(posReadyTasks_g.ymask);
if (ym == p)
{
if ((UVAR_t)(posReadyTasks_g.xtable[ym] &
~posCurrentTask_g->bit_x) == 0)
{
ym = POS_FINDBIT(posReadyTasks_g.ymask & pos_zmask(ym));
}
}
xt = POS_FINDBIT_EX(posReadyTasks_g.xtable[ym],
POS_NEXTROUNDROBIN(ym));
#if SYS_TASKTABSIZE_X > 1
posNextRoundRobin_g[ym] = (xt + 1) & (SYS_TASKTABSIZE_X - 1);
#endif
posNextTask_g = posTaskTable_g[(ym * SYS_TASKTABSIZE_X) + xt];
if (posCurrentTask_g != posNextTask_g)
{
#ifdef POS_DEBUGHELP
posNextTask_g->deb.state = task_running;
pos_taskHistory(&posNextTask_g->deb);
#endif
p_pos_softContextSwitch();
}
#if POSCFG_FEATURE_INHIBITSCHED != 0
}
#endif
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_running;
#endif
}
POS_SCHED_UNLOCK;
#endif
}
#endif /* POSCFG_FEATURE_YIELD */
/*-------------------------------------------------------------------------*/
#if POSCFG_TASKSTACKTYPE == 0
POSTASK_t posTaskCreate(POSTASKFUNC_t funcptr, void *funcarg,
VAR_t priority, void *stackstart)
#elif POSCFG_TASKSTACKTYPE == 1
POSTASK_t posTaskCreate(POSTASKFUNC_t funcptr, void *funcarg,
VAR_t priority, UINT_t stacksize)
#else
POSTASK_t posTaskCreate(POSTASKFUNC_t funcptr, void *funcarg,
VAR_t priority)
#endif
{
register POSTASK_t task;
register UVAR_t b, p;
register unsigned char *m;
register UINT_t i;
POS_LOCKFLAGS;
P_ASSERT("posTaskCreate: function pointer valid", funcptr != NULL);
if ((UVAR_t)priority >= POSCFG_MAX_PRIO_LEVEL)
return NULL;
POS_SCHED_LOCK;
task = posFreeTasks_g;
#if SYS_POSTALLOCATE != 0
if (task == NULL)
{
POS_SCHED_UNLOCK;
task = (POSTASK_t) POS_MEM_ALLOC(sizeof(struct POSTASK) +
(POSCFG_ALIGNMENT - 1));
if (task == NULL)
return NULL;
task = MEMALIGN(POSTASK_t, task);
POS_SCHED_LOCK;
task->next = posFreeTasks_g;
posFreeTasks_g = task;
}
#endif /* SYS_POSTALLOCATE */
#if POSCFG_ROUNDROBIN == 0
p = (SYS_TASKTABSIZE_Y - 1) - (priority / MVAR_BITS);
b = (~posAllocatedTasks_g.xtable[p]) &
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -