EmbeddedRelated.com
Forums

Executing interrupt routines in RAM instead of flash

Started by Jan Thogersen August 31, 2006
Hi,

I have written come code for the LPC2148 which heavily uses interrupts.
And the processor have some problems with handling all the interrupts.
So to gain some more speed I hope that it's possible to move my
interrupts to RAM.

I'm using the GCC compiler and I know that I can select if my project
should execute from RAM or flash. However, I need a pragma to put in
front of the ISR routines that tells the compiler that this routine
should be placed in memory.

Is this possible? Or how am I to place the routines in mem?

Thanks in advance!

Regards
Jan

An Engineer's Guide to the LPC2100 Series

--- In l..., Jan Thogersen wrote:
>
> Hi,
>
> I have written come code for the LPC2148 which heavily uses
interrupts.
> And the processor have some problems with handling all the
interrupts.
> So to gain some more speed I hope that it's possible to move my
> interrupts to RAM.
>
> I'm using the GCC compiler and I know that I can select if my
project
> should execute from RAM or flash. However, I need a pragma to put
in
> front of the ISR routines that tells the compiler that this
routine
> should be placed in memory.
>
> Is this possible? Or how am I to place the routines in mem?
>
> Thanks in advance!
>
> Regards
> Jan
>

Jan,

First thing to note is that unlike many ARM7 controllers, the speed
improvement using RAM as opposed to internal flash is marginal at
best on the LPC2xxx (assuming you have the MAM fully enabled and
configured correctly). If you're that marginal in terms of
throughput, maybe you should look at alternatives (faster clock
speed, fewer interrupts etc.)? Are you sure your problems are speed
of execution, rather than interrupts being locked out for example?
do you allow nested interrupts?

If you really need to run code from RAM, you shouldn't need to use
pragmas, or anything else special in the code itself: you should be
able to do it all in the link control file. You will also need some
code to copy the loaded code from flash to RAM (in the same way that
initialised variables are copied).

Brendan.
--- In l..., Jan Thogersen wrote:
>
> Hi,
>
> I have written come code for the LPC2148 which heavily uses interrupts.
> And the processor have some problems with handling all the interrupts.
> So to gain some more speed I hope that it's possible to move my
> interrupts to RAM.
>
> I'm using the GCC compiler and I know that I can select if my project
> should execute from RAM or flash. However, I need a pragma to put in
> front of the ISR routines that tells the compiler that this routine
> should be placed in memory.
>
> Is this possible? Or how am I to place the routines in mem?
>
> Thanks in advance!
>
> Regards
> Jan
>

Have you read section 6.1 (the last paragraph) of the datasheet? It
states that the flash design allows full speed execution in ARM mode.
It also states that you should use the ARM instruction set for
interrupt code.

Richard
Brendan Murphy wrote:
>
> --- In lpc2000@yahoogroups .com ,
> Jan Thogersen wrote:
> >
> > Hi,
> >
> > I have written come code for the LPC2148 which heavily uses
> interrupts.
> > And the processor have some problems with handling all the
> interrupts.
> > So to gain some more speed I hope that it's possible to move my
> > interrupts to RAM.
>
> Jan,
>
> First thing to note is that unlike many ARM7 controllers, the speed
> improvement using RAM as opposed to internal flash is marginal at
> best on the LPC2xxx (assuming you have the MAM fully enabled and
> configured correctly). If you're that marginal in terms of
> throughput, maybe you should look at alternatives (faster clock
> speed, fewer interrupts etc.)? Are you sure your problems are speed
> of execution, rather than interrupts being locked out for example?
> do you allow nested interrupts?
>
My problem is that my SPI interrupt is to slow. I need the SPI transfers
to be aligned shoulder to shoulder. But the internal structure of the
ARM is making a delay between the bytes. When I get an SPI buffer empty
interrupt then I as the first thing in the interrupt puts new bytes to
the buffer. However, it looks like the hardware don't start the transfer
until the interrupt exits because the speed of my SPI communication
depends on the length of interrupt which is strange...
That was why I was seeking a way of making the interrupt faster.

Is it possible with the GCC compiler to write the interrupt routine in
assembler?

Regards
Jan
> > do you allow nested interrupts?
> >
> My problem is that my SPI interrupt is to slow. I
> need the SPI transfers
> to be aligned shoulder to shoulder. But the internal
Do you mean byte alignment?

> structure of the
> ARM is making a delay between the bytes. When I get
> an SPI buffer empty
> interrupt then I as the first thing in the interrupt
> puts new bytes to
> the buffer. However, it looks like the hardware
> don't start the transfer
Sounds like there is a lock within the interrupt. It
would not been the alignment issue.

> until the interrupt exits because the speed of my
> SPI communication
> depends on the length of interrupt which is
> strange...
> That was why I was seeking a way of making the
> interrupt faster.
>
> Is it possible with the GCC compiler to write the
> interrupt routine in
> assembler?
Yes you can but it is not wise to play with it
unless you can read assembly. The reason I am not so
fond of writing in assembly subroutine in a C file is
that the stack alignment COULD change with different
optimization levels. One could easily remedy this
using assembly correctly but again it takes time.

The best way right now is to write a small program
with the interrupt handler and see what happens from
there.

John

__________________________________________________
--- In l..., Jan Thogersen wrote:
>
> Brendan Murphy wrote:
> >
> > --- In lpc2000@yahoogroups .com
40yahoogroups.com>,
> > Jan Thogersen wrote:
> > >
> > > Hi,
> > >
> > > I have written come code for the LPC2148 which heavily uses
> > interrupts.
> > > And the processor have some problems with handling all the
> > interrupts.
> > > So to gain some more speed I hope that it's possible to move my
> > > interrupts to RAM.
> >
> > Jan,
> >
> > First thing to note is that unlike many ARM7 controllers, the
speed
> > improvement using RAM as opposed to internal flash is marginal at
> > best on the LPC2xxx (assuming you have the MAM fully enabled and
> > configured correctly). If you're that marginal in terms of
> > throughput, maybe you should look at alternatives (faster clock
> > speed, fewer interrupts etc.)? Are you sure your problems are
speed
> > of execution, rather than interrupts being locked out for example?
> > do you allow nested interrupts?
> >
> My problem is that my SPI interrupt is to slow. I need the SPI
transfers
> to be aligned shoulder to shoulder. But the internal structure of
the
> ARM is making a delay between the bytes. When I get an SPI buffer
empty
> interrupt then I as the first thing in the interrupt puts new bytes
to
> the buffer. However, it looks like the hardware don't start the
transfer
> until the interrupt exits because the speed of my SPI communication
> depends on the length of interrupt which is strange...
> That was why I was seeking a way of making the interrupt faster.
>
> Is it possible with the GCC compiler to write the interrupt routine
in
> assembler?
>
> Regards
> Jan
>

I think you need to get a better handle on what's happening before
assuming it's a software optimisation issue.

You can write interrupt routines totally in assembler with GCC (in
fact the first few instructions more or less have to be in
assembler). However, as with running from flash vs. RAM, if you
compile your code with a high level of optimisation (use "-O3" from
memory), it does a ptetty good job. In other words, even if it was an
optimisation issue, there's not much to be gained from doing it in
assembler.

In short:

1. Running from RAM or doing stuff in assembler won't make a big
difference to your system. Make sure you have MAM fully enabled and
the optimiser on the compiler turned on.

2. Ensure everything is working correctly and you fully understand
what's going on before doing anything else.

3. Then, if you really do need to optimise, measure first to see
exactly where the problems are and selectively optimise those problem
areas by optimising the algorithms used first.

4. Then, asd a final stage, look at coding in assembler etc.

Try figuring out what's happening with the SPI interface: for
example, write a short program that uses polled I/O, then a simple
interrupt driven one. My guess is that you're not clearing or setting
some control flag correctly.

By the way, check out the file "gcc_ucossii" in the "Files" section
of the group (this name is probably wrong, but it's something like
that) and in particular the PDF document it contains. There's plenty
of stuff there on handling interrupts using GCC.

I hope this helps.

Brendan
Brendan Murphy wrote:
>
> --- In lpc2000@yahoogroups .com ,
> Jan Thogersen wrote:
> >
> > Brendan Murphy wrote:
> > >
> > > --- In lpc2000@yahoogroups .com > 40yahoogroups. com>,
> > > Jan Thogersen wrote:
> > > >
> > > > Hi,
> > > >
> > > > I have written come code for the LPC2148 which heavily uses
> > > interrupts.
> > > > And the processor have some problems with handling all the
> > > interrupts.
> > > > So to gain some more speed I hope that it's possible to move my
> > > > interrupts to RAM.
> In short:
>
> 1. Running from RAM or doing stuff in assembler won't make a big
> difference to your system. Make sure you have MAM fully enabled and
> the optimiser on the compiler turned on.
>
> 2. Ensure everything is working correctly and you fully understand
> what's going on before doing anything else.
>
> 3. Then, if you really do need to optimise, measure first to see
> exactly where the problems are and selectively optimise those problem
> areas by optimising the algorithms used first.
>
> 4. Then, asd a final stage, look at coding in assembler etc.
>
> Try figuring out what's happening with the SPI interface: for
> example, write a short program that uses polled I/O, then a simple
> interrupt driven one. My guess is that you're not clearing or setting
> some control flag correctly.
>
> By the way, check out the file "gcc_ucossii" in the "Files" section
> of the group (this name is probably wrong, but it's something like
> that) and in particular the PDF document it contains. There's plenty
> of stuff there on handling interrupts using GCC.
>
> I hope this helps.
>
> Brendan
>
Thanks everyone the all the answers. I found my the issues causing my
slow SPI transfer. My interrupt priority was wrong and I made some
optimizations to my algo's. So now it runs much faster. Thanks for
guiding in the right direction...

Regards
Jan