⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picoos.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
📖 第 1 页 / 共 5 页
字号:
      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 + -