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

📄 picoos.c

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