ChibiOS/RT Architecture - Reference Manual - Guides |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. 00003 00004 This file is part of ChibiOS/RT. 00005 00006 ChibiOS/RT is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 ChibiOS/RT is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 00019 --- 00020 00021 A special exception to the GPL can be applied should you wish to distribute 00022 a combined work that includes ChibiOS/RT, without being obliged to provide 00023 the source code for any proprietary components. See the file exception.txt 00024 for full details of how and when the exception can be applied. 00025 */ 00026 00027 /** 00028 * @file chsys.c 00029 * @brief System related code. 00030 * 00031 * @addtogroup system 00032 * @details System related APIs and services: 00033 * - Initialization. 00034 * - Locks. 00035 * - Interrupt Handling. 00036 * - Power Management. 00037 * - Abnormal Termination. 00038 * . 00039 * @{ 00040 */ 00041 00042 #include "ch.h" 00043 00044 static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); 00045 00046 /** 00047 * @brief This function implements the idle thread infinite loop. 00048 * @details The function puts the processor in the lowest power mode capable 00049 * to serve interrupts.<br> 00050 * The priority is internally set to the minimum system value so 00051 * that this thread is executed only if there are no other ready 00052 * threads in the system. 00053 * 00054 * @param[in] p the thread parameter, unused in this scenario 00055 */ 00056 static void idle_thread(void *p) { 00057 00058 (void)p; 00059 while (TRUE) { 00060 port_wait_for_interrupt(); 00061 IDLE_LOOP_HOOK(); 00062 } 00063 } 00064 00065 /** 00066 * @brief ChibiOS/RT initialization. 00067 * @details After executing this function the current instructions stream 00068 * becomes the main thread. 00069 * @note Interrupts should be still disabled when @p chSysInit() is invoked 00070 * and are internally enabled. 00071 * @note The main thread is created with priority @p NORMALPRIO. 00072 */ 00073 void chSysInit(void) { 00074 static Thread mainthread; 00075 00076 port_init(); 00077 scheduler_init(); 00078 vt_init(); 00079 #if CH_USE_MEMCORE 00080 core_init(); 00081 #endif 00082 #if CH_USE_HEAP 00083 heap_init(); 00084 #endif 00085 #if CH_DBG_ENABLE_TRACE 00086 trace_init(); 00087 #endif 00088 00089 /* Now this instructions flow becomes the main thread.*/ 00090 setcurrp(init_thread(&mainthread, NORMALPRIO)); 00091 currp->p_state = THD_STATE_CURRENT; 00092 chSysEnable(); 00093 00094 /* This thread has the lowest priority in the system, its role is just to 00095 serve interrupts in its context while keeping the lowest energy saving 00096 mode compatible with the system status.*/ 00097 chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO, 00098 (tfunc_t)idle_thread, NULL); 00099 } 00100 00101 /** 00102 * @brief Handles time ticks for round robin preemption and timer increments. 00103 * @details Decrements the remaining time quantum of the running thread 00104 * and preempts it when the quantum is used up. Increments system 00105 * time and manages the timers. 00106 * 00107 * @note The frequency of the timer determines the system tick granularity 00108 * and, together with the @p CH_TIME_QUANTUM macro, the round robin 00109 * interval. 00110 */ 00111 void chSysTimerHandlerI(void) { 00112 00113 #if CH_TIME_QUANTUM > 0 00114 /* Running thread has not used up quantum yet? */ 00115 if (rlist.r_preempt > 0) 00116 /* Decrement remaining quantum.*/ 00117 rlist.r_preempt--; 00118 #endif 00119 #if CH_DBG_THREADS_PROFILING 00120 currp->p_time++; 00121 #endif 00122 chVTDoTickI(); 00123 } 00124 00125 #if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED 00126 void chSysLock(void) { 00127 00128 chDbgAssert(currp->p_locks >= 0, 00129 "chSysLock(), #1", 00130 "negative nesting counter"); 00131 if (currp->p_locks++ == 0) 00132 port_lock(); 00133 } 00134 00135 void chSysUnlock(void) { 00136 00137 chDbgAssert(currp->p_locks > 0, 00138 "chSysUnlock(), #1", 00139 "non-positive nesting counter"); 00140 if (--currp->p_locks == 0) 00141 port_unlock(); 00142 } 00143 #endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */ 00144 00145 /** @} */