Hi, I'm developing an application in C for the NXP LPC2103 which uses interrupts (VIC) and works fine using just ARM code. However I'm almost out of code space and am trying to use THUMB. Enabling -mthumb-interwork (rather than -mno-thumb-interwork), without even building a file in THUMB, causes the processor to hang when it encounters an interrupt. Not enabling interrupts at startup cures this problem, but the application relies on them heavily. Optimisation is -0s (size), the program won't fit in any other mode. My interrupt enabling/disabling routines are: inline unsigned enableIRQ(void) { unsigned _cpsr; _cpsr = asm_get_cpsr(); asm_set_cpsr(_cpsr & ~IRQ_MASK); return _cpsr; } inline unsigned disableIRQ(void) { unsigned _cpsr; _cpsr = asm_get_cpsr(); asm_set_cpsr(_cpsr | IRQ_MASK); return _cpsr; } I think it's the actual getting into/out of the ISRs which is causing it to fall over. I'm using the latest version of Winarm (20060606). I've tried using Yagarto as well, with exactly the same problem. Can anyone suggest what's going wrong? I've been trying to get to the bottom of this for a while, and it's now getting urgent! P.S. I'm not very familiar with ARM assembly yet. Thanks, John.
John Dominey wrote: > Hi, > I'm developing an application in C for the NXP LPC2103 which uses > interrupts (VIC) and works fine using just ARM code. However I'm almost > out of code space and am trying to use THUMB. Enabling -mthumb-interwork > (rather than -mno-thumb-interwork), without even building a file in > THUMB, causes the processor to hang when it encounters an interrupt. Not > enabling interrupts at startup cures this problem, but the application > relies on them heavily. Optimisation is -0s (size), the program won't > fit in any other mode. > > My interrupt enabling/disabling routines are: > > inline unsigned enableIRQ(void) > { > unsigned _cpsr; > > _cpsr = asm_get_cpsr(); > asm_set_cpsr(_cpsr & ~IRQ_MASK); > return _cpsr; > } > > inline unsigned disableIRQ(void) > { > unsigned _cpsr; > > _cpsr = asm_get_cpsr(); > asm_set_cpsr(_cpsr | IRQ_MASK); > return _cpsr; > } > > I think it's the actual getting into/out of the ISRs which is causing it > to fall over. > > I'm using the latest version of Winarm (20060606). I've tried using > Yagarto as well, with exactly the same problem. > > Can anyone suggest what's going wrong? I've been trying to get to the > bottom of this for a while, and it's now getting urgent! > > P.S. I'm not very familiar with ARM assembly yet. > > Thanks, John. There is a known problem with interwork, interrupts and optimization. It has been discussed in in different forums/mailing-lists. A rather easy approach to work around this is to declare the functions with the "nacked" attribute and use entry- and exit-macros. It's not elegant or portable but works. The example lpc2106_uart_irq (based on code from Bill Knight) demonstrates this method. Another appraoch is an assembler-wrapper, for LPC it's demonstrated in the gcc-port of the LPC213x/4x driver-examples available in WinARM (update versions on my web-pages). Also see the various gcc-Ports of AT91SAM7 examples, the wrapper can be included easily, no knowledge in ARM assembly needed. Martin Thomas
Thanks - it works!!!! I'm not sure what to do about the exception handlers like void SWI_Routine (void) _attribute_ ((interrupt("SWI"))); void UNDEF_Routine (void) _attribute_ ((interrupt("UNDEF"))); How do you make these "nacked" while still telling the compiler that they're SWI and UNDEF interrupts? Do you still need to use ISR_ENTRY() and ISR_EXIT()? I know these interrupts should never be encountered, and I intend to reset the processor when they are, but how should it be done? Thanks again, John
John Dominey wrote: > Thanks - it works!!!! > I'm not sure what to do about the exception handlers like > > void SWI_Routine (void) _attribute_ ((interrupt("SWI"))); > void UNDEF_Routine (void) _attribute_ ((interrupt("UNDEF"))); > > How do you make these "nacked" while still telling the compiler that > they're SWI and UNDEF interrupts? Do you still need to use ISR_ENTRY() > and ISR_EXIT()? > I know these interrupts should never be encountered, and I intend to > reset the processor when they are, but how should it be done? > > Thanks again, > John I have not used the macros for anything else but "normal" interrupts. But if you are going to reset the processor anyway macros my not be needed at all. The needed "prologs" for the other interrupt-sources are documented in the technical reference. For SWI you might get an idea from my SWI-examples which use "wrappers".
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.