📄 picoos.c
字号:
pos_shift1l((MVAR_BITS-1) - (priority & (MVAR_BITS-1)));
#else
p = (SYS_TASKTABSIZE_Y - 1) - priority;
b = ~posAllocatedTasks_g.xtable[p];
#endif
if ((b == 0) || (task == NULL))
{
POS_SCHED_UNLOCK;
return NULL;
}
b = POS_FINDBIT(b);
#if (POSCFG_ROUNDROBIN != 0) && (SYS_TASKTABSIZE_X < MVAR_BITS)
if (b >= SYS_TASKTABSIZE_X)
{
POS_SCHED_UNLOCK;
return NULL;
}
#endif
posFreeTasks_g = task->next;
m = (unsigned char*) task;
i = sizeof(struct POSTASK);
while (i != 0) { *m = 0; ++m; --i; };
#if POSCFG_ARGCHECK > 1
task->magic = POSMAGIC_TASK;
#endif
#if SYS_TASKTABSIZE_Y > 1
task->idx_y = p;
task->bit_y = pos_shift1l(p);
#endif
task->bit_x = pos_shift1l(b);
posTaskTable_g[(p * SYS_TASKTABSIZE_X) + b] = task;
#if POSCFG_TASKSTACKTYPE == 0
p_pos_initTask(task, stackstart, funcptr, funcarg);
#elif POSCFG_TASKSTACKTYPE == 1
if (p_pos_initTask(task, stacksize, funcptr, funcarg) != 0)
{
task->next = posFreeTasks_g;
posFreeTasks_g = task;
POS_SCHED_UNLOCK;
return NULL;
}
#else
if (p_pos_initTask(task, funcptr, funcarg) != 0)
{
task->next = posFreeTasks_g;
posFreeTasks_g = task;
POS_SCHED_UNLOCK;
return NULL;
}
#endif
#if SYS_TASKSTATE != 0
task->state = POSTASKSTATE_ACTIVE;
#endif
pos_setTableBit(&posAllocatedTasks_g, task);
pos_enableTask(task);
#ifdef POS_DEBUGHELP
task->deb.handle = task;
task->deb.func = funcptr;
task->deb.name = NULL;
task->deb.state = task_created;
task->deb.next = picodeb_tasklist;
task->deb.prev = NULL;
if (picodeb_tasklist != NULL)
picodeb_tasklist->prev = &task->deb;
picodeb_tasklist = &task->deb;
if (posRunning_g != 0)
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_schedule();
POS_SCHED_UNLOCK;
return task;
}
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_EXIT != 0
void posTaskExit(void)
{
register POSTASK_t task = posCurrentTask_g;
POS_LOCKFLAGS;
#if POSCFG_TASKEXIT_HOOK != 0
if (task->exithook != NULL)
(task->exithook)(task, texh_exitcalled);
#endif
#if POSCFG_FEATURE_MSGBOXES != 0
if (task->msgsem != NULL)
{
posSemaDestroy(task->msgsem);
}
POS_SCHED_LOCK;
task->state = POSTASKSTATE_ZOMBIE;
if (task->firstmsg != NULL)
{
((MSGBUF_t*)(task->lastmsg))->next = posFreeMessagebuf_g;
posFreeMessagebuf_g = (MSGBUF_t*)(task->firstmsg);
if (msgAllocWaitReq_g != 0)
{
msgAllocWaitReq_g = 0;
POS_SCHED_UNLOCK;
posSemaSignal(msgAllocWaitSem_g);
POS_SCHED_LOCK;
}
}
#else
POS_SCHED_LOCK;
#endif
pos_disableTask(task);
pos_delTableBit(&posAllocatedTasks_g, task);
#if (POSCFG_TASKSTACKTYPE == 1) || (POSCFG_TASKSTACKTYPE == 2)
p_pos_freeStack(task);
#endif
#if POSCFG_TASKEXIT_HOOK != 0
if (task->exithook != NULL)
(task->exithook)(task, texh_freestackmem);
#endif
#ifdef POS_DEBUGHELP
if (task->deb.next != NULL)
task->deb.next->prev = task->deb.prev;
if (task->deb.prev == NULL) {
picodeb_tasklist = task->deb.next;
} else {
task->deb.prev->next = task->deb.next;
}
task->deb.state = task_notExisting;
#endif
#if SYS_TASKSTATE != 0
task->state = POSTASKSTATE_UNUSED;
#endif
task->next = posFreeTasks_g;
posFreeTasks_g = task;
pos_schedule();
for(;;);
}
#endif /* POSCFG_FEATURE_EXIT */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_GETTASK != 0
POSTASK_t posTaskGetCurrent(void)
{
return posCurrentTask_g;
}
#endif /* POSCFG_FEATURE_GETTASK */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_TASKUNUSED != 0
VAR_t posTaskUnused(POSTASK_t taskhandle)
{
P_ASSERT("posTaskUnused: task handle valid", taskhandle != NULL);
POS_ARGCHECK_RET(taskhandle, taskhandle->magic, POSMAGIC_TASK, -E_ARG);
return (taskhandle->state == POSTASKSTATE_UNUSED) ? 1 : 0;
}
#endif /* POSCFG_FEATURE_TASKUNUSED */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_SETPRIORITY != 0
VAR_t posTaskSetPriority(POSTASK_t taskhandle, VAR_t priority)
{
register UVAR_t b, p;
POS_LOCKFLAGS;
P_ASSERT("posTaskSetPriority: task handle valid", taskhandle != NULL);
POS_ARGCHECK_RET(taskhandle, taskhandle->magic, POSMAGIC_TASK, -E_ARG);
if ((UVAR_t)priority >= POSCFG_MAX_PRIO_LEVEL)
return -E_ARG;
POS_SCHED_LOCK;
#if POSCFG_ROUNDROBIN == 0
p = (SYS_TASKTABSIZE_Y - 1) - (priority / MVAR_BITS);
b = (~posAllocatedTasks_g.xtable[p]) &
pos_shift1l((MVAR_BITS-1) - (priority & (MVAR_BITS-1)));
#else
p = (SYS_TASKTABSIZE_Y - 1) - priority;
b = ~posAllocatedTasks_g.xtable[p];
#endif
if (b == 0)
{
POS_SCHED_UNLOCK;
return -E_FAIL;
}
b = POS_FINDBIT(b);
#if (POSCFG_ROUNDROBIN != 0) && (SYS_TASKTABSIZE_X < MVAR_BITS)
if (b >= SYS_TASKTABSIZE_X)
{
POS_SCHED_UNLOCK;
return -E_FAIL;
}
#endif
pos_disableTask(taskhandle);
pos_delTableBit(&posAllocatedTasks_g, taskhandle);
#if SYS_TASKTABSIZE_Y > 1
taskhandle->idx_y = p;
taskhandle->bit_y = pos_shift1l(p);
#endif
taskhandle->bit_x = pos_shift1l(b);
posTaskTable_g[(p * SYS_TASKTABSIZE_X) + b] = taskhandle;
pos_setTableBit(&posAllocatedTasks_g, taskhandle);
pos_enableTask(taskhandle);
POS_SCHED_UNLOCK;
return E_OK;
}
#endif /* POSCFG_FEATURE_SETPRIORITY */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_GETPRIORITY != 0
VAR_t posTaskGetPriority(POSTASK_t taskhandle)
{
register VAR_t p;
POS_LOCKFLAGS;
P_ASSERT("posTaskGetPriority: task handle valid", taskhandle != NULL);
POS_ARGCHECK_RET(taskhandle, taskhandle->magic, POSMAGIC_TASK, -E_ARG);
POS_SCHED_LOCK;
#if SYS_TASKTABSIZE_Y == 1
p = 0;
#else
p = (SYS_TASKTABSIZE_Y - 1) - taskhandle->idx_y;
#endif
#if POSCFG_ROUNDROBIN == 0
p = (p * MVAR_BITS) + (MVAR_BITS - 1) - POS_FINDBIT(taskhandle->bit_x);
#endif
POS_SCHED_UNLOCK;
return p;
}
#endif /* POSCFG_FEATURE_GETPRIORITY */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_SLEEP != 0
void posTaskSleep(UINT_t ticks)
{
register POSTASK_t task;
POS_LOCKFLAGS;
#if POSCFG_ARGCHECK > 1
if (posInInterrupt_g != 0)
return;
#endif
POS_SCHED_LOCK;
if (ticks != 0)
{
task = posCurrentTask_g;
tasktimerticks(task) = ticks;
pos_disableTask(task);
pos_addToSleepList(task);
}
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_sleeping;
#endif
pos_schedule();
POS_SCHED_UNLOCK;
}
#endif /* POSCFG_FEATURE_SLEEP */
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_INHIBITSCHED != 0
void posTaskSchedLock(void)
{
POS_LOCKFLAGS;
POS_SCHED_LOCK;
++posInhibitSched_g;
POS_SCHED_UNLOCK;
}
/*-------------------------------------------------------------------------*/
void posTaskSchedUnlock(void)
{
POS_LOCKFLAGS;
POS_SCHED_LOCK;
--posInhibitSched_g;
if ((posInhibitSched_g == 0) &&
(posMustSchedule_g != 0))
{
#ifdef POS_DEBUGHELP
posCurrentTask_g->deb.state = task_suspended;
#endif
pos_schedule();
}
POS_SCHED_UNLOCK;
}
#endif /* POSCFG_FEATURE_INHIBITSCHED */
/*-------------------------------------------------------------------------*/
#if POSCFG_TASKCB_USERSPACE > 0
void* posTaskGetUserspace(void)
{
return (void*) &posCurrentTask_g->usrspace[0];
}
#endif /* POSCFG_TASKCB_USERSPACE */
/*---------------------------------------------------------------------------
* EXPORTED FUNCTIONS: SEMAPHORES
*-------------------------------------------------------------------------*/
#if SYS_FEATURE_EVENTS != 0
POSSEMA_t posSemaCreate(INT_t initcount)
{
register EVENT_t ev;
register UVAR_t i;
POS_LOCKFLAGS;
POS_SCHED_LOCK;
ev = posFreeEvents_g;
#if SYS_POSTALLOCATE != 0
if (ev == NULL)
{
POS_SCHED_UNLOCK;
ev = (EVENT_t) POS_MEM_ALLOC(sizeof(union EVENT) +
(POSCFG_ALIGNMENT - 1));
if (ev == NULL)
return NULL;
ev = MEMALIGN(EVENT_t, ev);
#if POSCFG_ARGCHECK > 1
ev->e.magic = POSMAGIC_EVENTU;
#endif
POS_SCHED_LOCK;
}
else
{
#if POSCFG_ARGCHECK > 1
if (ev->e.magic != POSMAGIC_EVENTF)
{
POS_SCHED_UNLOCK;
return NULL;
}
ev->e.magic = POSMAGIC_EVENTU;
#endif
posFreeEvents_g = ev->l.next;
}
#else /* SYS_POSTALLOCATE */
if (ev != NULL)
{
#if POSCFG_ARGCHECK > 1
if (ev->e.magic != (UVAR_t) POSMAGIC_EVENTF)
{
POS_SCHED_UNLOCK;
return NULL;
}
ev->e.magic = POSMAGIC_EVENTU;
#endif
posFreeEvents_g = ev->l.next;
#endif /* SYS_POSTALLOCATE */
ev->e.d.counter = initcount;
#if POSCFG_FEATURE_MUTEXES != 0
ev->e.task = NULL;
#endif
for (i=0; i<SYS_TASKTABSIZE_Y; ++i)
{
ev->e.pend.xtable[i] = 0;
}
#if SYS_TASKTABSIZE_Y > 1
ev->e.pend.ymask = 0;
#endif
#ifdef POS_DEBUGHELP
ev->e.deb.handle = ev;
ev->e.deb.name = NULL;
ev->e.deb.type = event_semaphore;
ev->e.deb.counter= initcount;
ev->e.deb.next = picodeb_eventlist;
ev->e.deb.prev = NULL;
if (picodeb_eventlist != NULL)
picodeb_eventlist->prev = &ev->e.deb;
picodeb_eventlist = &ev->e.deb;
#endif
#if SYS_POSTALLOCATE == 0
}
#endif
POS_SCHED_UNLOCK;
return (POSSEMA_t) ev;
}
/*-------------------------------------------------------------------------*/
#if SYS_FEATURE_EVENTFREE != 0
void posSemaDestroy(POSSEMA_t sema)
{
register EVENT_t ev = (EVENT_t) sema;
POS_LOCKFLAGS;
P_ASSERT("posSemaDestroy: semaphore valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posSemaDestroy: semaphore allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
POS_ARGCHECK(ev, ev->e.magic, POSMAGIC_EVENTU);
#if SYS_TASKTABSIZE_Y > 1
if (ev->e.pend.ymask == 0)
#else
if (ev->e.pend.xtable[0] == 0)
#endif
{
POS_SCHED_LOCK;
#ifdef POS_DEBUGHELP
if (ev->e.deb.next != NULL)
ev->e.deb.next->prev = ev->e.deb.prev;
if (ev->e.deb.prev == NULL) {
picodeb_eventlist = ev->e.deb.next;
} else {
ev->e.deb.prev->next = ev->e.deb.next;
}
#endif
#if POSCFG_ARGCHECK > 1
ev->e.magic = POSMAGIC_EVENTF;
#endif
ev->l.next = posFreeEvents_g;
posFreeEvents_g = ev;
POS_SCHED_UNLOCK;
}
}
#endif /* SYS_FEATURE_EVENTFREE */
/*-------------------------------------------------------------------------*/
#if (POSCFG_SMALLCODE == 0) || (POSCFG_FEATURE_SEMAWAIT == 0)
VAR_t posSemaGet(POSSEMA_t sema)
{
register EVENT_t ev = (EVENT_t) sema;
register POSTASK_t task = posCurrentTask_g;
POS_LOCKFLAGS;
P_ASSERT("posSemaGet: semaphore valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posSemaGet: semaphore allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
P_ASSERT("posSemaGet: not in an interrupt", posInInterrupt_g == 0);
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
#if POSCFG_ARGCHECK > 1
if (posInInterrupt_g != 0)
return -E_FORB;
#endif
POS_SCHED_LOCK;
if (ev->e.d.counter > 0)
{
--(ev->e.d.counter);
#ifdef POS_DEBUGHELP
ev->e.deb.counter = ev->e.d.counter;
#endif
}
else
{
pos_disableTask(task);
pos_eventAddTask(ev, task);
#ifdef POS_DEBUGHELP
task->deb.state = task_waitingForSemaphore;
#endif
pos_schedule();
}
POS_SCHED_UNLOCK;
return E_OK;
}
#endif
/*-------------------------------------------------------------------------*/
#if POSCFG_FEATURE_SEMAWAIT != 0
VAR_t posSemaWait(POSSEMA_t sema, UINT_t timeoutticks)
{
register EVENT_t ev = (EVENT_t) sema;
register POSTASK_t task = posCurrentTask_g;
POS_LOCKFLAGS;
P_ASSERT("posSemaWait: semaphore valid", ev != NULL);
#if POSCFG_ARGCHECK > 1
P_ASSERT("posSemaWait: semaphore allocated",
ev->e.magic == POSMAGIC_EVENTU);
#endif
P_ASSERT("posSemaWait: not in an interrupt", posInInterrupt_g == 0);
POS_ARGCHECK_RET(ev, ev->e.magic, POSMAGIC_EVENTU, -E_ARG);
#if POSCFG_ARGCHECK > 1
if (posInInterrupt_g != 0)
return -E_FORB;
#endif
POS_SCHED_LOCK;
if (ev->e.d.counter > 0)
{
--(ev->e.d.counter);
#ifdef POS_DEBUGHELP
ev->e.deb.counter = ev->e.d.counter;
#endif
}
else
{
if (timeoutticks != INFINITE)
{
if (timeoutticks == 0)
{
POS_SCHED_UNLOCK;
return 1;
}
tasktimerticks(task) = timeoutticks;
pos_addToSleepList(task);
#ifdef POS_DEBUGHELP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -