ChibiOS/RT
2.5.1
chsys.h
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.h
00023  * @brief   System related macros and structures.
00024  *
00025  * @addtogroup system
00026  * @{
00027  */
00028 
00029 #ifndef _CHSYS_H_
00030 #define _CHSYS_H_
00031 
00032 /**
00033  * @name    Macro Functions
00034  * @{
00035  */
00036 #if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__)
00037 /**
00038  * @brief   Returns a pointer to the idle thread.
00039  * @pre     In order to use this function the option @p CH_NO_IDLE_THREAD
00040  *          must be disabled.
00041  * @note    The reference counter of the idle thread is not incremented but
00042  *          it is not strictly required being the idle thread a static
00043  *          object.
00044  *
00045  * @return              Pointer to the idle thread.
00046  *
00047  * @api
00048  */
00049 #define chSysGetIdleThread() (rlist.r_queue.p_prev)
00050 #endif
00051 
00052 /**
00053  * @brief   Halts the system.
00054  * @details This function is invoked by the operating system when an
00055  *          unrecoverable error is detected, for example because a programming
00056  *          error in the application code that triggers an assertion while
00057  *          in debug mode.
00058  * @note    Can be invoked from any system state.
00059  *
00060  * @special
00061  */
00062 #if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
00063 #define chSysHalt() port_halt()
00064 #else
00065 #define chSysHalt() {                                                       \
00066   SYSTEM_HALT_HOOK();                                                       \
00067   port_halt();                                                              \
00068 }
00069 #endif
00070 
00071 /**
00072  * @brief   Performs a context switch.
00073  * @note    Not a user function, it is meant to be invoked by the scheduler
00074  *          itself or from within the port layer.
00075  *
00076  * @param[in] ntp       the thread to be switched in
00077  * @param[in] otp       the thread to be switched out
00078  *
00079  * @special
00080  */
00081 #define chSysSwitch(ntp, otp) {                                             \
00082   dbg_trace(otp);                                                           \
00083   THREAD_CONTEXT_SWITCH_HOOK(ntp, otp);                                     \
00084   port_switch(ntp, otp);                                                    \
00085 }
00086 
00087 /**
00088  * @brief   Raises the system interrupt priority mask to the maximum level.
00089  * @details All the maskable interrupt sources are disabled regardless their
00090  *          hardware priority.
00091  * @note    Do not invoke this API from within a kernel lock.
00092  *
00093  * @special
00094  */
00095 #define chSysDisable() {                                                    \
00096   port_disable();                                                           \
00097   dbg_check_disable();                                                      \
00098 }
00099 
00100 /**
00101  * @brief   Raises the system interrupt priority mask to system level.
00102  * @details The interrupt sources that should not be able to preempt the kernel
00103  *          are disabled, interrupt sources with higher priority are still
00104  *          enabled.
00105  * @note    Do not invoke this API from within a kernel lock.
00106  * @note    This API is no replacement for @p chSysLock(), the @p chSysLock()
00107  *          could do more than just disable the interrupts.
00108  *
00109  * @special
00110  */
00111 #define chSysSuspend() {                                                    \
00112   port_suspend();                                                           \
00113   dbg_check_suspend();                                                      \
00114 }
00115 
00116 /**
00117  * @brief   Lowers the system interrupt priority mask to user level.
00118  * @details All the interrupt sources are enabled.
00119  * @note    Do not invoke this API from within a kernel lock.
00120  * @note    This API is no replacement for @p chSysUnlock(), the
00121  *          @p chSysUnlock() could do more than just enable the interrupts.
00122  *
00123  * @special
00124  */
00125 #define chSysEnable() {                                                     \
00126   dbg_check_enable();                                                       \
00127   port_enable();                                                            \
00128 }
00129 
00130 /**
00131  * @brief   Enters the kernel lock mode.
00132  *
00133  * @special
00134  */
00135 #define chSysLock()  {                                                      \
00136   port_lock();                                                              \
00137   dbg_check_lock();                                                         \
00138 }
00139 
00140 /**
00141  * @brief   Leaves the kernel lock mode.
00142  *
00143  * @special
00144  */
00145 #define chSysUnlock() {                                                     \
00146   dbg_check_unlock();                                                       \
00147   port_unlock();                                                            \
00148 }
00149 
00150 /**
00151  * @brief   Enters the kernel lock mode from within an interrupt handler.
00152  * @note    This API may do nothing on some architectures, it is required
00153  *          because on ports that support preemptable interrupt handlers
00154  *          it is required to raise the interrupt mask to the same level of
00155  *          the system mutual exclusion zone.<br>
00156  *          It is good practice to invoke this API before invoking any I-class
00157  *          syscall from an interrupt handler.
00158  * @note    This API must be invoked exclusively from interrupt handlers.
00159  *
00160  * @special
00161  */
00162 #define chSysLockFromIsr() {                                                \
00163   port_lock_from_isr();                                                     \
00164   dbg_check_lock_from_isr();                                                \
00165 }
00166 
00167 /**
00168  * @brief   Leaves the kernel lock mode from within an interrupt handler.
00169  *
00170  * @note    This API may do nothing on some architectures, it is required
00171  *          because on ports that support preemptable interrupt handlers
00172  *          it is required to raise the interrupt mask to the same level of
00173  *          the system mutual exclusion zone.<br>
00174  *          It is good practice to invoke this API after invoking any I-class
00175  *          syscall from an interrupt handler.
00176  * @note    This API must be invoked exclusively from interrupt handlers.
00177  *
00178  * @special
00179  */
00180 #define chSysUnlockFromIsr() {                                              \
00181   dbg_check_unlock_from_isr();                                              \
00182   port_unlock_from_isr();                                                   \
00183 }
00184 /** @} */
00185 
00186 /**
00187  * @name    ISRs abstraction macros
00188  */
00189 /**
00190  * @brief   IRQ handler enter code.
00191  * @note    Usually IRQ handlers functions are also declared naked.
00192  * @note    On some architectures this macro can be empty.
00193  *
00194  * @special
00195  */
00196 #define CH_IRQ_PROLOGUE()                                                   \
00197   PORT_IRQ_PROLOGUE();                                                      \
00198   dbg_check_enter_isr();
00199 
00200 /**
00201  * @brief   IRQ handler exit code.
00202  * @note    Usually IRQ handlers function are also declared naked.
00203  * @note    This macro usually performs the final reschedule by using
00204  *          @p chSchIsPreemptionRequired() and @p chSchDoReschedule().
00205  *
00206  * @special
00207  */
00208 #define CH_IRQ_EPILOGUE()                                                   \
00209   dbg_check_leave_isr();                                                    \
00210   PORT_IRQ_EPILOGUE();
00211 
00212 /**
00213  * @brief   Standard normal IRQ handler declaration.
00214  * @note    @p id can be a function name or a vector number depending on the
00215  *          port implementation.
00216  *
00217  * @special
00218  */
00219 #define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
00220 /** @} */
00221 
00222 /**
00223  * @name    Fast ISRs abstraction macros
00224  */
00225 /**
00226  * @brief   Standard fast IRQ handler declaration.
00227  * @note    @p id can be a function name or a vector number depending on the
00228  *          port implementation.
00229  * @note    Not all architectures support fast interrupts.
00230  *
00231  * @special
00232  */
00233 #define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id)
00234 /** @} */
00235 
00236 #ifdef __cplusplus
00237 extern "C" {
00238 #endif
00239   void chSysInit(void);
00240   void chSysTimerHandlerI(void);
00241 #ifdef __cplusplus
00242 }
00243 #endif
00244 
00245 #endif /* _CHSYS_H_ */
00246 
00247 /** @} */