|
ChibiOS/RT
2.5.1 |
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 /** @} */