EmbeddedRelated.com
Forums
Memfault Beyond the Launch

LPC2478 debugging FreeRTOS in external SDRAM with openocd-0.5.0

Started by "chr...@gmail.com" January 18, 2012
Hello Friends,

I've build a PCB around a LPC2478 with 64MB SDRAM, 16MB NOR Flash and a TFT
screen.
I'm using eclipse, openocd-0.5.0, code sourcery toolchain under Linux

1) By doing the SDRAM init phase in the openocd cfg file, I have managed to
debug
led flasher programs in SDRAM. These small programs do not use interrupts.
So,
the linker file is quite simple.

2) I have also successfully run FreeRTOS both in internal SRAM and internal
Flash. I used/modified
linker files that existed in the FreeRTOS distribution.

Concerning 1 and 2 means that my setup is pretty solid for debugging.

What I would like to do, is to be able to debug FreeRTOS in SDRAM, having
all interrupt vectors in SRAM (MEMMAP = 2).

But I have no solid background on linker scripts and startup code.

When I compile with the following ld script I get the error :

Description Resource Path Location Type
relocation truncated to fit: R_ARM_JUMP24 against `.text'
SBC_lpc2478_v0.1
line 139, external location:
/tmp/ccSepNbk.o:/data/LPC2478/SBC_lpc2478_v0.1/boot_orig.s C/C++ Problem

i tried the -mlong-calls but had no success.
on 139 line in boot_orig.s is the jump to startup
( b _start /* reset - _start */)

Here is my linker script and below that, my startup code

any thoughts or examples or documentation greatly appreciated

(to be honest I tried to read the ld manual from GNU but I got lost... )

Best Regards
chris

------------------- ld script -------------------------------
MEMORY
{
flash : ORIGIN = 0x00000000, LENGTH = 504K
ram : ORIGIN = 0x40000000, LENGTH = 64K
usbram : ORIGIN = 0x7FD00000, LENGTH = 8K
ethram : ORIGIN = 0x7FE00000, LENGTH = 16K
sdram (rwx) : ORIGIN = 0xA0000000, LENGTH = 64M
}

__stack_end__ = 0x40000000 + 32K - 4;

SECTIONS
{
. = 0;
startup : { *(.startup)} >ram

prog :
{
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} >sdram AT> ram

__end_of_text__ = .;

.data :
{
__data_beg__ = .;
__data_beg_src__ = __end_of_text__;
*(.data)
__data_end__ = .;
/* } >ram AT>flash */
} >sdram
.bss :
{
__bss_beg__ = .;
*(.bss)
} >sdram

/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;

.usbram (NOLOAD):
{
__usbram_beg__ = .;
*(.dmaram)
__usbram_end__ = .;
} >usbram

.ethram (NOLOAD):
{
__ethram_beg__ = .;
*(.ethram)
__ethram_end__ = .;
} >ethram

}
. = ALIGN(32 / 8);
_end = .;

PROVIDE (end = .);

---------------end ld script--------------------------

-------------- start of boot.s ------------------------
/* Sample initialization file */

.extern main
.extern exit

.text
.code 32
.align 0

.extern __bss_beg__
.extern __bss_end__
.extern __stack_end__
.extern __data_beg__
.extern __data_end__
.extern __data+beg_src__

.global start
.global endless_loop

/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000100
.set ABT_STACK_SIZE, 0x00000100
.set FIQ_STACK_SIZE, 0x00000100
.set IRQ_STACK_SIZE, 0X00000400
.set SVC_STACK_SIZE, 0x00000400

/* Standard definitions of Mode bits and Interrupt (I & F) flags in
PSRs */
.set MODE_USR, 0x10 /* User Mode */
.set MODE_FIQ, 0x11 /* FIQ Mode */
.set MODE_IRQ, 0x12 /* IRQ Mode */
.set MODE_SVC, 0x13 /* Supervisor Mode */
.set MODE_ABT, 0x17 /* Abort Mode */
.set MODE_UND, 0x1B /* Undefined Mode */
.set MODE_SYS, 0x1F /* System Mode */

.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
start:
_start:
_mainCRTStartup:

/* Setup a stack for each mode - note that this only sets up a usable
stack
for system/user, SWI and IRQ modes. Also each mode is setup with
interrupts initially disabled. */
ldr r0, .LC6
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */
mov sp, r0

/* We want to start in supervisor mode. Operation will switch to system
mode when the first task starts. */
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT

/* Clear BSS. */

mov a2, #0 /* Fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */

ldr r1, .LC1 /* Start of memory block */
ldr r3, .LC2 /* End of memory block */
subs r3, r3, r1 /* Length of block */
beq .end_clear_loop
mov r2, #0

.clear_loop:
strb r2, [r1], #1
subs r3, r3, #1
bgt .clear_loop

.end_clear_loop:

/* Initialise data. */

ldr r1, .LC3 /* Start of memory block */
ldr r2, .LC4 /* End of memory block */
ldr r3, .LC5
subs r3, r3, r1 /* Length of block */
beq .end_set_loop

.set_loop:
ldrb r4, [r2], #1
strb r4, [r1], #1
subs r3, r3, #1
bgt .set_loop

.end_set_loop:

mov r0, #0 /* no arguments */
mov r1, #0 /* no argv either */

bl main

endless_loop:
b endless_loop
.align 0

.LC1:
.word __bss_beg__
.LC2:
.word __bss_end__
.LC3:
.word __data_beg__
.LC4:
.word __data_beg_src__
.LC5:
.word __data_end__
.LC6:
.word __stack_end__
/* Setup vector table. Note that undf, pabt, dabt, fiq just execute
a null loop. */

.section .startup,"ax"
.code 32
.align 0

b _start /* reset - _start */
ldr pc, _undf /* undefined - _undf */
ldr pc, _swi /* SWI - _swi */
ldr pc, _pabt /* program abort - _pabt */
ldr pc, _dabt /* data abort - _dabt */
nop /* reserved */
ldr pc, [pc,#-0x120] /* IRQ - read the VIC */
ldr pc, _fiq /* FIQ - _fiq */

_undf: .word __undf /* undefined */
_swi: .word vPortYieldProcessor /* SWI */
_pabt: .word __pabt /* program abort */
_dabt: .word __dabt /* data abort */
_fiq: .word __fiq /* FIQ */

__undf: b . /* undefined */
__pabt: b . /* program abort */
__dabt: b . /* data abort */
__fiq: b . /* FIQ */

-------------- end of boot.s ---------------------


An Engineer's Guide to the LPC2100 Series

Requesting a build for large memory models will not help fix problems in
your assembler, it will only instruct the compiler to generate assembler
that supports longer offsets.

By the name of the file it sounds like this is part of the startup code, not
a file generated by a compiler, so it will not help to change the compiler
settings.

Since you are having issues in the init file which is written in assembler
you need to modify the .s file to branch to an address that it in range
where you can then perform a second long jump to your code, or simply change
the instruction to do a long jump.

I'm not familiar with the particular init file so don't know which option is
best, if the branch is part of a vector table then you will need to use the
first option, if it's not part of the vector table then just change the
branch itself.

Regards

Phil.

From: l... [mailto:l...] On Behalf Of
c...@gmail.com
Sent: 17 January 2012 22:19
To: l...
Subject: [lpc2000] LPC2478 debugging FreeRTOS in external SDRAM with
openocd-0.5.0

Hello Friends,

I've build a PCB around a LPC2478 with 64MB SDRAM, 16MB NOR Flash and a TFT
screen.
I'm using eclipse, openocd-0.5.0, code sourcery toolchain under Linux

1) By doing the SDRAM init phase in the openocd cfg file, I have managed to
debug
led flasher programs in SDRAM. These small programs do not use interrupts.
So,
the linker file is quite simple.

2) I have also successfully run FreeRTOS both in internal SRAM and internal
Flash. I used/modified
linker files that existed in the FreeRTOS distribution.

Concerning 1 and 2 means that my setup is pretty solid for debugging.

What I would like to do, is to be able to debug FreeRTOS in SDRAM, having
all interrupt vectors in SRAM (MEMMAP = 2).

But I have no solid background on linker scripts and startup code.

When I compile with the following ld script I get the error :

Description Resource Path Location Type
relocation truncated to fit: R_ARM_JUMP24 against `.text'
SBC_lpc2478_v0.1
line 139, external location:
/tmp/ccSepNbk.o:/data/LPC2478/SBC_lpc2478_v0.1/boot_orig.s C/C++ Problem

i tried the -mlong-calls but had no success.
on 139 line in boot_orig.s is the jump to startup
( b _start /* reset - _start */)

Here is my linker script and below that, my startup code

any thoughts or examples or documentation greatly appreciated

(to be honest I tried to read the ld manual from GNU but I got lost... )

Best Regards
chris

------------------- ld script -------------------------------
MEMORY
{
flash : ORIGIN = 0x00000000, LENGTH = 504K
ram : ORIGIN = 0x40000000, LENGTH = 64K
usbram : ORIGIN = 0x7FD00000, LENGTH = 8K
ethram : ORIGIN = 0x7FE00000, LENGTH = 16K
sdram (rwx) : ORIGIN = 0xA0000000, LENGTH = 64M
}

__stack_end__ = 0x40000000 + 32K - 4;

SECTIONS
{
. = 0;
startup : { *(.startup)} >ram

prog :
{
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} >sdram AT> ram

__end_of_text__ = .;

.data :
{
__data_beg__ = .;
__data_beg_src__ = __end_of_text__;
*(.data)
__data_end__ = .;
/* } >ram AT>flash */
} >sdram
.bss :
{
__bss_beg__ = .;
*(.bss)
} >sdram

/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;

.usbram (NOLOAD):
{
__usbram_beg__ = .;
*(.dmaram)
__usbram_end__ = .;
} >usbram

.ethram (NOLOAD):
{
__ethram_beg__ = .;
*(.ethram)
__ethram_end__ = .;
} >ethram

}
. = ALIGN(32 / 8);
_end = .;

PROVIDE (end = .);

---------------end ld script--------------------------

-------------- start of boot.s ------------------------
/* Sample initialization file */

.extern main
.extern exit

.text
.code 32

.align 0

.extern __bss_beg__
.extern __bss_end__
.extern __stack_end__
.extern __data_beg__
.extern __data_end__
.extern __data+beg_src__

.global start
.global endless_loop

/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000100
.set ABT_STACK_SIZE, 0x00000100
.set FIQ_STACK_SIZE, 0x00000100
.set IRQ_STACK_SIZE, 0X00000400
.set SVC_STACK_SIZE, 0x00000400

/* Standard definitions of Mode bits and Interrupt (I & F) flags in
PSRs */
.set MODE_USR, 0x10 /* User Mode */
.set MODE_FIQ, 0x11 /* FIQ Mode */
.set MODE_IRQ, 0x12 /* IRQ Mode */
.set MODE_SVC, 0x13 /* Supervisor Mode */
.set MODE_ABT, 0x17 /* Abort Mode */
.set MODE_UND, 0x1B /* Undefined Mode */
.set MODE_SYS, 0x1F /* System Mode */

.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */

start:
_start:
_mainCRTStartup:

/* Setup a stack for each mode - note that this only sets up a usable
stack
for system/user, SWI and IRQ modes. Also each mode is setup with
interrupts initially disabled. */
ldr r0, .LC6
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */
mov sp, r0

/* We want to start in supervisor mode. Operation will switch to system
mode when the first task starts. */
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT

/* Clear BSS. */

mov a2, #0 /* Fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */

ldr r1, .LC1 /* Start of memory block */
ldr r3, .LC2 /* End of memory block */
subs r3, r3, r1 /* Length of block */
beq .end_clear_loop
mov r2, #0

.clear_loop:
strb r2, [r1], #1
subs r3, r3, #1
bgt .clear_loop

.end_clear_loop:

/* Initialise data. */

ldr r1, .LC3 /* Start of memory block */
ldr r2, .LC4 /* End of memory block */
ldr r3, .LC5
subs r3, r3, r1 /* Length of block */
beq .end_set_loop

.set_loop:
ldrb r4, [r2], #1
strb r4, [r1], #1
subs r3, r3, #1
bgt .set_loop

.end_set_loop:

mov r0, #0 /* no arguments */
mov r1, #0 /* no argv either */

bl main

endless_loop:
b endless_loop

.align 0

.LC1:
.word __bss_beg__
.LC2:
.word __bss_end__
.LC3:
.word __data_beg__
.LC4:
.word __data_beg_src__
.LC5:
.word __data_end__
.LC6:
.word __stack_end__

/* Setup vector table. Note that undf, pabt, dabt, fiq just execute
a null loop. */

.section .startup,"ax"
.code 32
.align 0

b _start /* reset - _start */
ldr pc, _undf /* undefined - _undf */
ldr pc, _swi /* SWI - _swi */
ldr pc, _pabt /* program abort - _pabt */
ldr pc, _dabt /* data abort - _dabt */
nop /* reserved */
ldr pc, [pc,#-0x120] /* IRQ - read the VIC */
ldr pc, _fiq /* FIQ - _fiq */

_undf: .word __undf /* undefined */
_swi: .word vPortYieldProcessor /* SWI */
_pabt: .word __pabt /* program abort */
_dabt: .word __dabt /* data abort */
_fiq: .word __fiq /* FIQ */

__undf: b . /* undefined */
__pabt: b . /* program abort */
__dabt: b . /* data abort */
__fiq: b . /* FIQ */

-------------- end of boot.s ---------------------





> b _start /* reset - _start */

Presumably _start is too far away for your 'b' instruction. Therefore,
if possible, use the linker to keep _start closer, or try changing to an
ldr instruction (if that would work for the Reset, don't see why not).

Replace with:

ldr pc, _start_const

then somewhere after the vector table:

_start_const: .word _start /* Load the 32bit address */

Regards,
Richard.

+ http://www.FreeRTOS.org
Designed for Microcontrollers.
More than 7000 downloads per month.
Phil , Richard

Thank you for your help..

I got a very nice lesson...

I wanted to run everything from sram/sdram just because
the upload speed is fast and will cut down much time
of the debugging cycle, not to mention the
unlimited breakpoints.
I followed Richards approach and the build
was successful. I have also changed a bit the
linker script.

changed the line:

} >sdram AT> ram
to
}>sdram

in the prog: section

Anyone who might be helped by this kind of setup
is free to contact me

Best Regards
chris



Memfault Beyond the Launch