I'm trying to get a very simple timer interrupt working in C on Atmel's EB40A board. The processor is an Atmel AT91R40008. I'm using the gnu tools from codesourcery (arm-none-elf-gcc etc). I have some non-interrupt samples working. The interrupt is not working. LED1 (the main loop LED) blinks, but the timer LED doesn't blink. I found this sample on Atmel's web site but that loaded timer1_asm_irq_handler into AIC_SVR5. I'd LIKE to load it with "time1_c_irq_handler" instead. Could someone tell me if I can do that and how to get this simple example working? Here's a link to the files:
Only thing I can think of right now is to look at the assembly language that the compiler generates for the interrupt routine. Make sure it conforms to an interrupt service routine. Most CPUs have a seperate return instruction for regular subroutines and for interrupt service routines.
You didn't mention any compile or link errors/warnings so I assume it all goes together ok.
I added a "shim" in boot.asm and tried that by loading the AIC_SVR5 register with the assembly routine. I had to modify the assembly code to get it to assemble with arm-none-elf-as. But still no interrupts. It did not even break in the assembly routine.
I switcheck back to a strictly C interrupt changing the function declartion to the form of your Sys_kbd_irq_handler, but still no interrupts. The program is running because the main loop is blinking the mainline led.
It seems that I need to do something else to enable interrupts. Any ideas? The current state of the test program is at
At some point in the output code is there something like MRS r0, CPSR BIC r0, r0, #I_BIT MSR CPSR_cxsf, r0 present? ARM's reset with global interrupts disabled, Sprow.
At the time I last wrote an ISR on an ARM platform - which was probably at least 18 months ago - the GCC documentation said explicitly that interrupts are not part of C, and are therefore not directly supported. It was necessary to write a little snippet of ARM assembler like:
That was true back then, and is still true now. The difference is one of interpretation (i.e. one of nitpicking, if you want), and to some extent, one of what GCC version you're looking at.
For *some* CPUs, GCC goes out of its way to help you make the task of writing the necessary glue code between C and the interrupt mechanisms of a CPU a bit easier. That's what __attribute__((interrupt ("IRQ NAME"))) is all about --- it essentially is a way of telling GCC to generate the glue code (or "shim", "wrapper", "veneer", "redirector"
--- pick your name) for you, instead of having to do it manually. As of GCC-3.4.1, this extension exists for ARM, too.
Since __attribute__(()) is a GNU extension to C, it's technically not part of C, because "C" devoid of any qualifiers by convention always means "standard C". So the above statement from the GCC docs is still correct.
But __attribute__(()), if supported, looks and feels sufficiently similar to ordinary C that it would seem a bit misguided to insist on that technicality. I.e. people working on CPUs that have GCC supporting the __attribute__((interrupt)) extension aren't quite completely wrong when they state they're writing interrupt handlers in C (e.g, they're definitely not coding any assembler themselves) --- they're just not 100% accurately right either.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
I think the bottom line here is that at that time I was using 2.95.2 (yes, there were more recent versions around, but 2.95.2 was the "most tested" version with all the other code I was using). The interrupt attribute didn't cause an error on this compiler, but it didn't create a usable ISR either.
OK. It seems that I CAN have an interrupt routine in C with this version of the gnu arm compiler. But I am still trying to get interrupts to work with this code. The main loop runs (LED1 flashes), but the C interrupt function never gets called. I'm using a nohau jtag interface with Seehau to load the code. I have set breakpoints inside the C interrupt and also at the interrupt vector location, but neither one happens. This is for the eb40a board.
Here's the compiler info:
C:\arm\bin>arm-none-elf-gcc -v Reading specs from c:/arm/bin/../lib/gcc/arm-none-elf/3.4.2/specs Configured with: /scratch/paul/release/gcc/configure
--host=i686-mi ngw32 Thread model: single gcc version 3.4.2 (release) (CodeSourcery ARM Q3D 2004)
Could someone who knows please tell me why this doesn't work?
thanks, Paul
BOOT.ASM: ======================
.section .text .code 32 .global vectors
vectors: b reset @ Reset b exception @ Undefined instruction b exception @ SWI b exception @ Prefetch abort b exception @ Data abort b exception @ reserved vector ldr pc, [pc, # -0xF20] @ irqs b exception @ fast irqs
---------------------------------- ; The software is delivered "AS IS" without warranty or condition of any kind, either express, implied or statutory. ; This includes without limitation any warranty or condition with respect to merchantability or fitness for any particular purpose, or ; against the ;infringements of intellectual property rights of others. ;---------------------------------------------------------------------------
I also had gotten the Atmel sample to assemble in gnu. I tried that but still didn't get any interrupt even at the interrupt vector. What code did you have at the interrupt vector address? I haven't exactly tried yours yet since I'm not breaking at 0x18.
I think that my first problem is that interrupts are not being generated at all. Could I see your initialization of the timer1 interrupt?
It's generally not good form to paste in hundreds of lines of source code because those people not interested in the thread don't want to spend precious seconds of their valuable lives downloading it.
Anyway,
Sheesh, please at least use BIC instead of corrupting r1.
Also, I can't spot anywhere where the peripheral clock for the timer is turned on! Sprow.
I got it working in windows. No assembly "shim", no cygwin. This example is self-contained, except for the make.exe that I used which was the one from the MKS Toolkit. It uses codesourcery's free gnu compiler. It's not perfect, but it works. I still have to figure out how to use the ram.ld linker file better and I think that I should not use the .space directive in boot.s.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.