EmbeddedRelated.com
Forums
Memfault Beyond the Launch

LPC23xx MCB2300 starup issues with GCC FreeRTOS statup files

Started by sashi ono March 20, 2007
I am attempting to use the freertos lpc2106_GCC loader files and
boot.s file for the lpc2378 keil evaluation board to bring up a simple
blinking led first. then the entire freertos demo.

I only modified the loader file to what you see below. I left the
boot.s file untouched.

>From my other ports from lpc2106 -> lpc2129 and lpc2148. this is all I
had to do. For some reason this is not working for the lpc2168
/lpc2378 chip.

I have gotten freertos to run, by using the LPC23xxlwIP web example
startup files in the files area. But I think I am having some stack
problems with this.
I want to know what is different between the lpc21xx and the lpc23xx
series, and why it doesn't work.

Anyone have any insight?
new loader file lpc2368_rom.ld
----------------

MEMORY
{
flash : ORIGIN = 0x00000000, LENGTH = 500K
ram : ORIGIN = 0x40000000, LENGTH = 32K
usbram : ORIGIN = 0x7FD00000, LENGTH = 8K
ethram : ORIGIN = 0x7FE00000, LENGTH = 16K
}

__stack_end__ = 0x40000000 + 32K - 4;

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

prog :
{
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} >flash

__end_of_text__ = .;

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

.bss :
{
__bss_beg__ = .;
*(.bss)
} >ram

/* 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);

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

.ethram (NOLOAD):
{
__ethram_beg__ = .;
*(.ethram)
__ethram_end__ = .;
} >ethram
}
. = ALIGN(32 / 8);
_end = .;
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
PROVIDE (end = .);

original 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, 0x00000004
.set ABT_STACK_SIZE, 0x00000004
.set FIQ_STACK_SIZE, 0x00000004
.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,#-0xFF0] /* 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 */

An Engineer's Guide to the LPC2100 Series

Responding to myself
I found this app note and I am going through it now.
http://www.nxp.com/acrobat_download/applicationnotes/AN10576_1.pdf

I found one thing
The VICAddress register resides in a new location in memory, i.e.
0xFFFF FF00. Hence the IRQ interrupt vector (residing at 0x18) should
now be modified as:
LDR PC, [PC, # -0x0120]
Previously, the instruction would be:
LDR PC, [PC, # -0x0FF0]

I tried the change, and it still doesn't run though. I'm still missing
something

--- In l..., "sashi ono" wrote:
>
> I am attempting to use the freertos lpc2106_GCC loader files and
> boot.s file for the lpc2378 keil evaluation board to bring up a simple
> blinking led first. then the entire freertos demo.
>
> I only modified the loader file to what you see below. I left the
> boot.s file untouched.
>
> From my other ports from lpc2106 -> lpc2129 and lpc2148. this is all I
> had to do. For some reason this is not working for the lpc2168
> /lpc2378 chip.
>
> I have gotten freertos to run, by using the LPC23xxlwIP web example
> startup files in the files area. But I think I am having some stack
> problems with this.
> I want to know what is different between the lpc21xx and the lpc23xx
> series, and why it doesn't work.
>
> Anyone have any insight?
> new loader file lpc2368_rom.ld
> ----------------
>
> MEMORY
> {
> flash : ORIGIN = 0x00000000, LENGTH = 500K
> ram : ORIGIN = 0x40000000, LENGTH = 32K
> usbram : ORIGIN = 0x7FD00000, LENGTH = 8K
> ethram : ORIGIN = 0x7FE00000, LENGTH = 16K
> }
>
> __stack_end__ = 0x40000000 + 32K - 4;
>
> SECTIONS
> {
> . = 0;
> startup : { *(.startup)} >flash
>
> prog :
> {
> *(.text)
> *(.rodata)
> *(.rodata*)
> *(.glue_7)
> *(.glue_7t)
> } >flash
>
> __end_of_text__ = .;
>
> .data :
> {
> __data_beg__ = .;
> __data_beg_src__ = __end_of_text__;
> *(.data)
> __data_end__ = .;
> } >ram AT>flash
>
> .bss :
> {
> __bss_beg__ = .;
> *(.bss)
> } >ram
>
> /* 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);
>
> .usbram (NOLOAD):
> {
> __usbram_beg__ = .;
> *(.dmaram)
> __usbram_end__ = .;
> } >usbram
>
> .ethram (NOLOAD):
> {
> __ethram_beg__ = .;
> *(.ethram)
> __ethram_end__ = .;
> } >ethram
> }
> . = ALIGN(32 / 8);
> _end = .;
> _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
> PROVIDE (end = .);
>
> original 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, 0x00000004
> .set ABT_STACK_SIZE, 0x00000004
> .set FIQ_STACK_SIZE, 0x00000004
> .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,#-0xFF0] /* 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 */
>
--- In l..., "sashi ono" wrote:

> From my other ports from lpc2106 -> lpc2129 and lpc2148. this is all I
> had to do. For some reason this is not working for the lpc2168
> /lpc2378 chip.

LPC23xx series differs to previous members of LPC2000 family. One
thing is VIC address location. You should read user manual and some
application notes first.
for some reason the pinselect10 doesn't default to 0 and it caused
problems. setting it to zero and adjusting the VIC address in the
boot.s to 0x120 instead of 0xff0 file got it working.

I posted up the led blinker in the files area
http://tech.groups.yahoo.com/group/lpc2000/files/Linker%20and%20CRT/

i tried it with several compilers including the latest divkitpro and
it seems to work.

the files are based on the lpc2106 freertos gcc startup files. So it
should be easy to get the full freertos demo from these files. Just
need to add in the swi back in for the RTOS.

--- In l..., "slawcus" wrote:
>
> --- In l..., "sashi ono" wrote:
>
> > From my other ports from lpc2106 -> lpc2129 and lpc2148. this is all I
> > had to do. For some reason this is not working for the lpc2168
> > /lpc2378 chip.
>
> LPC23xx series differs to previous members of LPC2000 family. One
> thing is VIC address location. You should read user manual and some
> application notes first.
>

Memfault Beyond the Launch