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:
formatting link
Paul
Didn't find your answer? Ask the community — no account required.
G
Gary Kato
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.
L
Lewin A.R.W. Edwards
You can't vector the interrupt direct to C. You need an asm reflector shim.
P
Paul Marcel
Oh. I didn't know that. Do you have an example of how the asm reflector should be?
Paul
P
Peter Dickerson
shim.
well I have an ARM timer interrupt written entirely in C that uses the GCC extension
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
formatting link
Paul
L
Lewin A.R.W. Edwards
What GCC version are you using?
K
Ken
Never heard of an asm reflector shim.
GCC allows the interrupt to be written in C by using the __attribute__ extension.
Search for __attribute__ on
formatting link
The FreeRTOS source code has examples for the serial port and a timer interrupt - but for a Philips not an Atmel.
S
Sprow
Would that be the same as a veneer?
[snip blah blah]
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.
L
Lewin A.R.W. Edwards
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:
where c_fiq_handler is the C routine containing the actual ISR code.
H
Hans-Bernhard Broeker
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.
L
Lewin A.R.W. Edwards
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.
P
Paul Marcel
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?
thank you, Paul
J
Josep Durán
"Paul Marcel" escribió en el mensaje >
Only minor diferences to what you posted before. Anyway, here it goes : (remember I've got a EB55)
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.
P
Paul Marcel
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.
formatting link
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.