Robert,
I am running a shared clock network over ethernet, so to reduce task jitter
on the slave nodes the timer0 interrupt needs to be as close as possible.
Ghetto,
I am currently using the indirect mode parallel bus (WR, RD, CS, INT, 2 addr
lines and 8 data lines) which is fine but requires a lot more IO Pins than
the I2C. Previously I have used the I2C interface which is very easy to
setup and use, however for my purposes was way too slow. Wiznet do supply
sample code which is very helpful and I belive RealOS has some code for it
too, tho I haven't seen it.
Tom,
Thanks once again. I think my best bet will be to make the Ext Int
Fuunction and Timer0 int function as short as possible. The timings of the
network should mean that no clashes occur (send out tick message, recieve
rply message). I would prefer not to have to mess around with nested
interrupt where possible.
Cheers,
Andy
----- Original Message -----
From: "Tom Walsh" <tom@...>
To: <lpc2000@yahoogroups.com>
Sent: Thursday, May 11, 2006 12:10 AM
Subject: Re: [lpc2000] Interrupt function declaration
Andy wrote:
>Thanks Tom,
>
>I'm still quite new to embedded systems generally so please bear with me.
>I'm running a task scheduler based on a 1ms tick using Timer0, so need one
>interrupt for this. In addition I require an interrupt from EINT3 due to
>an
>external ethernet chip which requires attention when a message is recieved.
>The timer0 int is time critical and must happen on time, the external
>interrupt can wait a bit if need be. Currently I have the follow setup, do
>you think this would be ok?
>
>
>
Well, in that case, you want to run nested interrupts. I don't use that
mode, perhaps some others can comment on implementing nesting?
From what I understand, you have to use some assembly language stubs
to: save out some registers onto stack, ACK the current interrupt being
serviced to allow others to pre-empt your current routine if needed, and
then call your actual code for the current interrupt service. Return
from the call, restore the registers and simply return.
>VICVectAddr0 = (tDWord)Sch_Tick_Function;
>VICVectCntl0 = 0x20 | 4;
>VICIntEnable |= (1 << 4);
>
>VICVectAddr1 = (tDWord)W3100A_Int_Service;
>VICVectCntl1 = 0x20 | 17;
>VICIntEnable |= (1 << 17);
>
>
>
What that will do is to allow preference for the Sch_Tick_Function over
the W3100A_Int_Service should they be asserted simultaneously. It does
not allow the timer interrrupt to interrupt the execution of the W3100A
service, if the timer fires during the ISR for the W3100A, it will be
heldoff until you write to the VicVectAddr (VICVectAddr = 0;). From the
LPC2106 manual:
"Following the completion of the desired interrupt service routine,
clearing of the interrupt flag on the peripheral level will propagate to
corresponding bits in VIC registers (VICRawIntr, VICFIQStatus and
VICIRQStatus). Also, before the next interrupt can be serviced, it is
necessary that write is performed into the VICVectAddr register before
the return from interrupt is executed. Thiswrite will clear the
respective interrupt flag in the internal interrupt priority hardware."
Nesting handled differently. As I mentioned, I do not have a need to
nest. Essentailly you have to simultaneously turn on the Interrupt an
switch your context to Supv mode (this would be done by setting value in
the CPSR register). By switching to Supv Mode, you use the Supv stack
for your ISR. When a higher level interrupt pre-empts an on-going ISR,
it would get the IRQ context stack, leaving your stack frame intact.
Then that higher level service switches to the Supv context. So, your
first job in the Supv context is to save registers(!) as you may have
pre-empted a lower ISR task.
I am not sure of the return process...
>and using the __attribute__((interrupt)); extention for the task
>declarations.
>
>
That attribute tells gcc that any register it uses in the service must
be preserved. gcc is two pass, maybe three pass, compiler, it will
build the code, then when it is time to emit the opcodes, it will
produce a prolog / epilog to save / restore registers used.
>The program sits in a while(1) loop until either of the interrupts occur.
>Also, so whats the __irq; extention for?
>
>
Don't know, gcc-4.01 considers "__irq" in place of "__attribute__
((interrupt))" as a syntax error. I would suspect that you are using a
modified gcc compiler, or some other compiler? Actually, I see no
effect when using ((interrupt)), ((interrupt("IRQ"))), or
((interrupt("FIQ"))) upon the code generated. IIRC, I think that I read
somewhere that those attributes are ignored?
TomW
--
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------
Yahoo! Groups LinksMessage
Re: [lpc2000] Interrupt function declaration
2006-05-11 by Andy
Attachments
- No local attachments were found for this message.