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