/*..........................................................................*/ void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, QEvt const *ie) { /* create the embOS message box for the AO */ OS_CreateMB(&me->eQueue, (OS_U16)sizeof(QEvt *), (OS_UINT)qLen, (void *)&qSto[0]); me->prio = prio; /* save the QF priority */ QF_add_(me); /* make QF aware of this active object */ QMSM_INIT(&me->super, ie); /* thake the top-most initial tran. */ QS_FLUSH(); /* flush the trace buffer to the host */ /* create an embOS task for the AO */ OS_CreateTaskEx(&me->thread, "AO", (OS_PRIO)prio, /* embOS uses the same numbering as QP */ &thread_function, (void OS_STACKPTR *)stkSto, (OS_UINT)stkSize, (OS_UINT)0, /* no AOs at the same prio */ (void *)me); }
//............................................................................ void QMActive::start(uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, QEvt const *ie) { // create the embOS message box for the AO OS_CreateMB(&m_eQueue, static_cast<OS_U16>(sizeof(QEvt *)), static_cast<OS_UINT>(qLen), static_cast<void *>(&qSto[0])); m_prio = prio; // save the QF priority QF::add_(this); // make QF aware of this active object init(ie); // thake the top-most initial tran. QS_FLUSH(); // flush the trace buffer to the host // create an embOS task for the AO OS_CreateTaskEx(&m_thread, "AO", static_cast<OS_PRIO>(prio), // embOS uses same numbering as QP &thread_function, static_cast<void OS_STACKPTR *>(stkSto), static_cast<OS_UINT>(stkSize), static_cast<OS_UINT>(0), // no AOs at the same prio this); }
/*..........................................................................*/ void QActive_start(QActive *me, uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvent const *ie) { int err; me->eQueue = xQueueCreate( qLen , sizeof(QEvent*) ); Q_ASSERT(me->eQueue != (void *)0); /* queue created */ me->prio = prio; /* save the QF priority */ QF_add_(me); /* make QF aware of this active object */ QF_ACTIVE_INIT_(&me->super, ie); /* execute initial transition */ QS_FLUSH(); /* flush the trace buffer to the host */ // vTaskDelay( 0x32 ); /* task is represented by its unique priority */ // me->thread = (uint8_t)(QF_MAX_ACTIVE - me->prio); /* map to OSprio. */ err= xTaskCreate( task_function, task_name[task_idx] , 0x100 * 3, me,tskIDLE_PRIORITY+me->prio, &me->thread); Q_ASSERT(me->thread != (xTaskHandle) NULL ); task_idx++; }
//**************************************************************************** // @description // Starts execution of the AO and registers the AO with the framework. // // @param[in] prio priority at which to start the active object // @param[in] qSto pointer to the storage for the ring buffer of the // event queue (used only with the built-in QP::QEQueue) // @param[in] qLen length of the event queue (in events) // @param[in] stkSto pointer to the stack storage (used only when // per-AO stack is needed) // @param[in] stkSize stack size (in bytes) // @param[in] ie pointer to the optional initialization event // (might be NULL). // void QMActive::start(uint_fast8_t const prio, QEvt const *qSto[], uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, QEvt const * const ie) { Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't start AO's in an ISR! */ && (prio <= (uint_fast8_t)QF_MAX_ACTIVE) && (qSto != static_cast<QEvt const **>(0)) && (qLen != static_cast<uint_fast16_t>(0)) && (stkSto != static_cast<void *>(0)) && (stkSize != static_cast<uint_fast16_t>(0))); m_eQueue.init(qSto, qLen); // initialize QEQueue of this AO // initialize the stack of the private thread QXK_stackInit_(this, static_cast<QXThreadHandler>(&thread_ao), stkSto, stkSize); m_prio = prio; // set the QF priority of this AO QF::add_(this); // make QF aware of this AO this->init(ie); // take the top-most initial tran. (virtual) QS_FLUSH(); // flush the trace buffer to the host QF_CRIT_STAT_ QF_CRIT_ENTRY_(); QXK_attr_.readySet.insert(m_prio); if (QXK_attr_.curr != static_cast<QMActive *>(0)) { // is QXK running? QXK_sched_(); } QF_CRIT_EXIT_(); }
/*..........................................................................*/ void QActive_start(QActive *me, uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvent const *ie) { INT8U err; me->eQueue = OSQCreate((void **)qSto, qLen); Q_ASSERT(me->eQueue != (OS_EVENT *)0); /* uC/OS-II queue created */ me->prio = prio; /* save the QF priority */ QF_add_(me); /* make QF aware of this active object */ QF_ACTIVE_INIT_(&me->super, ie); /* execute initial transition */ QS_FLUSH(); /* flush the trace buffer to the host */ /* uC/OS task is represented by its unique priority */ me->thread = (uint8_t)(QF_MAX_ACTIVE - me->prio); /* map to uC/OS prio. */ err = OSTaskCreateExt(&task_function, /* the task function */ me, /* the 'pdata' parameter */ &(((OS_STK *)stkSto)[(stkSize / sizeof(OS_STK)) - 1]), /* ptos */ me->thread, /* uC/OS-II task priority */ me->thread, /* task id */ (OS_STK *)stkSto, /* pbos */ stkSize/sizeof(OS_STK), /* size of the stack in OS_STK units */ (void *)0, /* pext */ (INT16U)OS_TASK_OPT_STK_CLR); /* opt */ Q_ASSERT(err == OS_NO_ERR); /* uC/OS-II task created */ }
//............................................................................ void QActive::start(uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvent const *ie) { m_eQueue = OSQCreate((void **)qSto, qLen); Q_ASSERT(m_eQueue != (OS_EVENT *)0); // uC/OS-II queue created m_prio = prio; // set the QF priority QF::add_(this); // make QF aware of this active object init(ie); // execute the initial transition QS_FLUSH(); // flush the trace buffer to the host m_thread = QF_MAX_ACTIVE - m_prio; // map QF priority to uC/OS-II INT8U err = OSTaskCreateExt(&task_function, // the task function this, // the 'pdata' parameter &(((OS_STK *)stkSto)[(stkSize / sizeof(OS_STK)) - 1]), // ptos m_thread, // uC/OS-II task priority m_thread, // task id (OS_STK *)stkSto, // pbos stkSize/sizeof(OS_STK), // size of the stack in OS_STK units (void *)0, // pext (INT16U)OS_TASK_OPT_STK_CLR); // opt Q_ASSERT(err == OS_NO_ERR); // uC/OS-II task created }
/* QActive functions =======================================================*/ void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, QEvt const *ie) { DWORD threadId; int win32Prio; void *fudgedQSto; uint_fast16_t fudgedQLen; Q_REQUIRE_ID(700, ((uint_fast8_t)0 < prio) /* priority must be in range */ && (prio <= (uint_fast8_t)QF_MAX_ACTIVE) && (qSto != (QEvt const **)0) /* queue storage must be... */ && (qLen > (uint_fast16_t)0) /* ...provided */ && (stkSto == (void *)0)); /* statck storage must NOT... * ... be provided */ me->prio = prio; /* set QF priority of this AO before adding it to QF */ QF_add_(me); /* make QF aware of this active object */ /* ignore the original storage for the event queue 'qSto' and * instead allocate an oversized "fudged" storage for the queue. * See also NOTE2 in qf_port.h. */ Q_ASSERT_ID(710, (uint32_t)qLen * QF_WIN32_FUDGE_FACTOR < USHRT_MAX); fudgedQLen = qLen * QF_WIN32_FUDGE_FACTOR; /* fudge the queue length */ fudgedQSto = calloc(fudgedQLen, sizeof(QEvt *)); /* new queue storage */ Q_ASSERT_ID(720, fudgedQSto != (void *)0); /* allocation must succeed */ QEQueue_init(&me->eQueue, (QEvt const **)fudgedQSto, fudgedQLen); /* save osObject as integer, in case it contains the Win32 priority */ win32Prio = (me->osObject != (void *)0) ? (int)me->osObject : THREAD_PRIORITY_NORMAL; /* create the Win32 "event" to throttle the AO's event queue */ me->osObject = CreateEvent(NULL, FALSE, FALSE, NULL); QMSM_INIT(&me->super, ie); /* take the top-most initial tran. */ QS_FLUSH(); /* flush the QS trace buffer to the host */ /* stack size not provided? */ if (stkSize == 0U) { stkSize = 1024U; /* NOTE: will be rounded up to the nearest page */ } /* create a Win32 thread for the AO; * The thread is created with THREAD_PRIORITY_NORMAL */ me->thread = CreateThread(NULL, stkSize, &ao_thread, me, 0, &threadId); Q_ASSERT_ID(730, me->thread != (HANDLE)0); /* thread must be created */ /* was the thread priority provided? */ if (win32Prio != 0) { SetThreadPriority(me->thread, win32Prio); } }
/*..........................................................................*/ void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, QEvt const *ie) { pthread_t thread; pthread_attr_t attr; struct sched_param param; /* p-threads allocate stack internally */ Q_REQUIRE_ID(600, stkSto == (void *)0); QEQueue_init(&me->eQueue, qSto, qLen); pthread_cond_init(&me->osObject, 0); me->prio = (uint8_t)prio; QF_add_(me); /* make QF aware of this active object */ QMSM_INIT(&me->super, ie); /* take the top-most initial tran. */ QS_FLUSH(); /* flush the QS trace buffer to the host */ pthread_attr_init(&attr); /* SCHED_FIFO corresponds to real-time preemptive priority-based scheduler * NOTE: This scheduling policy requires the superuser privileges */ pthread_attr_setschedpolicy(&attr, SCHED_FIFO); /* see NOTE04 */ param.sched_priority = prio + (sched_get_priority_max(SCHED_FIFO) - QF_MAX_ACTIVE - 3); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (stkSize == 0U) { /* set the allowed minimum */ stkSize = (uint_fast16_t)PTHREAD_STACK_MIN; } pthread_attr_setstacksize(&attr, (size_t)stkSize); if (pthread_create(&thread, &attr, &thread_routine, me) != 0) { /* Creating the p-thread with the SCHED_FIFO policy failed. Most * probably this application has no superuser privileges, so we just * fall back to the default SCHED_OTHER policy and priority 0. */ pthread_attr_setschedpolicy(&attr, SCHED_OTHER); param.sched_priority = 0; pthread_attr_setschedparam(&attr, ¶m); Q_ALLEGE(pthread_create(&thread, &attr, &thread_routine, me)== 0); } pthread_attr_destroy(&attr); me->thread = (uint8_t)1; }
/*..........................................................................*/ void QF_run(void) { uint8_t p; QActive *a; QEvent const *e; QF_INT_LOCK_KEY_ QF_onStartup(); /* startup callback */ for (;;) { /* the background loop */ QF_INT_LOCK_(); #if (QF_MAX_ACTIVE <= 8) if (QPSet8_notEmpty(&QF_readySet_)) { QPSet8_findMax(&QF_readySet_, p); #else if (QPSet64_notEmpty(&QF_readySet_)) { QPSet64_findMax(&QF_readySet_, p); #endif a = QF_active_[p]; QF_INT_UNLOCK_(); e = QActive_get_(a); /* get the next event for this AO */ QF_ACTIVE_DISPATCH_(&a->super, e); /* dispatch to the AO */ QF_gc(e); /* determine if event is garbage and collect it if so */ } else { #ifndef QF_INT_KEY_TYPE QF_onIdle(); /* see NOTE01 */ #else QF_onIdle(intLockKey_); /* see NOTE01 */ #endif /* QF_INT_KEY_TYPE */ } } } /*..........................................................................*/ void QActive_start(QActive *me, uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvent const *ie) { Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE) && (stkSto == (void *)0)); /* does not need per-actor stack */ (void)stkSize; /* avoid the "unused parameter" compiler warning */ QEQueue_init(&me->eQueue, qSto, (QEQueueCtr)qLen);/* initialize QEQueue */ me->prio = prio; /* set the QF priority of this active object */ QF_add_(me); /* make QF aware of this active object */ QF_ACTIVE_INIT_(&me->super, ie); /* execute initial transition */ QS_FLUSH(); /* flush the trace buffer to the host */ }
//............................................................................ void QActive::start(uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t /*lint -e1904 stkSize */, QEvent const *ie) { Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE) && (stkSto == (void *)0)); // does not need per-actor stack m_eQueue.init(qSto, (QEQueueCtr)qLen); // initialize QEQueue m_prio = prio; // set the QF priority of this active object QF::add_(this); // make QF aware of this active object init(ie); // execute initial transition QS_FLUSH(); // flush the trace buffer to the host }
/*..........................................................................*/ void QActive_start(QActive *me, uint8_t prio, QEvent const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvent const *ie) { pthread_attr_t attr; struct sched_param param; Q_REQUIRE(stkSto == (void *)0); /* p-threads allocate stack internally */ QEQueue_init(&me->eQueue, qSto, (QEQueueCtr)qLen); pthread_cond_init(&me->osObject, 0); me->prio = prio; QF_add_(me); /* make QF aware of this active object */ QF_ACTIVE_INIT_(&me->super, ie); /* execute the initial transition */ QS_FLUSH(); /* flush the trace buffer to the host */ pthread_attr_init(&attr); /* SCHED_FIFO corresponds to real-time preemptive priority-based scheduler * NOTE: This scheduling policy requires the superuser privileges */ pthread_attr_setschedpolicy(&attr, SCHED_FIFO); /* see NOTE04 */ param.sched_priority = prio + (sched_get_priority_max(SCHED_FIFO) - QF_MAX_ACTIVE - 3); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (pthread_create(&me->thread, &attr, &thread_routine, me) != 0) { /* Creating the p-thread with the SCHED_FIFO policy failed. * Most probably this application has no superuser privileges, * so we just fall back to the default SCHED_OTHER policy * and priority 0. */ pthread_attr_setschedpolicy(&attr, SCHED_OTHER); param.sched_priority = 0; pthread_attr_setschedparam(&attr, ¶m); Q_ALLEGE(pthread_create(&me->thread, &attr, &thread_routine, me)== 0); } pthread_attr_destroy(&attr); }
//............................................................................ void GuiQActive::start(uint_fast8_t const prio, QEvt const *qSto[], uint_fast16_t const /*qLen*/, void * const stkSto, uint_fast16_t const /*stkSize*/, QEvt const * const ie) { Q_REQUIRE((static_cast<uint_fast8_t>(0) < prio) && (prio <= static_cast<uint_fast8_t>(QF_MAX_ACTIVE)) && (qSto == (QEvt const **)0)/* does not need per-actor queue */ && (stkSto == static_cast<void *>(0))); // AOs don't need stack setPrio(prio); // set the QF priority of this AO QF::add_(this); // make QF aware of this AO static_cast<GuiApp *>(QApplication::instance())->registerAct(this); this->init(ie); // execute initial transition (virtual call) QS_FLUSH(); // flush the trace buffer to the host }
/*..........................................................................*/ void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, QEvt const *ie) { /* * The following os_thread_def_AO object specifies the attributes of the * RTX thread for Active Objects. This object is allocated on the stack, * because it only serves to create the specific task for this AO. */ osThreadDef_t os_thread_def_AO; /* no stack storage because RTX pre-allocates stacks internally, * but the queue storage and size must be provided */ Q_REQUIRE_ID(510, (stkSto == (void *)0) && (qSto != (QEvt const **)0) && (qLen > (uint_fast16_t)0)); /* create the QP event queue for the AO */ QEQueue_init(&me->eQueue, qSto, qLen); me->prio = prio; /* save the QF priority */ QF_add_(me); /* make QF aware of this active object */ QMSM_INIT(&me->super, ie); /* thake the top-most initial tran. */ QS_FLUSH(); /* flush the trace buffer to the host */ /* create the RTX thread for the AO... */ os_thread_def_AO.pthread = &ao_thread; /* RTX thread routine for AOs */ os_thread_def_AO.instances = (uint32_t)1; /* # instances of this thread */ os_thread_def_AO.stacksize = (uint32_t)stkSize; /* stack size [BYTES!] */ os_thread_def_AO.tpriority = (me->osObject != (uint32_t)0) /* RTX priority provided? */ ? (osPriority)(me->osObject) /* use the provided value */ : osPriorityNormal; /* use the default */ me->thread = osThreadCreate(&os_thread_def_AO, (void *)me); /* ensure that the thread was created correctly */ Q_ENSURE_ID(520, me->thread != (osThreadId)0); }
/*..........................................................................*/ void QActive_start(QActive *me, uint8_t prio, QEvt const *qSto[], uint32_t qLen, void *stkSto, uint32_t stkSize, QEvt const *ie) { Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE)); QEQueue_init(&me->eQueue, qSto, (QEQueueCtr)qLen); me->prio = prio; QF_add_(me); /* make QF aware of this active object */ #if defined(QK_TLS) || defined(QK_EXT_SAVE) me->osObject = (uint8_t)stkSize; /* osObject contains the thread flags */ me->thread = stkSto;/* contains the pointer to the thread-local storage */ #else Q_ASSERT((stkSto == (void *)0) && (stkSize == (uint32_t)0)); #endif QF_ACTIVE_INIT_(&me->super, ie); /* execute initial transition */ QS_FLUSH(); /* flush the trace buffer to the host */ }