Forums

Interrupt vectors in SRAM, code in Flash

Started by Shahzeb Ihsan August 7, 2007
Has anyone tried to use interrupt vectors from the SRAM with the rest
of the user code residing normally in the flash? From what I've read
this seems possible, but there were a few things I'd like to clear up
to make sure I am on the right track...

1.) The interrupt vectors will have to be "copied" into the SRAM's
first 64 bytes. I believe this is the way it was with Atmel's AT91
series ARM controllers.

2.) Set MEMMAP = 0x02 to remap the interrupt vectors to the SRAM.

-Shahzeb

An Engineer's Guide to the LPC2100 Series

--- In l..., "Shahzeb Ihsan" wrote:
>
> Has anyone tried to use interrupt vectors from the SRAM with the rest
> of the user code residing normally in the flash? From what I've read
> this seems possible, but there were a few things I'd like to clear up
> to make sure I am on the right track...
>
> 1.) The interrupt vectors will have to be "copied" into the SRAM's
> first 64 bytes. I believe this is the way it was with Atmel's AT91
> series ARM controllers.
>
> 2.) Set MEMMAP = 0x02 to remap the interrupt vectors to the SRAM.
>
> -Shahzeb
>

Yes, this works. I use such a system to keep two banks of software in
the flash of my LPC2129. The boot code can load either bank from an
SD card and thereafter run either bank, depending on last bank run,
CRC check on the banks, presence of an SD card containing new code in
the socket and/or commands from a keypad at startup. To do this, the
correct vectors for the bank to be run have to be copied into SRAM,
the vector page remapped and a startup reset called.

It works fine - go for it!

Rgds,
Martin
OK, that's good to know, I actually am doing something related to two
banks of code...

Just one more thing, you wrote something about a startup reset, can
you please clarify?

Thanks for the prompt response.

Regards,
Shahzeb

--- In l..., "mjames_doveridge" wrote:
>
> --- In l..., "Shahzeb Ihsan" wrote:
> >
> > Has anyone tried to use interrupt vectors from the SRAM with the rest
> > of the user code residing normally in the flash? From what I've read
> > this seems possible, but there were a few things I'd like to clear up
> > to make sure I am on the right track...
> >
> > 1.) The interrupt vectors will have to be "copied" into the SRAM's
> > first 64 bytes. I believe this is the way it was with Atmel's AT91
> > series ARM controllers.
> >
> > 2.) Set MEMMAP = 0x02 to remap the interrupt vectors to the SRAM.
> >
> > -Shahzeb
> > Yes, this works. I use such a system to keep two banks of software in
> the flash of my LPC2129. The boot code can load either bank from an
> SD card and thereafter run either bank, depending on last bank run,
> CRC check on the banks, presence of an SD card containing new code in
> the socket and/or commands from a keypad at startup. To do this, the
> correct vectors for the bank to be run have to be copied into SRAM,
> the vector page remapped and a startup reset called.
>
> It works fine - go for it!
>
> Rgds,
> Martin
>
--- In l..., "mjames_doveridge" wrote:

> Yes, this works. I use such a system to keep two banks of software in
> the flash of my LPC2129. The boot code can load either bank from an
> SD card and thereafter run either bank, depending on last bank run,
> CRC check on the banks, presence of an SD card containing new code in
> the socket and/or commands from a keypad at startup. To do this, the
> correct vectors for the bank to be run have to be copied into SRAM,
> the vector page remapped and a startup reset called.
>
> It works fine - go for it!
>
> Rgds,
> Martin
>

This certainly works OK. In many cases, though it mightn't even be
necessary to remap the vectors: you can use the fact that the VIC
provides vectored interrupts. In other words, just reconfigure the VIC,
depending on which code you want to handle the interrupts.

If you need to remap all exceptions, though (e.g. reset, abort, FIQ
etc.), it's probably easier to remap everything to RAM.

Brendan.
It works fine, but you have do it in this order:

- disable interrupts
- enable MEMMAP=2
- copy 64bytes
- enable interrupts

Remember to compile into correct memory location.
--- In l..., "Shahzeb Ihsan" wrote:
>
> OK, that's good to know, I actually am doing something related to two
> banks of code...
>
> Just one more thing, you wrote something about a startup reset, can
> you please clarify?
>

IIRC, after the boot code has remapped the vectors it just loads a
void function parameter with the contents of address 0 and calls it,
so transferring control to the selected bank.

Rgds,
Martin
So, I tried this, works great when I just download code into flash.
But causes problems with debugging (I use HJTAG + AXD + ADSv1.2). On
reset I jump to a sub-routine which copies interrupt vectors from a
location in the flash to the SRAM, I'm copying the code below, maybe
some one can point out if there is something wrong with this approach.
Thanks for all your help.

P.S.: I tried to do this within the main() function in C code and that
worked fine even in debug mode, I don't know why the other approach is
failing...

//-----------------------//
;// Load "R0" with the address of the interrupt vector table
;// in the flash
LDR R0, =InterruptVectors

;// Store the number of bytes to be copied in "R1" ("0x40")
MOV R1, #0x40

;// Load SRAM base address in "R2"
LDR R2, =SRAM_BASE_ADDR

;// "R4" stores the count of bytes copied, initialize it to "0x00"
MOV R4, #0x00

;// Copy interrupt vectors to the SRAM
VectCopyLoop
LDR R3, [R0, R4] ;// Read one instruction from the
vector table into "R3"
STR R3, [R2, R4] ;// Copy the instruction from "R3"
into the SRAM
ADD R4, R4, #4 ;// Increment byte count
CMP R4, R1 ;// Check if all 64 bytes of the
vector table have been copied
BNE VectCopyLoop

;// Issue remap command (set "LPC_MEMMAP_REG" to "0x02")
LDR R0, =LPC_MEMMAP_REG
MOV R1, #0x02
STR R1, [R0]

;// Reset processor, this is just a jump to the new reset vector
;// in the SRAM
LDR R0, =SRAM_BASE_ADDR
BX R0
//-----------------------//

Regards,
Shahzeb
--- In l..., Wojciech Kromer
wrote:
>
> It works fine, but you have do it in this order:
>
> - disable interrupts
> - enable MEMMAP=2
> - copy 64bytes
> - enable interrupts
>
> Remember to compile into correct memory location.
>
Did you disabled interrupts before execute this
routine? Did you re-enabled them after executing this
routine?
You need something like:

disable_ints
MRS r7,CPSR
ORR r7,r7,#0xC0
MSR CPSR_c,r7
...
your routine
...

enable_ints
MRS r7,CPSR
BIC r7,r7,#0xC0
MSR CPSR_c,r7

--- Shahzeb Ihsan escreveu:

> So, I tried this, works great when I just download
> code into flash.
> But causes problems with debugging (I use HJTAG +
> AXD + ADSv1.2). On
> reset I jump to a sub-routine which copies
> interrupt vectors from a
> location in the flash to the SRAM, I'm copying the
> code below, maybe
> some one can point out if there is something wrong
> with this approach.
> Thanks for all your help.
>
> P.S.: I tried to do this within the main() function
> in C code and that
> worked fine even in debug mode, I don't know why the
> other approach is
> failing...
//-----------------------//
> ;// Load "R0" with the address of the interrupt
> vector table
> ;// in the flash
> LDR R0, =InterruptVectors
>
> ;// Store the number of bytes to be copied in
> "R1" ("0x40")
> MOV R1, #0x40
>
> ;// Load SRAM base address in "R2"
> LDR R2, =SRAM_BASE_ADDR
>
> ;// "R4" stores the count of bytes copied,
> initialize it to "0x00"
> MOV R4, #0x00
>
> ;// Copy interrupt vectors to the SRAM
> VectCopyLoop
> LDR R3, [R0, R4] ;// Read one
> instruction from the
> vector table into "R3"
> STR R3, [R2, R4] ;// Copy the
> instruction from "R3"
> into the SRAM
> ADD R4, R4, #4 ;// Increment
> byte count
> CMP R4, R1 ;// Check if all
> 64 bytes of the
> vector table have been copied
> BNE VectCopyLoop
>
> ;// Issue remap command (set "LPC_MEMMAP_REG"
> to "0x02")
> LDR R0, =LPC_MEMMAP_REG
> MOV R1, #0x02
> STR R1, [R0]
>
> ;// Reset processor, this is just a jump to the
> new reset vector
> ;// in the SRAM
> LDR R0, =SRAM_BASE_ADDR
> BX R0
>
//-----------------------//
>
> Regards,
> Shahzeb
> --- In l..., Wojciech Kromer
>
> wrote:
> >
> > It works fine, but you have do it in this order:
> >
> > - disable interrupts
> > - enable MEMMAP=2
> > - copy 64bytes
> > - enable interrupts
> >
> > Remember to compile into correct memory location.
> >
>
> Yahoo! Groups Links
>

Alertas do Yahoo! Mail em seu celular. Saiba mais em http://br.mobile.yahoo.com/mailalertas/
Hi,

Yes, the interrupts were disabled, this is what I do, that causes
problems with debugging when I enable interrupts (this exact same code
works perfectly fine when executed without debugging):

1.) On reset, I jump to a sub-routine for copying interrupt vectors
2.) In this sub-routine I disable interrupts, copy vectors into SRAM,
give the remap command (MEMMAP = 0x02) and branch to 0x40000000 (SRAM
base, new location of the reset vector)
3.) The reset handler initializes stacks, disable interrupts for all
processor modes and jumps to "__main" (heap, stack, RW region
initialization performed by ADS library function), which then calls
"main()".
4.) Initialize hardware and enable interrupts.
5.) Memory read/write error on the first interrupt. Sometimes I get
another error

The interesting thing is, if on reset I jump directly to the reset
handler and then eventually to "main()" and do the interrupt copying
procedure over there, everything works fine.

Do you think there can be any issues with remapping right after a
reset? Or might there be an issue of the processor registers/state not
being properly reset by the JTAG reset. I know HJTAG's reset doesn't
reset the peripheral registers etc. to their default reset values.

Any help is appreciated.

Regards,
Shahzeb

--- In l..., Alexandre Kremer wrote:
>
> Did you disabled interrupts before execute this
> routine? Did you re-enabled them after executing this
> routine?
> You need something like:
>
> disable_ints
> MRS r7,CPSR
> ORR r7,r7,#0xC0
> MSR CPSR_c,r7
> ...
> your routine
> ...
>
> enable_ints
> MRS r7,CPSR
> BIC r7,r7,#0xC0
> MSR CPSR_c,r7
>
> --- Shahzeb Ihsan escreveu:
>
> > So, I tried this, works great when I just download
> > code into flash.
> > But causes problems with debugging (I use HJTAG +
> > AXD + ADSv1.2). On
> > reset I jump to a sub-routine which copies
> > interrupt vectors from a
> > location in the flash to the SRAM, I'm copying the
> > code below, maybe
> > some one can point out if there is something wrong
> > with this approach.
> > Thanks for all your help.
> >
> > P.S.: I tried to do this within the main() function
> > in C code and that
> > worked fine even in debug mode, I don't know why the
> > other approach is
> > failing...
> >
> >
> //-----------------------//
> > ;// Load "R0" with the address of the interrupt
> > vector table
> > ;// in the flash
> > LDR R0, =InterruptVectors
> >
> > ;// Store the number of bytes to be copied in
> > "R1" ("0x40")
> > MOV R1, #0x40
> >
> > ;// Load SRAM base address in "R2"
> > LDR R2, =SRAM_BASE_ADDR
> >
> > ;// "R4" stores the count of bytes copied,
> > initialize it to "0x00"
> > MOV R4, #0x00
> >
> > ;// Copy interrupt vectors to the SRAM
> > VectCopyLoop
> > LDR R3, [R0, R4] ;// Read one
> > instruction from the
> > vector table into "R3"
> > STR R3, [R2, R4] ;// Copy the
> > instruction from "R3"
> > into the SRAM
> > ADD R4, R4, #4 ;// Increment
> > byte count
> > CMP R4, R1 ;// Check if all
> > 64 bytes of the
> > vector table have been copied
> > BNE VectCopyLoop
> >
> > ;// Issue remap command (set "LPC_MEMMAP_REG"
> > to "0x02")
> > LDR R0, =LPC_MEMMAP_REG
> > MOV R1, #0x02
> > STR R1, [R0]
> >
> > ;// Reset processor, this is just a jump to the
> > new reset vector
> > ;// in the SRAM
> > LDR R0, =SRAM_BASE_ADDR
> > BX R0
> >
> //-----------------------//
> >
> > Regards,
> > Shahzeb
> >
> >
> > --- In l..., Wojciech Kromer
> >
> > wrote:
> > >
> > > It works fine, but you have do it in this order:
> > >
> > > - disable interrupts
> > > - enable MEMMAP=2
> > > - copy 64bytes
> > > - enable interrupts
> > >
> > > Remember to compile into correct memory location.
> > >
> >
> >
> >
> >
> >
> > Yahoo! Groups Links
> >
> >
> >
> >
> > Alertas do Yahoo! Mail em seu celular. Saiba mais em
http://br.mobile.yahoo.com/mailalertas/
>
--- In l..., "Shahzeb Ihsan" wrote:
>
> So, I tried this, works great when I just download code into flash.
> But causes problems with debugging (I use HJTAG + AXD + ADSv1.2). On
> reset I jump to a sub-routine which copies interrupt vectors from a



Maybe a stupid question : did you initialize the stack before you jump
to this
subroutine and initialize the stack again at the new starting point ?

Armand ten Doesschate