📄 picoos.c
字号:
task->deb.state = task_waitingForSemaphoreWithTimeout;
}
else
{
task->deb.state = task_waitingForSemaphore;
#endif
}
pos_disableTask(task);
pos_eventAddTask(ev, task);
pos_schedule();
if (timeoutticks != INFINITE)
{
if (task->prev == task)
{
if (pos_isTableBitSet(&ev->e.pend, task))
{
pos_eventRemoveTask(ev, task);
POS_SCHED_UNLOCK;
return 1;
}
}
else
{
cleartimerticks(task);
pos_removeFromSleepList(task);
}
}
}
POS_SCHED_UNLOCK;
return E_OK;
}
#endif /* POSCFG_FEATURE_SEMAWAIT */
/*-------------------------------------------------------------------------*/
VAR_t posSemaSignal(POSSEMA_t sema)
{
register EVENT_t ev = (EVENT_t) sema;
POS_LOCKFLAGS;
P_ASSERT("posSemaSignal: semaphore valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posSemaSignal: semaphore allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
POS_SCHED_LOCK;
if (ev->e.d.counter == 0)
{
if (pos_sched_event(ev) == 0)
{
ev->e.d.counter = 1;
#ifdef POS_DEBUGHELP
ev->e.deb.counter = 1;
#endif
}
}
else
{
if (ev->e.d.counter != (((UINT_t)~0) >> 1))
{
++(ev->e.d.counter);
#ifdef POS_DEBUGHELP
ev->e.deb.counter = ev->e.d.counter;
#endif
}
}
POS_SCHED_UNLOCK;
return E_OK;
}
#endif /* SYS_FEATURE_EVENTS */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: MUTEXES
*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_MUTEXES != 0
POSMUTEX_t posMutexCreate(void)
{
#ifdef POS_DEBUGHELP
EVENT_t ev = (EVENT_t) posSemaCreate(1);
if (ev != NULL) ev->e.deb.type = event_mutex;
return (POSMUTEX_t) ev;
#else
return (POSMUTEX_t) posSemaCreate(1);
#endif
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_MUTEXDESTROY != 0
void posMutexDestroy(POSMUTEX_t mutex)
{
P_ASSERT("posMutexDestroy: mutex valid", mutex != NULL);
posSemaDestroy((POSSEMA_t) mutex);
}
#endif /* POSCFG_FEATURE_MUTEXDESTROY */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_MUTEXTRYLOCK != 0
VAR_t posMutexTryLock(POSMUTEX_t mutex)
{
register EVENT_t ev = (EVENT_t) mutex;
register POSTASK_t task = posCurrentTask_g;
POS_LOCKFLAGS;
P_ASSERT("posMutexTryLock: mutex valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posMutexTryLock: mutex allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
POS_SCHED_LOCK;
if (ev->e.task == task)
{
--(ev->e.d.counter);
#ifdef POS_DEBUGHELP
ev->e.deb.counter = ev->e.d.counter;
#endif
}
else
{
if (ev->e.d.counter < 1)
{
POS_SCHED_UNLOCK;
return 1; /* no lock */
}
ev->e.d.counter = 0;
ev->e.task = task;
#ifdef POS_DEBUGHELP
ev->e.deb.counter = 0;
#endif
}
POS_SCHED_UNLOCK;
return 0; /* have lock */
}
#endif /* POSCFG_FEATURE_MUTEXTRYLOCK */
/*-------------------------------------------------------------------------*/
VAR_t posMutexLock(POSMUTEX_t mutex)
{
register EVENT_t ev = (EVENT_t) mutex;
register POSTASK_t task = posCurrentTask_g;
POS_LOCKFLAGS;
P_ASSERT("posMutexLock: mutex valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posMutexLock: mutex allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
P_ASSERT("posMutexLock: not in an interrupt", posInInterrupt_g == 0);
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
POS_SCHED_LOCK;
if (ev->e.task == task)
{
--(ev->e.d.counter);
#ifdef POS_DEBUGHELP
ev->e.deb.counter = ev->e.d.counter;
#endif
}
else
{
if (ev->e.d.counter > 0)
{
ev->e.d.counter = 0;
#ifdef POS_DEBUGHELP
ev->e.deb.counter = 0;
#endif
}
else
{
pos_disableTask(task);
pos_eventAddTask(ev, task);
#ifdef POS_DEBUGHELP
task->deb.state = task_waitingForMutex;
#endif
pos_schedule();
}
ev->e.task = task;
}
POS_SCHED_UNLOCK;
return E_OK;
}
/*-------------------------------------------------------------------------*/
VAR_t posMutexUnlock(POSMUTEX_t mutex)
{
register EVENT_t ev = (EVENT_t) mutex;
POS_LOCKFLAGS;
P_ASSERT("posMutexUnlock: mutex valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posMutexUnlock: mutex allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
POS_SCHED_LOCK;
if (ev->e.d.counter == 0)
{
ev->e.task = NULL;
if (pos_sched_event(ev) == 0)
{
ev->e.d.counter = 1;
#ifdef POS_DEBUGHELP
ev->e.deb.counter = 1;
#endif
}
}
else
{
++(ev->e.d.counter);
#ifdef POS_DEBUGHELP
ev->e.deb.counter = ev->e.d.counter;
#endif
}
POS_SCHED_UNLOCK;
return E_OK;
}
#endif /* POSCFG_FEATURE_MUTEXES */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: MESSAGE BOXES
*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_MSGBOXES != 0
#if POSCFG_MSG_MEMORY == 0
static MSGBUF_t* pos_msgAlloc(void)
#else
void* posMessageAlloc(void)
#endif
{
register MSGBUF_t *mbuf;
POS_LOCKFLAGS;
if ((posInInterrupt_g != 0)
#if POSCFG_FEATURE_INHIBITSCHED != 0
|| (posInhibitSched_g != 0)
#endif
)
{
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_SCHED_LOCK;
#endif
mbuf = posFreeMessagebuf_g;
if (mbuf != NULL)
{
posFreeMessagebuf_g = (MSGBUF_t*) mbuf->next;
}
#if POSCFG_ISR_INTERRUPTABLE != 0
POS_SCHED_UNLOCK;
#endif
#if POSCFG_MSG_MEMORY == 0
return mbuf;
#else
return (void*) mbuf;
#endif
}
#if SYS_POSTALLOCATE != 0
POS_SCHED_LOCK;
mbuf = posFreeMessagebuf_g;
if (mbuf != NULL)
{
posFreeMessagebuf_g = (MSGBUF_t*) mbuf->next;
POS_SCHED_UNLOCK;
#if POSCFG_MSG_MEMORY == 0
return mbuf;
#else
return (void*) mbuf;
#endif
}
POS_SCHED_UNLOCK;
mbuf = (MSGBUF_t*) POS_MEM_ALLOC(sizeof(MSGBUF_t) +
(POSCFG_ALIGNMENT - 1));
if (mbuf != NULL)
{
mbuf = MEMALIGN(MSGBUF_t*, mbuf);
#if POSCFG_ARGCHECK > 1
mbuf->magic = POSMAGIC_MSGBUF;
#endif
#if POSCFG_MSG_MEMORY == 0
return mbuf;
#else
return (void*) mbuf;
#endif
}
#endif /* SYS_POSTALLOCATE */
posSemaGet(msgAllocSyncSem_g);
POS_SCHED_LOCK;
mbuf = posFreeMessagebuf_g;
while (mbuf == NULL)
{
msgAllocWaitReq_g = 1;
POS_SCHED_UNLOCK;
posSemaGet(msgAllocWaitSem_g);
POS_SCHED_LOCK;
mbuf = posFreeMessagebuf_g;
}
posFreeMessagebuf_g = (MSGBUF_t*) mbuf->next;
POS_SCHED_UNLOCK;
posSemaSignal(msgAllocSyncSem_g);
#if POSCFG_MSG_MEMORY == 0
return mbuf;
#else
return (void*) mbuf;
#endif
}
/*-------------------------------------------------------------------------*/
#if POSCFG_MSG_MEMORY == 0
static void pos_msgFree(MSGBUF_t *mbuf)
{
POS_LOCKFLAGS;
P_ASSERT("posMessageFree: buffer valid", mbuf != NULL);
#else
void posMessageFree(void *buf)
{
MSGBUF_t *mbuf = (MSGBUF_t*) buf;
POS_LOCKFLAGS;
P_ASSERT("posMessageFree: buffer valid", buf != NULL);
POS_ARGCHECK(mbuf, mbuf->magic, POSMAGIC_MSGBUF);
#endif
POS_SCHED_LOCK;
mbuf->next = (void*) posFreeMessagebuf_g;
posFreeMessagebuf_g = mbuf;
if (msgAllocWaitReq_g != 0)
{
msgAllocWaitReq_g = 0;
POS_SCHED_UNLOCK;
posSemaSignal(msgAllocWaitSem_g);
return;
}
POS_SCHED_UNLOCK;
}
/*-------------------------------------------------------------------------*/
VAR_t posMessageSend(void *buf, POSTASK_t taskhandle)
{
register MSGBUF_t *mbuf;
POS_LOCKFLAGS;
#if POSCFG_ARGCHECK != 0
if ((taskhandle == NULL)
#if POSCFG_ARGCHECK > 1
|| (taskhandle->magic != POSMAGIC_TASK)
#endif
#if (POSCFG_FEATURE_MSGWAIT != 0) && (POSCFG_MSG_MEMORY == 0)
|| (buf == NULL)
#endif
)
{
#if POSCFG_MSG_MEMORY != 0
posMessageFree(buf);
#endif
P_ASSERT("posMessageSend: arguments valid", 0);
return -E_ARG;
}
#endif
#if POSCFG_MSG_MEMORY == 0
mbuf = pos_msgAlloc();
if (mbuf == NULL)
return -E_NOMEM;
mbuf->bufptr = buf;
#else
mbuf = (MSGBUF_t*) buf;
POS_ARGCHECK_RET(mbuf, mbuf->magic, POSMAGIC_MSGBUF, -E_ARG);
#endif
POS_SCHED_LOCK;
#if POSCFG_FEATURE_EXIT != 0
if (taskhandle->state != POSTASKSTATE_ACTIVE)
{
POS_SCHED_UNLOCK;
#if POSCFG_MSG_MEMORY != 0
posMessageFree(buf);
#else
pos_msgFree(mbuf);
#endif
return -E_FAIL;
}
#endif
mbuf->next = NULL;
if (taskhandle->lastmsg == NULL)
{
taskhandle->firstmsg = (void*) mbuf;
taskhandle->lastmsg = (void*) mbuf;
}
else
{
((MSGBUF_t*)(taskhandle->lastmsg))->next = mbuf;
taskhandle->lastmsg = (void*) mbuf;
}
if (taskhandle->msgwait != 0)
{
taskhandle->msgwait = 0;
pos_sched_event((EVENT_t)taskhandle->msgsem);
#if (POSCFG_SOFT_MTASK !=0)&&(SYS_TASKTABSIZE_Y >1)&&(POSCFG_ROUNDROBIN !=0)
if ((posMustSchedule_g != 0) &&
(taskhandle->idx_y >= posCurrentTask_g->idx_y))
{
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_schedule();
}
#else
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_schedule();
#endif
}
POS_SCHED_UNLOCK;
return E_OK;
}
/*-------------------------------------------------------------------------*/
#if (POSCFG_SMALLCODE == 0) || (POSCFG_FEATURE_MSGWAIT == 0)
void* posMessageGet(void)
{
register POSTASK_t task = posCurrentTask_g;
register MSGBUF_t *mbuf;
register POSSEMA_t sem;
#if POSCFG_MSG_MEMORY == 0
void *buf;
#endif
POS_LOCKFLAGS;
P_ASSERT("posMessageGet: not in an interrupt", posInInterrupt_g == 0);
#if POSCFG_ARGCHECK > 1
if (posInInterrupt_g != 0)
return NULL;
#endif
if (task->msgsem == NULL)
{
sem = posSemaCreate(0);
P_ASSERT("posMessageGet: event allocation", sem != NULL);
if (sem == NULL)
{
return NULL;
}
POS_SETEVENTNAME(sem, "taskMessageSem");
POS_SCHED_LOCK;
task->msgsem = sem;
}
else
{
POS_SCHED_LOCK;
}
mbuf = (MSGBUF_t*) (task->firstmsg);
if (mbuf == NULL)
{
task->msgwait = 1;
pos_disableTask(task);
pos_eventAddTask((EVENT_t)task->msgsem, task);
#ifdef POS_DEBUGHELP
task->deb.state = task_waitingForMessage;
#endif
pos_schedule();
mbuf = (MSGBUF_t*) (task->firstmsg);
}
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
}
#endif
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_MSGWAIT != 0
void* posMessageWait(UINT_t timeoutticks)
{
register POSTASK_t task = posCurrentTask_g;
register MSGBUF_t *mbuf;
register POSSEMA_t sem;
#if POSCFG_MSG_MEMORY == 0
void *buf;
#endif
POS_LOCKFLAGS;
P_ASSERT("posMessageWait: not in an interrupt", posInInterrupt_g == 0);
#if POSCFG_ARGCHECK > 1
if (posInInterrupt_g != 0)
return NULL;
#endif
if (task->msgsem == NULL)
{
sem = posSemaCreate(0);
if (sem == NULL)
{
return NULL;
}
POS_SETEVENTNAME(sem, "taskMessageSem");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -