X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Firq.h;h=8e8abe20802dd85f1a93efe69bba000172bd765e;hb=a3ffb42b8a665abcbc54d8cfd290c368ab5f083c;hp=f4cd21ee32d4f90d4b7d93db085a166a6b250f55;hpb=d2961e1bd3def26dc0bb0b38b493af69e4b1ceca;p=bertos.git diff --git a/bertos/cpu/irq.h b/bertos/cpu/irq.h index f4cd21ee..8e8abe20 100644 --- a/bertos/cpu/irq.h +++ b/bertos/cpu/irq.h @@ -148,7 +148,7 @@ } #define IRQ_RUNNING() irq_running() - #if CONFIG_KERN_PREEMPT + #if (CONFIG_KERN && CONFIG_KERN_PREEMPT) #define DECLARE_ISR_CONTEXT_SWITCH(func) \ void func(void); \ @@ -286,9 +286,9 @@ sreg; \ }) - #define IRQ_ENABLED() (!(CPU_READ_FLAGS() & 0x80)) + #define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0) - #if CONFIG_KERN_PREEMPT + #if (CONFIG_KERN && CONFIG_KERN_PREEMPT) EXTERN_C void asm_irq_switch_context(void); /** @@ -340,17 +340,17 @@ * IRQs will be automatically re-enabled when restoring * the context of the user task. */ - #define DECLARE_ISR_CONTEXT_SWITCH(func) \ - void ISR_FUNC func(void); \ - static void __isr_##func(void); \ - void ISR_FUNC func(void) \ - { \ - IRQ_ENTRY(); \ - IRQ_DISABLE; \ - __isr_##func(); \ - IRQ_EXIT(); \ - } \ - static void __isr_##func(void) + #define DECLARE_ISR_CONTEXT_SWITCH(func) \ + void ISR_FUNC func(void); \ + static NOINLINE void __isr_##func(void); \ + void ISR_FUNC func(void) \ + { \ + IRQ_ENTRY(); \ + IRQ_DISABLE; \ + __isr_##func(); \ + IRQ_EXIT(); \ + } \ + static NOINLINE void __isr_##func(void) /** * Interrupt service routine prototype: can be used for * forward declarations. @@ -376,21 +376,41 @@ #endif /* !CONFIG_KERN_PRI */ #endif /* CONFIG_KERN_PREEMPT */ + #ifndef ISR_FUNC + #define ISR_FUNC __attribute__((naked)) + #endif #ifndef DECLARE_ISR #define DECLARE_ISR(func) \ - void __attribute__((interrupt)) func(void) + void ISR_FUNC func(void); \ + /* \ + * FIXME: avoid the inlining of this function. \ + * \ + * This is terribly inefficient, but it's a \ + * reliable workaround to avoid gcc blowing \ + * away the stack (see the bug below): \ + * \ + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41999 \ + */ \ + static NOINLINE void __isr_##func(void); \ + void ISR_FUNC func(void) \ + { \ + asm volatile ( \ + "sub lr, lr, #4\n\t" \ + "stmfd sp!, {r0-r3, ip, lr}\n\t"); \ + __isr_##func(); \ + asm volatile ( \ + "ldmfd sp!, {r0-r3, ip, pc}^\n\t"); \ + } \ + static NOINLINE void __isr_##func(void) #endif #ifndef DECLARE_ISR_CONTEXT_SWITCH - #define DECLARE_ISR_CONTEXT_SWITCH(func) \ - void __attribute__((interrupt)) func(void) + #define DECLARE_ISR_CONTEXT_SWITCH(func) DECLARE_ISR(func) #endif #ifndef ISR_PROTO - #define ISR_PROTO(func) \ - void __attribute__((interrupt)) func(void) + #define ISR_PROTO(func) void ISR_FUNC func(void) #endif #ifndef ISR_PROTO_CONTEXT_SWITCH - #define ISR_PROTO_CONTEXT_SWITCH(func) \ - void __attribute__((interrupt)) func(void) + #define ISR_PROTO_CONTEXT_SWITCH(func) ISR_PROTO(func) #endif #endif /* !__IAR_SYSTEMS_ICC_ */ @@ -462,7 +482,7 @@ ); \ (bool)(sreg & 0x80); \ }) - #if CONFIG_KERN_PREEMPT + #if (CONFIG_KERN && CONFIG_KERN_PREEMPT) #define DECLARE_ISR_CONTEXT_SWITCH(vect) \ INLINE void __isr_##vect(void); \ ISR(vect) \ @@ -507,6 +527,13 @@ #define ISR_PROTO_CONTEXT_SWITCH(vect) ISR(vect) #endif +#elif CPU_MSP430 + + /* Get the compiler defined macros */ + #include + #define IRQ_DISABLE dint() + #define IRQ_ENABLE eint() + #else #error No CPU_... defined. #endif @@ -536,7 +563,7 @@ #ifndef IRQ_PREEMPT_HANDLER - #if CONFIG_KERN_PREEMPT + #if (CONFIG_KERN && CONFIG_KERN_PREEMPT) /** * Handle preemptive context switch inside timer IRQ. */