|
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 IAR/ARMCMx/chcore_v6m.c 00023 * @brief ARMv6-M architecture port code. 00024 * 00025 * @addtogroup IAR_ARMCMx_V6M_CORE 00026 * @{ 00027 */ 00028 00029 #include "ch.h" 00030 00031 /*===========================================================================*/ 00032 /* Port interrupt handlers. */ 00033 /*===========================================================================*/ 00034 00035 /** 00036 * @brief System Timer vector. 00037 * @details This interrupt is used as system tick. 00038 * @note The timer must be initialized in the startup code. 00039 */ 00040 CH_IRQ_HANDLER(SysTickVector) { 00041 00042 CH_IRQ_PROLOGUE(); 00043 00044 chSysLockFromIsr(); 00045 chSysTimerHandlerI(); 00046 chSysUnlockFromIsr(); 00047 00048 CH_IRQ_EPILOGUE(); 00049 } 00050 00051 #if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) 00052 /** 00053 * @brief NMI vector. 00054 * @details The NMI vector is used for exception mode re-entering after a 00055 * context switch. 00056 */ 00057 void NMIVector(void) { 00058 register struct extctx *ctxp; 00059 00060 /* Discarding the current exception context and positioning the stack to 00061 point to the real one.*/ 00062 ctxp = (struct extctx *)__get_PSP(); 00063 ctxp++; 00064 __set_PSP((unsigned long)ctxp); 00065 port_unlock_from_isr(); 00066 } 00067 #endif /* !CORTEX_ALTERNATE_SWITCH */ 00068 00069 #if CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) 00070 /** 00071 * @brief PendSV vector. 00072 * @details The PendSV vector is used for exception mode re-entering after a 00073 * context switch. 00074 */ 00075 void PendSVVector(void) { 00076 register struct extctx *ctxp; 00077 00078 /* Discarding the current exception context and positioning the stack to 00079 point to the real one.*/ 00080 ctxp = (struct extctx *)__get_PSP(); 00081 ctxp++; 00082 __set_PSP((unsigned long)ctxp); 00083 } 00084 #endif /* CORTEX_ALTERNATE_SWITCH */ 00085 00086 /*===========================================================================*/ 00087 /* Port exported functions. */ 00088 /*===========================================================================*/ 00089 00090 /** 00091 * @brief IRQ epilogue code. 00092 * 00093 * @param[in] lr value of the @p LR register on ISR entry 00094 */ 00095 void _port_irq_epilogue(regarm_t lr) { 00096 00097 if (lr != (regarm_t)0xFFFFFFF1) { 00098 register struct extctx *ctxp; 00099 00100 port_lock_from_isr(); 00101 /* Adding an artificial exception return context, there is no need to 00102 populate it fully.*/ 00103 ctxp = (struct extctx *)__get_PSP(); 00104 ctxp--; 00105 __set_PSP((unsigned long)ctxp); 00106 ctxp->xpsr = (regarm_t)0x01000000; 00107 00108 /* The exit sequence is different depending on if a preemption is 00109 required or not.*/ 00110 if (chSchIsPreemptionRequired()) { 00111 /* Preemption is required we need to enforce a context switch.*/ 00112 ctxp->pc = (regarm_t)_port_switch_from_isr; 00113 } 00114 else { 00115 /* Preemption not required, we just need to exit the exception 00116 atomically.*/ 00117 ctxp->pc = (regarm_t)_port_exit_from_isr; 00118 } 00119 00120 /* Note, returning without unlocking is intentional, this is done in 00121 order to keep the rest of the context switch atomic.*/ 00122 } 00123 } 00124 00125 /** @} */