/**
 * @brief   Creates a new thread allocating the memory from the specified
 *          memory pool.
 * @pre     The configuration options @p CH_USE_DYNAMIC and @p CH_USE_MEMPOOLS
 *          must be enabled in order to use this function.
 * @note    A thread can terminate by calling @p chThdExit() or by simply
 *          returning from its main function.
 * @note    The memory allocated for the thread is not released when the thread
 *          terminates but when a @p chThdWait() is performed.
 *
 * @param[in] mp        pointer to the memory pool object
 * @param[in] prio      the priority level for the new thread
 * @param[in] pf        the thread function
 * @param[in] arg       an argument passed to the thread function. It can be
 *                      @p NULL.
 * @return              The pointer to the @p Thread structure allocated for
 *                      the thread into the working space area.
 * @retval  NULL        if the memory pool is empty.
 *
 * @api
 */
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
                                  tfunc_t pf, void *arg) {
  void *wsp;
  Thread *tp;

  chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool");

  wsp = chPoolAlloc(mp);
  if (wsp == NULL)
    return NULL;
  
#if CH_DBG_FILL_THREADS
  _thread_memfill((uint8_t *)wsp,
                  (uint8_t *)wsp + sizeof(Thread),
                  CH_THREAD_FILL_VALUE);
  _thread_memfill((uint8_t *)wsp + sizeof(Thread),
                  (uint8_t *)wsp + mp->mp_object_size,
                  CH_STACK_FILL_VALUE);
#endif

  chSysLock();
  tp = chThdCreateI(wsp, mp->mp_object_size, prio, pf, arg);
  tp->p_flags = THD_MEM_MODE_MEMPOOL;
  tp->p_mpool = mp;
  chSchWakeupS(tp, RDY_OK);
  chSysUnlock();
  return tp;
}
Example #2
0
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread,
                            void *arg, int stacksize, int prio) {
  size_t wsz;
  void *wsp;
  syssts_t sts;
  thread_t *tp;

  (void)name;
  wsz = THD_WORKING_AREA_SIZE(stacksize);
  wsp = chCoreAlloc(wsz);
  if (wsp == NULL)
    return NULL;

#if CH_DBG_FILL_THREADS == TRUE
  _thread_memfill((uint8_t *)wsp,
                  (uint8_t *)wsp + sizeof(thread_t),
                  CH_DBG_THREAD_FILL_VALUE);
  _thread_memfill((uint8_t *)wsp + sizeof(thread_t),
                  (uint8_t *)wsp + wsz,
                  CH_DBG_STACK_FILL_VALUE);
#endif

  sts = chSysGetStatusAndLockX();
  tp = chThdCreateI(wsp, wsz, prio, (tfunc_t)thread, arg);
  chRegSetThreadNameX(tp, name);
  chThdStartI(tp);
  chSysRestoreStatusX(sts);

  return (sys_thread_t)tp;
}
/**
 * @brief   Creates a new thread allocating the memory from the heap.
 * @pre     The configuration options @p CH_USE_DYNAMIC and @p CH_USE_HEAP
 *          must be enabled in order to use this function.
 * @note    A thread can terminate by calling @p chThdExit() or by simply
 *          returning from its main function.
 * @note    The memory allocated for the thread is not released when the thread
 *          terminates but when a @p chThdWait() is performed.
 *
 * @param[in] heapp     heap from which allocate the memory or @p NULL for the
 *                      default heap
 * @param[in] size      size of the working area to be allocated
 * @param[in] prio      the priority level for the new thread
 * @param[in] pf        the thread function
 * @param[in] arg       an argument passed to the thread function. It can be
 *                      @p NULL.
 * @return              The pointer to the @p Thread structure allocated for
 *                      the thread into the working space area.
 * @retval NULL         if the memory cannot be allocated.
 *
 * @api
 */
Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
                            tprio_t prio, tfunc_t pf, void *arg) {
  void *wsp;
  Thread *tp;

  wsp = chHeapAlloc(heapp, size);
  if (wsp == NULL)
    return NULL;
  
#if CH_DBG_FILL_THREADS
  _thread_memfill((uint8_t *)wsp,
                  (uint8_t *)wsp + sizeof(Thread),
                  CH_THREAD_FILL_VALUE);
  _thread_memfill((uint8_t *)wsp + sizeof(Thread),
                  (uint8_t *)wsp + size,
                  CH_STACK_FILL_VALUE);
#endif
  
  chSysLock();
  tp = chThdCreateI(wsp, size, prio, pf, arg);
  tp->p_flags = THD_MEM_MODE_HEAP;
  chSchWakeupS(tp, RDY_OK);
  chSysUnlock();
  return tp;
}
Example #4
0
/**
 * @brief   Creates a new thread allocating the memory from the specified
 *          memory pool.
 * @pre     The configuration options @p CH_CFG_USE_DYNAMIC and
 *          @p CH_CFG_USE_MEMPOOLS must be enabled in order to use this
 *          function.
 * @note    A thread can terminate by calling @p chThdExit() or by simply
 *          returning from its main function.
 * @note    The memory allocated for the thread is not released when the thread
 *          terminates but when a @p chThdWait() is performed.
 *
 * @param[in] mp        pointer to the memory pool object
 * @param[in] prio      the priority level for the new thread
 * @param[in] pf        the thread function
 * @param[in] arg       an argument passed to the thread function. It can be
 *                      @p NULL.
 * @return              The pointer to the @p thread_t structure allocated for
 *                      the thread into the working space area.
 * @retval  NULL        if the memory pool is empty.
 *
 * @api
 */
thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, tprio_t prio,
                                    tfunc_t pf, void *arg) {
  void *wsp;
  thread_t *tp;

  chDbgCheck(mp != NULL);

  wsp = chPoolAlloc(mp);
  if (wsp == NULL) {
    return NULL;
  }

#if CH_DBG_FILL_THREADS == TRUE
  _thread_memfill((uint8_t *)wsp,
                  (uint8_t *)wsp + sizeof(thread_t),
                  CH_DBG_THREAD_FILL_VALUE);
  _thread_memfill((uint8_t *)wsp + sizeof(thread_t),
                  (uint8_t *)wsp + mp->mp_object_size,
                  CH_DBG_STACK_FILL_VALUE);
#endif

  chSysLock();
  tp = chThdCreateI(wsp, mp->mp_object_size, prio, pf, arg);
  tp->p_flags = CH_FLAG_MODE_MPOOL;
  tp->p_mpool = mp;
  chSchWakeupS(tp, MSG_OK);
  chSysUnlock();

  return tp;
}
Example #5
0
/**
 * @brief   Creates a new thread allocating the memory from the heap.
 * @pre     The configuration options @p CH_CFG_USE_DYNAMIC and
 *          @p CH_CFG_USE_HEAP must be enabled in order to use this function.
 * @note    A thread can terminate by calling @p chThdExit() or by simply
 *          returning from its main function.
 * @note    The memory allocated for the thread is not released when the thread
 *          terminates but when a @p chThdWait() is performed.
 *
 * @param[in] heapp     heap from which allocate the memory or @p NULL for the
 *                      default heap
 * @param[in] size      size of the working area to be allocated
 * @param[in] prio      the priority level for the new thread
 * @param[in] pf        the thread function
 * @param[in] arg       an argument passed to the thread function. It can be
 *                      @p NULL.
 * @return              The pointer to the @p thread_t structure allocated for
 *                      the thread into the working space area.
 * @retval NULL         if the memory cannot be allocated.
 *
 * @api
 */
thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
                              tprio_t prio, tfunc_t pf, void *arg) {
  void *wsp;
  thread_t *tp;

  wsp = chHeapAlloc(heapp, size);
  if (wsp == NULL) {
    return NULL;
  }

#if CH_DBG_FILL_THREADS == TRUE
  _thread_memfill((uint8_t *)wsp,
                  (uint8_t *)wsp + sizeof(thread_t),
                  CH_DBG_THREAD_FILL_VALUE);
  _thread_memfill((uint8_t *)wsp + sizeof(thread_t),
                  (uint8_t *)wsp + size,
                  CH_DBG_STACK_FILL_VALUE);
#endif

  chSysLock();
  tp = chThdCreateI(wsp, size, prio, pf, arg);
  tp->p_flags = CH_FLAG_MODE_HEAP;
  chSchWakeupS(tp, MSG_OK);
  chSysUnlock();

  return tp;
}
Example #6
0
static void thd2_execute(void) {

  threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriority()-4, thread, "D");
  threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority()-5, thread, "E");
  threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriority()-1, thread, "A");
  threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriority()-2, thread, "B");
  /* Done this way for coverage of chThdCreateI() and chThdResume().*/
  chSysLock();
  threads[2] = chThdCreateI(wa[2], WA_SIZE, chThdGetPriority()-3, thread, "C");
  chSysUnlock();
  chThdResume(threads[2]);
  test_wait_threads();
  test_assert_sequence(1, "ABCDE");
}
Example #7
0
/**
 * @brief   Creates a new thread into a static memory area.
 * @note    A thread can terminate by calling @p chThdExit() or by simply
 *          returning from its main function.
 *
 * @param[out] wsp      pointer to a working area dedicated to the thread stack
 * @param[in] size      size of the working area
 * @param[in] prio      the priority level for the new thread
 * @param[in] pf        the thread function
 * @param[in] arg       an argument passed to the thread function. It can be
 *                      @p NULL.
 * @return              The pointer to the @p Thread structure allocated for
 *                      the thread into the working space area.
 *
 * @api
 */
Thread *chThdCreateStatic(void *wsp, size_t size,
                          tprio_t prio, tfunc_t pf, void *arg) {
  Thread *tp;
  
#if CH_DBG_FILL_THREADS
  _thread_memfill((uint8_t *)wsp,
                  (uint8_t *)wsp + sizeof(Thread),
                  CH_THREAD_FILL_VALUE);
  _thread_memfill((uint8_t *)wsp + sizeof(Thread),
                  (uint8_t *)wsp + size,
                  CH_STACK_FILL_VALUE);
#endif
  chSysLock();
  chSchWakeupS(tp = chThdCreateI(wsp, size, prio, pf, arg), RDY_OK);
  chSysUnlock();
  return tp;
}
Example #8
0
/**
 * @brief   Configures and activates the USB peripheral.
 * @note    Starting the OTG cell can be a slow operation carried out with
 *          interrupts disabled, perform it before starting time-critical
 *          operations.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 *
 * @notapi
 */
void usb_lld_start(USBDriver *usbp) {
  stm32_otg_t *otgp = usbp->otg;

  if (usbp->state == USB_STOP) {
    /* Clock activation.*/
#if STM32_USB_USE_OTG1
    if (&USBD1 == usbp) {
      /* OTG FS clock enable and reset.*/
      rccEnableOTG_FS(FALSE);
      rccResetOTG_FS();

      /* Enables IRQ vector.*/
      nvicEnableVector(STM32_OTG1_NUMBER,
                       CORTEX_PRIORITY_MASK(STM32_USB_OTG1_IRQ_PRIORITY));
    }
#endif
#if STM32_USB_USE_OTG2
    if (&USBD2 == usbp) {
      /* OTG HS clock enable and reset.*/
      rccEnableOTG_HS(FALSE);
      rccResetOTG_HS();

      /* Workaround for the problem described here:
         http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1798 */
      rccDisableOTG_HSULPI(TRUE);

      /* Enables IRQ vector.*/
      nvicEnableVector(STM32_OTG2_NUMBER,
                       CORTEX_PRIORITY_MASK(STM32_USB_OTG2_IRQ_PRIORITY));
    }
#endif

    /* Creates the data pump threads in a suspended state. Note, it is
       created only once, the first time @p usbStart() is invoked.*/
    usbp->txpending = 0;
    if (usbp->thd_ptr == NULL)
      usbp->thd_ptr = usbp->thd_wait = chThdCreateI(usbp->wa_pump,
                                                    sizeof usbp->wa_pump,
                                                    STM32_USB_OTG_THREAD_PRIO,
                                                    usb_lld_pump,
                                                    usbp);

    /* - Forced device mode.
       - USB turn-around time = TRDT_VALUE.
       - Full Speed 1.1 PHY.*/
    otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL;

    /* 48MHz 1.1 PHY.*/
    otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11;

    /* PHY enabled.*/
    otgp->PCGCCTL = 0;

    /* Internal FS PHY activation.*/
#if defined(BOARD_OTG_NOVBUSSENS)
    otgp->GCCFG = GCCFG_NOVBUSSENS | GCCFG_VBUSASEN | GCCFG_VBUSBSEN |
                  GCCFG_PWRDWN;
#else
    otgp->GCCFG = GCCFG_VBUSASEN | GCCFG_VBUSBSEN | GCCFG_PWRDWN;
#endif

    /* Soft core reset.*/
    otg_core_reset(usbp);

    /* Interrupts on TXFIFOs half empty.*/
    otgp->GAHBCFG = 0;

    /* Endpoints re-initialization.*/
    otg_disable_ep(usbp);

    /* Clear all pending Device Interrupts, only the USB Reset interrupt
       is required initially.*/
    otgp->DIEPMSK  = 0;
    otgp->DOEPMSK  = 0;
    otgp->DAINTMSK = 0;
    if (usbp->config->sof_cb == NULL)
      otgp->GINTMSK  = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM |
                       GINTMSK_ESUSPM  |*/;
    else
      otgp->GINTMSK  = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM |
                       GINTMSK_ESUSPM */ | GINTMSK_SOFM;
    otgp->GINTSTS  = 0xFFFFFFFF;         /* Clears all pending IRQs, if any. */

    /* Global interrupts enable.*/
    otgp->GAHBCFG |= GAHBCFG_GINTMSK;
  }
}
Example #9
0
OsTask *osCreateTask(const char_t *name, OsTaskCode taskCode,
   void *params, size_t stackSize, int_t priority)
{
   uint_t i;
   void *wa;
   OsTask *task = NULL;

   //Compute the size of the stack in bytes
   stackSize *= sizeof(uint_t);

   //Allocate a memory block to hold the working area
   wa = osAllocMem(THD_WA_SIZE(stackSize));

   //Successful memory allocation?
   if(wa != NULL)
   {
      //Enter critical section
      chSysLock();

      //Loop through task table
      for(i = 0; i < OS_PORT_MAX_TASKS; i++)
      {
         //Check whether the current entry is free
         if(taskTable[i].tp == NULL)
            break;
      }

      //Any entry available in the table?
      if(i < OS_PORT_MAX_TASKS)
      {
         //Create a new task
         taskTable[i].tp = chThdCreateI(wa, THD_WA_SIZE(stackSize),
            priority, (tfunc_t) taskCode, params);

         //Check whether the task was successfully created
         if(taskTable[i].tp != NULL)
         {
            //Insert the newly created task in the ready list
            chSchWakeupS(taskTable[i].tp, RDY_OK);

            //Save task pointer
            task = &taskTable[i];
            //Save working area base address
            waTable[i] = wa;

            //Leave critical section
            chSysUnlock();
         }
         else
         {
            //Leave critical section
            chSysUnlock();
            //Clean up side effects
            osFreeMem(wa);
         }
      }
      else
      {
         //Leave critical section
         chSysUnlock();
         //No entry available in the table
         osFreeMem(wa);
      }
   }

   //Return a pointer to the newly created task
   return task;
}