/** * @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(); /* 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_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 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) { _scheduler_init(); _vt_init(); _trace_init(); #if CH_DBG_SYSTEM_STATE_CHECK == TRUE ch.dbg.isr_cnt = (cnt_t)0; ch.dbg.lock_cnt = (cnt_t)0; #endif #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_CFG_NO_IDLE_THREAD == FALSE /* Now this instructions flow becomes the main thread.*/ #if CH_CFG_USE_REGISTRY == TRUE currp = _thread_init(&ch.mainthread, (const char *)&ch_debug, NORMALPRIO); #else currp = _thread_init(&ch.mainthread, "main", NORMALPRIO); #endif #else /* Now this instructions flow becomes the idle thread.*/ currp = _thread_init(&ch.mainthread, "idle", IDLEPRIO); #endif #if CH_DBG_ENABLE_STACK_CHECK == TRUE { /* Setting up the base address of the static main thread stack, the symbol must be provided externally.*/ extern stkalign_t __main_thread_stack_base__; currp->wabase = &__main_thread_stack_base__; } #elif CH_CFG_USE_DYNAMIC == TRUE currp->wabase = NULL; #endif /* Setting up the caller as current thread.*/ currp->state = CH_STATE_CURRENT; /* Port layer initialization last because it depend on some of the initializations performed before.*/ port_init(); #if CH_DBG_STATISTICS == TRUE /* Starting measurement for this thread.*/ chTMStartMeasurementX(&currp->stats); #endif /* It is alive now.*/ chSysEnable(); #if CH_CFG_NO_IDLE_THREAD == FALSE { static const thread_descriptor_t idle_descriptor = { "idle", THD_WORKING_AREA_BASE(ch_idle_thread_wa), THD_WORKING_AREA_END(ch_idle_thread_wa), IDLEPRIO, _idle_thread, NULL }; /* 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) chThdCreate(&idle_descriptor); } #endif }