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

📄 picoos.c

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