/** * @brief ChibiOS/RT initialization. * @details After executing this function the current instructions stream * becomes the main thread. * @pre Interrupts must disabled before invoking this function. * @post The main thread is created with priority @p NORMALPRIO and * interrupts are enabled. * * @special */ void chSysInit(void) { #if CH_DBG_ENABLE_STACK_CHECK == TRUE extern stkalign_t __main_thread_stack_base__; #endif port_init(); _scheduler_init(); _vt_init(); #if CH_CFG_USE_TM == TRUE _tm_init(); #endif #if CH_CFG_USE_MEMCORE == TRUE _core_init(); #endif #if CH_CFG_USE_HEAP == TRUE _heap_init(); #endif #if CH_DBG_STATISTICS == TRUE _stats_init(); #endif #if CH_DBG_ENABLE_TRACE == TRUE _dbg_trace_init(); #endif #if CH_CFG_NO_IDLE_THREAD == FALSE /* Now this instructions flow becomes the main thread.*/ setcurrp(_thread_init(&ch.mainthread, NORMALPRIO)); #else /* Now this instructions flow becomes the idle thread.*/ setcurrp(_thread_init(&ch.mainthread, IDLEPRIO)); #endif currp->p_state = CH_STATE_CURRENT; #if CH_DBG_ENABLE_STACK_CHECK == TRUE /* This is a special case because the main thread thread_t structure is not adjacent to its stack area.*/ currp->p_stklimit = &__main_thread_stack_base__; #endif chSysEnable(); /* Note, &ch_debug points to the string "main" if the registry is active, else the parameter is ignored.*/ chRegSetThreadName((const char *)&ch_debug); #if CH_CFG_NO_IDLE_THREAD == FALSE /* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/ (void) chThdCreateStatic(ch.idle_thread_wa, sizeof(ch.idle_thread_wa), IDLEPRIO, (tfunc_t)_idle_thread, NULL); #endif }
/** * @brief ChibiOS/RT initialization. * @details After executing this function the current instructions stream * becomes the main thread. * @pre Interrupts must be still disabled when @p chSysInit() is invoked * and are internally enabled. * @post The main thread is created with priority @p NORMALPRIO. * @note This function has special, architecture-dependent, requirements, * see the notes into the various port reference manuals. * * @special */ void chSysInit(void) { static Thread mainthread; port_init(); scheduler_init(); vt_init(); #if CH_USE_MEMCORE core_init(); #endif #if CH_USE_HEAP heap_init(); #endif #if CH_DBG_ENABLE_TRACE trace_init(); #endif /* Now this instructions flow becomes the main thread.*/ setcurrp(_thread_init(&mainthread, NORMALPRIO)); currp->p_state = THD_STATE_CURRENT; chSysEnable(); #if !CH_NO_IDLE_THREAD /* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/ chThdCreateStatic(_idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO, (tfunc_t)_idle_thread, NULL); #endif }
/** * @brief Switches to the first thread on the runnable queue. * @details The current thread is positioned in the ready list ahead of all * threads having the same priority. * @note Not a user function, it is meant to be invoked by the scheduler * itself or from within the port layer. * * @special */ void chSchDoRescheduleAhead(void) { thread_t *otp, *cp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(queue_fifo_remove(&ch.rlist.r_queue)); #if defined(CH_CFG_IDLE_LEAVE_HOOK) if (otp->p_prio == IDLEPRIO) { CH_CFG_IDLE_LEAVE_HOOK(); } #endif currp->p_state = CH_STATE_CURRENT; otp->p_state = CH_STATE_READY; cp = (thread_t *)&ch.rlist.r_queue; do { cp = cp->p_next; } while (cp->p_prio > otp->p_prio); /* Insertion on p_prev.*/ otp->p_next = cp; otp->p_prev = cp->p_prev; otp->p_prev->p_next = cp->p_prev = otp; chSysSwitch(currp, otp); }
/** * @brief Wakes up a thread. * @details The thread is inserted into the ready list or immediately made * running depending on its relative priority compared to the current * thread. * @pre The thread must not be already inserted in any list through its * @p p_next and @p p_prev or list corruption would occur. * @note It is equivalent to a @p chSchReadyI() followed by a * @p chSchRescheduleS() but much more efficient. * @note The function assumes that the current thread has the highest * priority. * * @param[in] ntp the thread to be made ready * @param[in] msg the wakeup message * * @sclass */ void chSchWakeupS(thread_t *ntp, msg_t msg) { chDbgCheckClassS(); /* Storing the message to be retrieved by the target thread when it will restart execution.*/ ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current one then it is just inserted in the ready list else it made running immediately and the invoking thread goes in the ready list instead.*/ if (ntp->p_prio <= currp->p_prio) { chSchReadyI(ntp); } else { thread_t *otp = chSchReadyI(currp); setcurrp(ntp); #if defined(CH_CFG_IDLE_LEAVE_HOOK) if (otp->p_prio == IDLEPRIO) { CH_CFG_IDLE_LEAVE_HOOK(); } #endif ntp->p_state = CH_STATE_CURRENT; chSysSwitch(ntp, otp); } }
void chSchDoRescheduleBehind(void) { Thread *otp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; otp->p_preempt = CH_TIME_QUANTUM; chSchReadyI(otp); chSysSwitch(currp, otp); }
void chSchGoSleepS(tstate_t newstate) { Thread *otp; (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chDbgTrace(otp); chSysSwitchI(currp, otp); }
void chSchGoSleepS(tstate_t newstate) { Thread *otp; chDbgCheckClassS(); (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 /* The thread is renouncing its remaining time slices so it will have a new time quantum when it will wakeup.*/ otp->p_preempt = CH_TIME_QUANTUM; #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chSysSwitch(currp, otp); }
void chSchWakeupS(Thread *ntp, msg_t msg) { chDbgCheckClassS(); ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current one then it is just inserted in the ready list else it made running immediately and the invoking thread goes in the ready list instead.*/ if (ntp->p_prio <= currp->p_prio) chSchReadyI(ntp); else { Thread *otp = chSchReadyI(currp); setcurrp(ntp); ntp->p_state = THD_STATE_CURRENT; chSysSwitch(ntp, otp); } }
/** * @brief Switches to the first thread on the runnable queue. * @details The current thread is positioned in the ready list behind all * threads having the same priority. The thread regains its time * quantum. * @note Not a user function, it is meant to be invoked by the scheduler * itself or from within the port layer. * * @special */ void chSchDoRescheduleBehind(void) { thread_t *otp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(queue_fifo_remove(&ch.rlist.r_queue)); #if defined(CH_CFG_IDLE_LEAVE_HOOK) if (otp->p_prio == IDLEPRIO) { CH_CFG_IDLE_LEAVE_HOOK(); } #endif currp->p_state = CH_STATE_CURRENT; #if CH_CFG_TIME_QUANTUM > 0 otp->p_preempt = CH_CFG_TIME_QUANTUM; #endif chSchReadyI(otp); chSysSwitch(currp, otp); }
void chSchDoRescheduleAhead(void) { Thread *otp, *cp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; otp->p_state = THD_STATE_READY; cp = (Thread *)&rlist.r_queue; do { cp = cp->p_next; } while (cp->p_prio > otp->p_prio); /* Insertion on p_prev.*/ otp->p_next = cp; otp->p_prev = cp->p_prev; otp->p_prev->p_next = cp->p_prev = otp; chSysSwitch(currp, otp); }
void chSchWakeupS(Thread *ntp, msg_t msg) { ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current one then it is just inserted in the ready list else it made running immediately and the invoking thread goes in the ready list instead.*/ if (ntp->p_prio <= currp->p_prio) chSchReadyI(ntp); else { Thread *otp = chSchReadyI(currp); #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif setcurrp(ntp); ntp->p_state = THD_STATE_CURRENT; chDbgTrace(otp); chSysSwitchI(ntp, otp); } }
/** * @brief Puts the current thread to sleep into the specified state. * @details The thread goes into a sleeping state. The possible * @ref thread_states are defined into @p threads.h. * * @param[in] newstate the new thread state * * @sclass */ void chSchGoSleepS(tstate_t newstate) { thread_t *otp; chDbgCheckClassS(); (otp = currp)->p_state = newstate; #if CH_CFG_TIME_QUANTUM > 0 /* The thread is renouncing its remaining time slices so it will have a new time quantum when it will wakeup.*/ otp->p_preempt = CH_CFG_TIME_QUANTUM; #endif setcurrp(queue_fifo_remove(&ch.rlist.r_queue)); #if defined(CH_CFG_IDLE_ENTER_HOOK) if (currp->p_prio == IDLEPRIO) { CH_CFG_IDLE_ENTER_HOOK(); } #endif currp->p_state = CH_STATE_CURRENT; chSysSwitch(currp, otp); }
/** * @brief ChibiOS/RT initialization. * @details After executing this function the current instructions stream * becomes the main thread. * @pre Interrupts must be still disabled when @p chSysInit() is invoked * and are internally enabled. * @post The main thread is created with priority @p NORMALPRIO. * @note This function has special, architecture-dependent, requirements, * see the notes into the various port reference manuals. * * @special */ void chSysInit(void) { static Thread mainthread; #if CH_DBG_ENABLE_STACK_CHECK extern stkalign_t __main_thread_stack_base__; #endif port_init(); _scheduler_init(); _vt_init(); #if CH_USE_MEMCORE _core_init(); #endif #if CH_USE_HEAP _heap_init(); #endif #if CH_DBG_ENABLE_TRACE _trace_init(); #endif /* Now this instructions flow becomes the main thread.*/ setcurrp(_thread_init(&mainthread, NORMALPRIO)); currp->p_state = THD_STATE_CURRENT; #if CH_DBG_ENABLE_STACK_CHECK /* This is a special case because the main thread Thread structure is not adjacent to its stack area.*/ currp->p_stklimit = &__main_thread_stack_base__; #endif chSysEnable(); chRegSetThreadName("main"); #if !CH_NO_IDLE_THREAD /* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/ chThdCreateStatic(_idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO, (tfunc_t)_idle_thread, NULL); #endif }