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

📄 picoos.c

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