ChibiOS/RT
2.5.1
chsys.c
Go to the documentation of this file.
00001 /*
00002     ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
00003                  2011,2012 Giovanni Di Sirio.
00004 
00005     This file is part of ChibiOS/RT.
00006 
00007     ChibiOS/RT is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     ChibiOS/RT is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 /**
00022  * @file    chsys.c
00023  * @brief   System related code.
00024  *
00025  * @addtogroup system
00026  * @details System related APIs and services:
00027  *          - Initialization.
00028  *          - Locks.
00029  *          - Interrupt Handling.
00030  *          - Power Management.
00031  *          - Abnormal Termination.
00032  *          .
00033  * @{
00034  */
00035 
00036 #include "ch.h"
00037 
00038 #if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
00039 /**
00040  * @brief   Idle thread working area.
00041  */
00042 WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE);
00043 
00044 /**
00045  * @brief   This function implements the idle thread infinite loop.
00046  * @details The function puts the processor in the lowest power mode capable
00047  *          to serve interrupts.<br>
00048  *          The priority is internally set to the minimum system value so
00049  *          that this thread is executed only if there are no other ready
00050  *          threads in the system.
00051  *
00052  * @param[in] p the thread parameter, unused in this scenario
00053  */
00054 void _idle_thread(void *p) {
00055 
00056   (void)p;
00057   chRegSetThreadName("idle");
00058   while (TRUE) {
00059     port_wait_for_interrupt();
00060     IDLE_LOOP_HOOK();
00061   }
00062 }
00063 #endif /* CH_NO_IDLE_THREAD */
00064 
00065 /**
00066  * @brief   ChibiOS/RT initialization.
00067  * @details After executing this function the current instructions stream
00068  *          becomes the main thread.
00069  * @pre     Interrupts must be still disabled when @p chSysInit() is invoked
00070  *          and are internally enabled.
00071  * @post    The main thread is created with priority @p NORMALPRIO.
00072  * @note    This function has special, architecture-dependent, requirements,
00073  *          see the notes into the various port reference manuals.
00074  *
00075  * @special
00076  */
00077 void chSysInit(void) {
00078   static Thread mainthread;
00079 #if CH_DBG_ENABLE_STACK_CHECK
00080   extern stkalign_t __main_thread_stack_base__;
00081 #endif
00082 
00083   port_init();
00084   _scheduler_init();
00085   _vt_init();
00086 #if CH_USE_MEMCORE
00087   _core_init();
00088 #endif
00089 #if CH_USE_HEAP
00090   _heap_init();
00091 #endif
00092 #if CH_DBG_ENABLE_TRACE
00093   _trace_init();
00094 #endif
00095 
00096   /* Now this instructions flow becomes the main thread.*/
00097   setcurrp(_thread_init(&mainthread, NORMALPRIO));
00098   currp->p_state = THD_STATE_CURRENT;
00099 #if CH_DBG_ENABLE_STACK_CHECK
00100   /* This is a special case because the main thread Thread structure is not
00101      adjacent to its stack area.*/
00102   currp->p_stklimit = &__main_thread_stack_base__;
00103 #endif
00104   chSysEnable();
00105 
00106   /* Note, &ch_debug points to the string "main" if the registry is
00107      active, else the parameter is ignored.*/
00108   chRegSetThreadName((const char *)&ch_debug);
00109 
00110 #if !CH_NO_IDLE_THREAD
00111   /* This thread has the lowest priority in the system, its role is just to
00112      serve interrupts in its context while keeping the lowest energy saving
00113      mode compatible with the system status.*/
00114   chThdCreateStatic(_idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO,
00115                     (tfunc_t)_idle_thread, NULL);
00116 #endif
00117 }
00118 
00119 /**
00120  * @brief   Handles time ticks for round robin preemption and timer increments.
00121  * @details Decrements the remaining time quantum of the running thread
00122  *          and preempts it when the quantum is used up. Increments system
00123  *          time and manages the timers.
00124  * @note    The frequency of the timer determines the system tick granularity
00125  *          and, together with the @p CH_TIME_QUANTUM macro, the round robin
00126  *          interval.
00127  *
00128  * @iclass
00129  */
00130 void chSysTimerHandlerI(void) {
00131 
00132   chDbgCheckClassI();
00133 
00134 #if CH_TIME_QUANTUM > 0
00135   /* Running thread has not used up quantum yet? */
00136   if (currp->p_preempt > 0)
00137     /* Decrement remaining quantum.*/
00138     currp->p_preempt--;
00139 #endif
00140 #if CH_DBG_THREADS_PROFILING
00141   currp->p_time++;
00142 #endif
00143   chVTDoTickI();
00144 #if defined(SYSTEM_TICK_EVENT_HOOK)
00145   SYSTEM_TICK_EVENT_HOOK();
00146 #endif
00147 }
00148 
00149 /** @} */