Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: relocating code in RAM with lpc2106.

2005-02-28 by kennethwada

Hello Milind;

Let us say...

You are attempting to do a very advanced thing with the LPC2xxx chip. 
This is emminently doable though.

In general, you need to do the following:

Define your startup vector:
'the following is a code snippet from one of my projects'

AREA    INTVECT, 'CODE_IVEC', READONLY, ALIGN=2  // READONLY, ALIGN=4 
bytes
        RSEG  INTVECT
PUBLIC  __startup
__startup       PROC    CODE32

// Pre-defined interrupt handlers that may be directly 
// overwritten by C interrupt functions
EXTERN CODE32 (Undef_Handler?A)
EXTERN CODE32 (SWI_Handler?A)
EXTERN CODE32 (PAbt_Handler?A)
EXTERN CODE32 (DAbt_Handler?A)
EXTERN CODE32 (IRQ_Handler?A)
EXTERN CODE32 (FIQ_Handler?A)

// Exception Vectors
// Mapped to Address 0.
// Absolute addressing mode must be used.

vectors:        LDR     PC,Reset_Addr         
                LDR     PC,Undef_Addr
                LDR     PC,SWI_Addr
                LDR     PC,PAbt_Addr
                LDR     PC,DAbt_Addr
                NOP                            /* Reserved Vector */
;               LDR     PC,IRQ_Addr
                LDR     PC,[PC, #-0x0FF0]      /* Vector from 
VicVectAddr */
                LDR     PC,FIQ_Addr

Reset_Addr:     DD      Reset_Handler
Undef_Addr:     DD      Undef_Handler?A
SWI_Addr:       DD      SWI_Handler?A
PAbt_Addr:      DD      PAbt_Handler?A
DAbt_Addr:      DD      DAbt_Handler?A
                DD      0                      /* Reserved Address */
IRQ_Addr:       DD      IRQ_Handler?A
FIQ_Addr:       DD      FIQ_Handler?A
ENDP

As you can see, this vector consumes exactly 64 bytes of code!

Next, you need to relocate, (at runtime), your 64 byte interrupt 
vector table that you created above.

Do this as follows:

Reset_Handler:  
     .... ; <--- some startup code here, (usually PINSEL programming)

/*****
    Relocate interrupt vectors to internal RAM
***/
    MEMMAP  EQU   0xE01FC040              ; interrupt memory map 
register

    LDR     R1,=__startup
    MOV     R0,#0x40000000
    MOV     R2,#0x10

copyLoop:
    LDMIA   R1!,{R3}
    STMIA   R0!,{R3}
    SUBS    R2,R2,#0x0001
    BNE     copyLoop

    LDR     R0,=MEMMAP
    MOV     R1,#0x02
    STR     R1, [R0]

In your 'C' code, you need to define your vectors such that they 
reside in RAM. The Keil compiler has a real nifty way to do this via 
the following LINKER directive:

CLASSES (ERAM       (0x40000040-0x40001FFF))

This places all code that has been defined to store in flash, and 
execute in RAM to be loaded at runtime into the RAM area.

That is, for every subroutine you define with the following Keil 
modifier:

void my_interrupt_service (void) __irq __ram;

This __irq and __ram modifier does two things:
__irq compiles the subroutine as a service vector using ARM 
instructions.

__ram places the entire subroutine into the ERAM segment that will 
automatically get loaded into flash by the nifty Keil tool.

in lieu of the Keil tool, you must be able find a way relocate,
(copy) 
your service vectors into ram at run time.

whew!

hope this helps;
Ken Wada

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.