📄 picoos.c
字号:
POS_SCHED_LOCK;
task->msgsem = sem;
}
else
{
POS_SCHED_LOCK;
}
mbuf = (MSGBUF_t*) (task->firstmsg);
if ((timeoutticks != 0) && (mbuf == NULL))
{
if (timeoutticks != INFINITE)
{
tasktimerticks(task) = timeoutticks;
pos_addToSleepList(task);
#ifdef POS_DEBUGHELP
task->deb.state = task_waitingForMessageWithTimeout;
}
else
{
task->deb.state = task_waitingForMessage;
#endif
}
task->msgwait = 1;
pos_disableTask(task);
pos_eventAddTask((EVENT_t)task->msgsem, task);
pos_schedule();
mbuf = (MSGBUF_t*) (task->firstmsg);
if (task->msgwait != 0)
{
pos_eventRemoveTask((EVENT_t)task->msgsem, task);
task->msgwait = 0;
}
if ((timeoutticks != INFINITE) &&
(task->prev != task))
{
cleartimerticks(task);
pos_removeFromSleepList(task);
}
}
if (mbuf != NULL)
{
task->firstmsg = (void*) (mbuf->next);
if (task->firstmsg == NULL)
{
task->lastmsg = NULL;
}
POS_SCHED_UNLOCK;
#if POSCFG_MSG_MEMORY == 0
buf = mbuf->bufptr;
pos_msgFree(mbuf);
return buf;
#else
return (void*) (mbuf->buffer);
#endif
}
POS_SCHED_UNLOCK;
return NULL;
}
#endif /* POSCFG_FEATURE_MSGWAIT */
/*-------------------------------------------------------------------------*/
VAR_t posMessageAvailable(void)
{
return (posCurrentTask_g->firstmsg != NULL) ? 1 : 0;
}
#endif /* POSCFG_FEATURE_MSGBOXES */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: TIMER
*-------------------------------------------------------------------------*/
#if (POSCFG_FEATURE_JIFFIES != 0) && (POSCFG_FEATURE_LARGEJIFFIES != 0)
JIF_t posGetJiffies(void)
{
register JIF_t jif;
POS_LOCKFLAGS;
POS_SCHED_LOCK;
jif = pos_jiffies_g;
POS_SCHED_UNLOCK;
return jif;
}
#endif /* POSCFG_FEATURE_JIFFIES */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_TIMER != 0
POSTIMER_t posTimerCreate(void)
{
register TIMER_t *t;
POS_LOCKFLAGS;
POS_SCHED_LOCK;
t = posFreeTimer_g;
#if SYS_POSTALLOCATE != 0
if (t == NULL)
{
POS_SCHED_UNLOCK;
t = (TIMER_t*) POS_MEM_ALLOC(sizeof(TIMER_t) +
(POSCFG_ALIGNMENT - 1));
if (t == NULL)
return NULL;
t = MEMALIGN(TIMER_t*, t);
#if POSCFG_ARGCHECK > 1
t->magic = POSMAGIC_TIMER;
#endif
}
else
{
posFreeTimer_g = t->next;
POS_SCHED_UNLOCK;
}
#else /* SYS_POSTALLOCATE */
if ((t == NULL)
#if POSCFG_ARGCHECK > 1
|| (t->magic != POSMAGIC_TIMER)
#endif
)
{
POS_SCHED_UNLOCK;
return NULL;
}
posFreeTimer_g = t->next;
POS_SCHED_UNLOCK;
#endif /* SYS_POSTALLOCATE */
t->prev = t;
#if POSCFG_ARGCHECK > 1
t->wait = 0;
t->reload = 0;
#endif
#if POSCFG_FEATURE_TIMERFIRED != 0
t->fired = 0;
#endif
return (POSTIMER_t) t;
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_TIMERDESTROY != 0
void posTimerDestroy(POSTIMER_t tmr)
{
register TIMER_t *t = (TIMER_t*) tmr;
POS_LOCKFLAGS;
P_ASSERT("posTimerDestroy: timer valid", tmr != NULL);
POS_ARGCHECK(t, t->magic, POSMAGIC_TIMER);
posTimerStop(tmr);
POS_SCHED_LOCK;
if (t == t->prev)
{
t->next = posFreeTimer_g;
posFreeTimer_g = t;
}
POS_SCHED_UNLOCK;
}
#endif /* POSCFG_FEATURE_TIMERDESTROY */
/*-------------------------------------------------------------------------*/
VAR_t posTimerSet(POSTIMER_t tmr, POSSEMA_t sema,
UINT_t waitticks, UINT_t periodticks)
{
register TIMER_t *t = (TIMER_t*) tmr;
register EVENT_t ev = (EVENT_t) sema;
POS_LOCKFLAGS;
P_ASSERT("posTimerSet: timer valid", tmr != NULL);
P_ASSERT("posTimerSet: semaphore valid", sema != NULL);
POS_ARGCHECK_RET(t, t->magic, POSMAGIC_TIMER, -E_ARG);
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
#if POSCFG_ARGCHECK > 1
if (waitticks == 0)
return -E_ARG;
#endif
posTimerStop(tmr);
POS_SCHED_LOCK;
t->sema = sema;
t->wait = waitticks;
t->reload = periodticks;
POS_SCHED_UNLOCK;
return E_OK;
}
/*-------------------------------------------------------------------------*/
VAR_t posTimerStart(POSTIMER_t tmr)
{
register TIMER_t *t = (TIMER_t*) tmr;
POS_LOCKFLAGS;
P_ASSERT("posTimerStart: timer valid", tmr != NULL);
POS_ARGCHECK_RET(t, t->magic, POSMAGIC_TIMER, -E_ARG);
POS_SCHED_LOCK;
t->counter = t->wait;
if (t->prev == t)
{
#if POSCFG_FEATURE_TIMERFIRED != 0
t->fired = 0;
#endif
pos_addToTimerList(t);
}
POS_SCHED_UNLOCK;
return E_OK;
}
/*-------------------------------------------------------------------------*/
VAR_t posTimerStop(POSTIMER_t tmr)
{
register TIMER_t *t = (TIMER_t*) tmr;
POS_LOCKFLAGS;
P_ASSERT("posTimerStop: timer valid", tmr != NULL);
POS_ARGCHECK_RET(t, t->magic, POSMAGIC_TIMER, -E_ARG);
POS_SCHED_LOCK;
if (t->prev != t)
{
pos_removeFromTimerList(t);
}
POS_SCHED_UNLOCK;
return E_OK;
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_TIMERFIRED != 0
VAR_t posTimerFired(POSTIMER_t tmr)
{
register TIMER_t *t = (TIMER_t*) tmr;
register VAR_t f;
POS_LOCKFLAGS;
P_ASSERT("posTimerFired: timer valid", tmr != NULL);
POS_ARGCHECK_RET(t, t->magic, POSMAGIC_TIMER, -E_ARG);
POS_SCHED_LOCK;
f = t->fired;
t->fired = 0;
POS_SCHED_UNLOCK;
return f;
}
#endif /* POSCFG_FEATURE_TIMERFIRED */
#endif /* POSCFG_FEATURE_TIMER */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: FLAGS
*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_FLAGS != 0
POSFLAG_t posFlagCreate(void)
{
register EVENT_t ev;
ev = (EVENT_t) posSemaCreate(0);
if (ev != NULL)
{
#ifdef POS_DEBUGHELP
ev->e.deb.type = event_flags;
#endif
ev->e.d.flags = 0;
}
return (POSFLAG_t) ev;
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_FLAGDESTROY != 0
void posFlagDestroy(POSFLAG_t flg)
{
P_ASSERT("posFlagDestroy: flag valid", flg != NULL);
posSemaDestroy((POSSEMA_t) flg);
}
#endif /* POSCFG_FEATURE_FLAGDESTROY */
/*-------------------------------------------------------------------------*/
VAR_t posFlagSet(POSFLAG_t flg, UVAR_t flgnum)
{
register EVENT_t ev = (EVENT_t) flg;
POS_LOCKFLAGS;
P_ASSERT("posFlagSet: flag valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posFlagSet: flag allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
#if POSCFG_ARGCHECK != 0
if (flgnum >= (MVAR_BITS-1))
return -E_ARG;
#endif
POS_SCHED_LOCK;
ev->e.d.flags |= pos_shift1l(flgnum);
pos_sched_event(ev);
POS_SCHED_UNLOCK;
return E_OK;
}
/*-------------------------------------------------------------------------*/
VAR_t posFlagGet(POSFLAG_t flg, UVAR_t mode)
{
register EVENT_t ev = (EVENT_t) flg;
register POSTASK_t task = posCurrentTask_g;
register UVAR_t f;
POS_LOCKFLAGS;
P_ASSERT("posFlagGet: flag valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posFlagGet: flag allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
P_ASSERT("posFlagGet: not in an interrupt", posInInterrupt_g == 0);
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
#if POSCFG_ARGCHECK > 1
if ((mode != POSFLAG_MODE_GETSINGLE) &&
(mode != POSFLAG_MODE_GETMASK))
return -E_ARG;
#endif
POS_SCHED_LOCK;
if (ev->e.d.flags == 0)
{
do
{
pos_disableTask(task);
pos_eventAddTask(ev, task);
#ifdef POS_DEBUGHELP
task->deb.state = task_waitingForFlag;
#endif
pos_schedule();
}
while (ev->e.d.flags == 0);
}
if (mode == POSFLAG_MODE_GETSINGLE)
{
f = POS_FINDBIT(ev->e.d.flags);
ev->e.d.flags &= ~pos_shift1l(f);
}
else
{
f = ev->e.d.flags;
ev->e.d.flags = 0;
}
POS_SCHED_UNLOCK;
return (VAR_t) f;
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_FLAGWAIT != 0
VAR_t posFlagWait(POSFLAG_t flg, UINT_t timeoutticks)
{
register EVENT_t ev = (EVENT_t) flg;
register POSTASK_t task = posCurrentTask_g;
register UVAR_t f;
POS_LOCKFLAGS;
P_ASSERT("posFlagWait: flag valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posFlagWait: flag allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
P_ASSERT("posFlagWait: not in an interrupt", posInInterrupt_g == 0);
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
POS_SCHED_LOCK;
if ((timeoutticks != 0) && (ev->e.d.flags == 0))
{
if (timeoutticks != INFINITE)
{
tasktimerticks(task) = timeoutticks;
pos_addToSleepList(task);
#ifdef POS_DEBUGHELP
task->deb.state = task_waitingForFlagWithTimeout;
}
else
{
task->deb.state = task_waitingForFlag;
#endif
}
do
{
pos_disableTask(task);
pos_eventAddTask(ev, task);
pos_schedule();
}
while ((ev->e.d.flags == 0) &&
((timeoutticks == INFINITE) || (task->prev != task)));
if (timeoutticks != INFINITE)
{
pos_eventRemoveTask(ev, task);
if (task->prev != task)
{
cleartimerticks(task);
pos_removeFromSleepList(task);
}
}
}
f = ev->e.d.flags;
ev->e.d.flags = 0;
POS_SCHED_UNLOCK;
return (VAR_t) f;
}
#endif /* POSCFG_FEATURE_FLAGWAIT */
#endif /* POSCFG_FEATURE_FLAGS */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: SOFTWARE INTERRUPTS
*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_SOFTINTS != 0
void posSoftInt(UVAR_t intno, UVAR_t param)
{
UVAR_t next;
POS_LOCKFLAGS;
P_ASSERT("posSoftInt: interrupt number", intno < POSCFG_SOFTINTERRUPTS);
if (intno < POSCFG_SOFTINTERRUPTS)
{
POS_IRQ_DISABLE_ALL;
next = sintIdxIn_g + 1;
if (next > POSCFG_SOFTINTQUEUELEN)
next = 0;
if (next != sintIdxOut_g)
{
softintqueue_g[sintIdxIn_g].intno = intno;
softintqueue_g[sintIdxIn_g].param = param;
sintIdxIn_g = next;
}
POS_IRQ_ENABLE_ALL;
}
}
/*-------------------------------------------------------------------------*/
VAR_t posSoftIntSetHandler(UVAR_t intno, POSINTFUNC_t inthandler)
{
POS_LOCKFLAGS;
P_ASSERT("posSoftIntSetHandler: interrupt number",
intno < POSCFG_SOFTINTERRUPTS);
if (intno >= POSCFG_SOFTINTERRUPTS)
return -E_ARG;
POS_SCHED_LOCK;
if (softIntHandlers_g[intno] != NULL)
{
POS_SCHED_UNLOCK;
return -E_FAIL;
}
softIntHandlers_g[intno] = inthandler;
POS_SCHED_UNLOCK;
return E_OK;
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_SOFTINTDEL != 0
VAR_t posSoftIntDelHandler(UVAR_t intno)
{
POS_LOCKFLAGS;
P_ASSERT("posSoftIntDelHandler: interrupt number",
intno < POSCFG_SOFTINTERRUPTS);
if (intno >= POSCFG_SOFTINTERRUPTS)
return -E_ARG;
POS_SCHED_LOCK;
softIntHandlers_g[intno] = NULL;
POS_SCHED_UNLOCK;
return E_OK;
}
#endif /* POSCFG_FEATURE_SOFTINTDEL */
#endif /* POSCFG_FEATURE_SOFTINTS */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: ATOMIC VARIABLES
*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_ATOMICVAR != 0
void posAtomicSet(POSATOMIC_t *var, INT_t value)
{
POS_LOCKFLAGS;
P_ASSERT("posAtomicSet: variable pointer", var != NULL);
if (var != NULL)
{
POS_SCHED_LOCK;
*var = value;
POS_SCHED_UNLOCK;
}
}
/*-------------------------------------------------------------------------*/
INT_t posAtomicGet(POSATOMIC_t *var)
{
INT_t v
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -