/** * @brief Interrupt simulation. */ void ChkIntSources(void) { LARGE_INTEGER n; #if HAL_USE_SERIAL if (sd_lld_interrupt_pending()) { dbg_check_lock(); if (chSchIsPreemptionRequired()) chSchDoReschedule(); dbg_check_unlock(); return; } #endif /* Interrupt Timer simulation (10ms interval).*/ QueryPerformanceCounter(&n); if (n.QuadPart > nextcnt.QuadPart) { nextcnt.QuadPart += slice.QuadPart; CH_IRQ_PROLOGUE(); chSysLockFromIsr(); chSysTimerHandlerI(); chSysUnlockFromIsr(); CH_IRQ_EPILOGUE(); dbg_check_lock(); if (chSchIsPreemptionRequired()) chSchDoReschedule(); dbg_check_unlock(); } else { /* Avoid CPU spinning */ Sleep(1); } }
/** * @brief IRQ epilogue code. * * @param[in] lr value of the @p LR register on ISR entry */ void _port_irq_epilogue(regarm_t lr) { if (lr != (regarm_t)0xFFFFFFF1) { register struct extctx *ctxp; register uint32_t psp __asm("psp"); port_lock_from_isr(); /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp = (struct extctx *)psp; ctxp--; psp = (uint32_t)ctxp; ctxp->xpsr = (regarm_t)0x01000000; /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ } }
/** * @brief Exception exit redirection to _port_switch_from_isr(). */ void _port_irq_epilogue(void) { port_lock_from_isr(); if ((SCB_ICSR & ICSR_RETTOBASE) != 0) { struct extctx *ctxp; register uint32_t psp __asm("psp"); /* Current PSP value.*/ ctxp = (struct extctx *)psp; /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; psp = (uint32_t)ctxp; ctxp->xpsr = (regarm_t)0x01000000; /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { #if CORTEX_USE_FPU /* Triggering a lazy FPU state save.*/ register uint32_t fpscr __asm("fpscr"); ctxp->r0 = (regarm_t)fpscr; #endif /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } #if CORTEX_USE_FPU { uint32_t fpccr; /* Saving the special register SCB_FPCCR into the reserved offset of the Cortex-M4 exception frame.*/ (ctxp + 1)->fpccr = (regarm_t)(fpccr = SCB_FPCCR); /* Now the FPCCR is modified in order to not restore the FPU status from the artificial return context.*/ SCB_FPCCR = fpccr | FPCCR_LSPACT; } #endif /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ return; } port_unlock_from_isr(); }
/** * @brief Exception exit redirection to _port_switch_from_isr(). */ void _port_irq_epilogue(void) { port_lock_from_isr(); if ((SCB_ICSR & ICSR_RETTOBASE) != 0) { struct extctx *ctxp; register uint32_t psp __asm("psp"); /* Current PSP value.*/ ctxp = (struct extctx *)psp; #if CORTEX_USE_FPU /* Enforcing a lazy FPU state save. Note, it goes in the original context because the FPCAR register has not been modified.*/ { volatile register uint32_t fpscr __asm("fpscr"); (void)fpscr; } #endif /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; ctxp->xpsr = (regarm_t)0x01000000; #if CORTEX_USE_FPU ctxp->fpscr = (regarm_t)SCB_FPDSCR; #endif psp = (uint32_t)ctxp; /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ return; } port_unlock_from_isr(); }
/** * @brief Exception exit redirection to _port_switch_from_isr(). */ void _port_irq_epilogue(void) { port_lock_from_isr(); if ((SCB->ICSR & SCB_ICSR_RETTOBASE_Msk) != 0) { struct port_extctx *ctxp; #if CORTEX_USE_FPU /* Enforcing a lazy FPU state save by accessing the FPCSR register.*/ (void) __get_FPSCR(); #endif /* The port_extctx structure is pointed by the PSP register.*/ ctxp = (struct port_extctx *)__get_PSP(); /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; /* Setting up a fake XPSR register value.*/ ctxp->xpsr = (regarm_t)0x01000000; #if CORTEX_USE_FPU ctxp->fpscr = (regarm_t)FPU->FPDSCR; #endif /* Writing back the modified PSP value.*/ __set_PSP((uint32_t)ctxp); /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ return; } port_unlock_from_isr(); }
/** * @brief IRQ epilogue code. * * @param[in] lr value of the @p LR register on ISR entry */ void _port_irq_epilogue(regarm_t lr) { if (lr != (regarm_t)0xFFFFFFF1U) { struct port_extctx *ctxp; port_lock_from_isr(); /* The extctx structure is pointed by the PSP register.*/ ctxp = (struct port_extctx *)__get_PSP(); /* Adding an artificial exception return context, there is no need to populate it fully.*/ ctxp--; /* Writing back the modified PSP value.*/ __set_PSP((uint32_t)ctxp); /* Setting up a fake XPSR register value.*/ ctxp->xpsr = (regarm_t)0x01000000; /* The exit sequence is different depending on if a preemption is required or not.*/ if (chSchIsPreemptionRequired()) { /* Preemption is required we need to enforce a context switch.*/ ctxp->pc = (regarm_t)_port_switch_from_isr; } else { /* Preemption not required, we just need to exit the exception atomically.*/ ctxp->pc = (regarm_t)_port_exit_from_isr; } /* Note, returning without unlocking is intentional, this is done in order to keep the rest of the context switch atomic.*/ } }