/** * @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; }
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; }
/** * @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; }
/** * @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; }
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"); }
/** * @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; }
/** * @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; } }
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; }