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

📄 sys_arch.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
📖 第 1 页 / 共 2 页
字号:
  {
    /* empty the mailbox */
    for(;;)
    {
      l = posListGet(&fmb->m.listhead, POSLIST_HEAD, 0);
      if (l == NULL)
        break;
      m = POSLIST_ELEMENT(l, struct mail, list);
      if (m->l.payload == NULL)
      {
        LWIP_DEBUGF(SYS_DBLVL, ("sys_arch.c: sys_mbox_free: "
                    "mailbox not empty!\n" ));
      }
      else
      {
        LWIP_DEBUGF(SYS_DBLVL, ("sys_arch.c: sys_mbox_free: "
                    "mailbox not empty, memory leaks!\n" ));
      }
      SCHED_LOCK();
      cur_used_mails_g--;
#ifdef SYSDEBUG
      m->mbox = NULL;
#endif
      m->l.next = unused_mail_list_g;
      unused_mail_list_g = m;
      SCHED_UNLOCK();
    }
    /* cleanup and free the memory */
    posListTerm(&fmb->m.listhead);
#if SYS_TCPIPMBOXFIX
    if ((struct sys_mbox*) p_tcpipmbox_g == mbox)
    {
      posListTerm(&p_tcpipmbox_g->highPrioList);
      SCHED_LOCK();
      p_tcpipmbox_g = NULL;
    }
    else
#endif
    {
      SCHED_LOCK();
#ifdef SYSDEBUG
      fmb->task = NULL;
      fmb->magic = 0;
#endif
      fmb->m.next = unused_mbox_list_g;
      unused_mbox_list_g = fmb;
#ifdef SYSDEBUG
      cur_used_mboxes_g--;
#endif
    }
#if SYS_STATS
    lwip_stats.sys.mbox.used--;
#endif /* SYS_STATS */
    SCHED_UNLOCK();
  }
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_post(struct sys_mbox *mbox, void *msg)
{
  static INT_t maxloops = 4;
  INT_t loops;
  struct mail *m;

  if (mbox != NULL)
  {
#ifdef SYSDEBUG
    if (mbox->magic != MMAGIC)
    {
      SCHED_LOCK();
      printf("sys_mbox_post: wrong magic number!\n");
      for(;;);
    }
    if (mbox->task == NULL)
    {
      printf("sys_mbox_post: illegal mailbox!\n");
      SCHED_LOCK();
      for(;;);
    }
#endif

    /* allocate a new mail structure */
    loops = 0;
    for(;;)
    {
      SCHED_LOCK();
      if ((cur_used_mails_g < MAIL_THRESHOLD) || (loops >= maxloops))
      {
        m = unused_mail_list_g;
        if (m != NULL)
        {
          unused_mail_list_g = m->l.next;
        }
        else
        if (max_used_mails_g < SYS_MAX_MAIL)
        {
          m = &mail_memory_g[max_used_mails_g];
          max_used_mails_g++;
        }
        if (m != NULL)
        {
          cur_used_mails_g++;
          SCHED_UNLOCK();
          break;
        }
      }
      mail_waiting_g++;
      SCHED_UNLOCK();
#ifdef SYSDEBUG
      printf("sys_mbox_post: waiting(%i)\n", mail_waiting_g);
#endif
      if (sys_sem_wait_timeout(mail_sem_g,(loops>=maxloops)?1000:1000/HZ)==0)
      {
        LWIP_ASSERT("WARNING: sys_arch.c: out of message memory, "
                    "please increase SYS_MSG_MAX\n", loops < maxloops);
        SCHED_LOCK();
        if (mail_waiting_g > 0)
          mail_waiting_g--;
        SCHED_UNLOCK();
      }
      loops++;
    }

    /* post the mail */
#ifdef SYSDEBUG
    m->mbox = mbox;
#endif
    m->l.payload = msg;
#if SYS_TCPIPMBOXFIX
    if (((struct sys_mbox*) p_tcpipmbox_g == mbox) &&
        (((struct tcpip_msg*)msg)->type != TCPIP_MSG_INPUT))
    {
      SCHED_LOCK();
      posListAdd(&p_tcpipmbox_g->highPrioList, POSLIST_TAIL, &m->list2);
      posListAdd(&mbox->m.listhead, POSLIST_TAIL, &m->list);
      SCHED_UNLOCK();
    }
    else
#endif
    posListAdd(&mbox->m.listhead, POSLIST_TAIL, &m->list);
  }
}
/*-----------------------------------------------------------------------------------*/
u32_t
sys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, u32_t timeout)
{
  struct mail *m;
  POSLIST_t   *l;
#if SYS_TCPIPMBOXFIX
  POSLIST_t   *l2;
#endif
  JIF_t       start, stop;
  u32_t       w;

  if (mbox == NULL)
    return SYS_ARCH_TIMEOUT;

  /* sample start time */
  start = jiffies;

  /* wait for mail */
  l = posListGet(&mbox->m.listhead, POSLIST_HEAD,
                 (timeout == 0) ? INFINITE : (UINT_t) MS(timeout) );
#if SYS_TCPIPMBOXFIX
  if ((struct sys_mbox*) p_tcpipmbox_g == mbox)
  {
    l2 = posListGet(&p_tcpipmbox_g->highPrioList, POSLIST_HEAD, 0);
    if (l2 != NULL)
    {
      m = POSLIST_ELEMENT(l2, struct mail, list2);
      if (&m->list != l)
      {
        posListAdd(&mbox->m.listhead, POSLIST_HEAD, l);
        l = &m->list;
        posListRemove(l);
      }
    }
  }
#endif
  if (l == NULL)
  {
    LWIP_ASSERT("WARNING: sys_arch.c: out of pico]OS semaphores(2), "
                "please increase POSCFG_MAX_EVENTS\n", start != jiffies);

    mbox->lasttime = start + (timeout / HZ);
    return SYS_ARCH_TIMEOUT;
  }

  /* get the mail payload */
  m = POSLIST_ELEMENT(l, struct mail, list);
  if (msg != NULL)
    *msg = m->l.payload;

  /* free the mail memory */
  SCHED_LOCK();
  cur_used_mails_g--;
#ifdef SYSDEBUG
  m->mbox = NULL;
#endif
  m->l.next = unused_mail_list_g;
  unused_mail_list_g = m;
  if (mail_waiting_g > 0)
  {
    mail_waiting_g--;
    SCHED_UNLOCK();
    sys_sem_signal(mail_sem_g);
  }
  else
  {
    SCHED_UNLOCK();
  }

  /* calculate the waited time */
  if (!POS_TIMEAFTER(start, mbox->lasttime+2))
    start = mbox->lasttime;
  stop = jiffies;
  mbox->lasttime = stop;
  w = (u32_t) (stop - start) * 1000;
  w = w / HZ;
  return (w < timeout) ? w : timeout;
}
/*-----------------------------------------------------------------------------------*/
sys_thread_t
sys_thread_new(void (*function)(void *arg), void *arg, int prio)
{
  POSTASK_t  th;

  if ((prio < 0) || (prio >= POSCFG_MAX_PRIO_LEVEL))
    prio = DEFAULT_THREAD_PRIO;

  do
  {
#if POSCFG_ENABLE_NANO
    th = (POSTASK_t) nosTaskCreate((POSTASKFUNC_t) function, arg,
                                   (VAR_t)prio, 0, LWIPNAME "-*");
#else
#if POSCFG_TASKSTACKTYPE == 0
    MEMPTR_t stk;
    th = NULL;
    SCHED_LOCK();
    if (no_of_tasks_g < SYS_THREAD_MAX)
    {
      stk = (MEMPTR_t)
            &stackmem_g[ no_of_tasks_g * (SYS_STACK_SIZE / sizeof(UVAR_t)) ];
#if SYS_STACK_GROWUP == 0
      stk += SYS_STACK_SIZE - sizeof(UVAR_t);
#endif
      th = posTaskCreate((POSTASKFUNC_t) function, arg, prio, (void*)stk);
      if (th != NULL) no_of_tasks_g++;
    }
    SCHED_UNLOCK();
#elif POSCFG_TASKSTACKTYPE == 1
    th = posTaskCreate((POSTASKFUNC_t) function, arg,
                       (VAR_t) prio, SYS_STACK_SIZE);
#elif POSCFG_TASKSTACKTYPE == 2
    th = posTaskCreate((POSTASKFUNC_t) function, arg, prio);
#endif /* POSCFG_TASKSTACKTYPE == 2 */

    POS_SETTASKNAME(th, LWIPNAME);
#endif /* !have nano layer */
  }
  while ((th == NULL) && (++prio < POSCFG_MAX_PRIO_LEVEL));

  if (th == NULL)
  {
    LWIP_DEBUGF(SYS_DBLVL, ("sys_thread_new: pico]OS task create failed, "
                "function = %p, prio = %i\n", (void*)function, prio) );
    return NULL;
  } 
  return (sys_thread_t) th;
}
/*-----------------------------------------------------------------------------------*/
struct sys_timeouts *
sys_arch_timeouts(void)
{
#if POSCFG_ENABLE_NANO
  return (struct sys_timeouts *) (void*)
         (((MEMPTR_t) nosTaskGetUserspace()) + SYS_USRSPACE_OFS);
#else
  return (struct sys_timeouts *) (void*)
         (((MEMPTR_t) posTaskGetUserspace()) + SYS_USRSPACE_OFS);
#endif
}
/*-----------------------------------------------------------------------------------*/
sys_prot_t
sys_arch_protect(void)
{
#if POSCFG_FEATURE_MUTEXES
  posMutexLock(sysprotMutex_g);
#else
  POSTASK_t thistask = posTaskGetCurrent();
  SCHED_LOCK();
  if (thistask == sysprotLastTask_g)
  {
    sysprotLockCntr_g++;
    SCHED_UNLOCK();
  }
  else
  {
    SCHED_UNLOCK();
    posSemaGet(sysprotSemaphore_g);
    sysprotLastTask_g = thistask;
    sysprotLockCntr_g = 1;
  }
#endif
  return 0;
}
/*-----------------------------------------------------------------------------------*/
void
sys_arch_unprotect(sys_prot_t pval)
{
  (void) pval;
#if POSCFG_FEATURE_MUTEXES
  posMutexUnlock(sysprotMutex_g);
#else
  SCHED_LOCK();
  if (--sysprotLockCntr_g == 0)
  {
    sysprotLastTask_g = NULL;
    SCHED_UNLOCK();
    posSemaSignal(sysprotSemaphore_g);
  }
  else
  {
    SCHED_UNLOCK();
  }
#endif
}
/*-----------------------------------------------------------------------------------*/
void
sys_init()
{
  int i;

#if BUF_MAX_SEM > 0
  semabufLast_g      = 0;
  for (i=0; i<BUF_MAX_SEM; i++)
    semabuffer_g[i] = NULL;
#endif

#if BUF_MAX_MBOX > 0
  mboxbufLast_g      = 0;
  for (i=0; i<BUF_MAX_MBOX; i++)
    mboxbuffer_g[i] = NULL;
#endif

#if SYS_TCPIPMBOXFIX
  p_tcpipmbox_g      = NULL;
#endif
  unused_mbox_list_g = NULL;
  unused_mail_list_g = NULL;
  max_used_mboxes_g  = 0;
  max_used_mails_g   = 0;
  cur_used_mails_g   = 0;
#ifdef SYSDEBUG
  cur_used_mboxes_g  = 0;
#endif
  mail_waiting_g     = 0;
  mail_sem_g = sys_sem_new(0);
  LWIP_ASSERT("sys_arch.c: failed to create semaphore", mail_sem_g != NULL);

#if POSCFG_FEATURE_MUTEXES
  sysprotMutex_g = posMutexCreate();
  LWIP_ASSERT("sys_arch.c: failed to create mutex", sysprotMutex_g != NULL);
#else
  sysprotLockCntr_g = 0;
  sysprotLastTask_g = NULL;
  sysprotSemaphore_g = posSemaCreate(1);
  LWIP_ASSERT("sys_arch.c: failed to create semaphore", sysprotSemaphore_g != NULL);
#endif

  /* some extra checking */
  if (POSCFG_TASKCB_USERSPACE < SYS_USRSPACE_OFS+sizeof(struct sys_timeouts))
  {
    LWIP_DEBUGF(SYS_DBLVL, ("sys_arch.c: pico]OS task user space is "
                            "configured too small. Minimum size = %u bytes\n",
                            SYS_USRSPACE_OFS+sizeof(struct sys_timeouts) ));
    LWIP_ASSERT("sys_arch.c: pico]OS task user space is configured too small.",0);
    for(;;);
  }
}
/*-----------------------------------------------------------------------------------*/
void
sys_thread_abord(void)
{
#if POSCFG_FEATURE_EXIT
#if POSCFG_ENABLE_NANO
  nosTaskExit();
#else
  posTaskExit();
#endif
#else
#if POSCFG_ENABLE_NANO
  nosSemaWait(nosSemaCreate(0, 0, LWIPNAME "-abort-*"));
#else
  posSemaWait(posSemaCreate(0));
#endif
  for(;;)
#endif
}
/*-----------------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -