ARM Boot Code

I’m able to get my application to execute on the ARM now. However, it crashes shortly there after. Using a very simple program with a LED output I have been able to find the point where it crashes. I’m wondering if I have missed something in the boot code that is causing it to crash.

It turns on the LED in the while loop but then crashes at the first for loop and never turns off the LED.

Here’s my boot code:

LDR SP,=0x40001000
LDR lr, =__main
MOV pc, lr

Note: My LED illuminates when the output goes low.

Here’s my application code:

#include "LPC246x.h"

void __main (void)
{
	int delay;

	PINSEL3 &= 0xFFFFFFCF;		// Set Port1.18 to GPIO
	IODIR1   = 0x00040000;		// Set Port1.18 to Output

	while(1)
	{
		IOCLR1 = 0x00040000;
		for( delay = 0; delay < 0x400000; delay++ );
		IOSET1 = 0x00040000;
		for( delay = 0; delay < 0x400000; delay++ );
	}
}

You’re not setting up any of the stacks, pointers, area’s, etc. At the very least I think you need to initialize the vectors.

What documentation would a person look at to initialize this stuff? I looked through the data sheet for the LPC2468 as best as possible and am using eclipse with yagarto.

Did I miss something in the data sheet?

Best thing to do is to find some LPC example software out there on the web (there’s a lot). There might even be some stuff on NXP’s website, but I haven’t looked around for it since I’m an Atmel kinda guy.

Thanks. I have been trying numerous different boot code that I have found on the web. I tried the one from NXP’s website as well. I seem to have troubles getting one that Yagarto accepts the syntax for. Most of them are really large. I just want initalize as little as possible to get my code running. Hopefully then I can understand a little better what’s going on.

However, I took a class on ARM micros in grad school and we developed using a NXP setup in eclipse. Only thing was the teacher skipped the details on boot code and just gave us the file. Unfortunately, that was 4 years ago and on a 21xx. Now I’m using a LPC24xx. Yet the only boot code I’ve made any progress with has been the one I received in that class.

I played around with it a lot… double checked settings that were in it against the data sheet. They seemed good. And I started to remove code from it to see if the behavior of the program changed. What I was left with was what I have originally attached. It actually behaved the exact same stripped down as it does with the whole original file as shown below. However, this didn’t really surprise me as I’m not using the interrupts.

Anyways, thanks for your help. Maybe I can adapt the syntax of one of these other files to work.

@// code originally from phillips appnote 10254
@ ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ
@                        Assembler Directives
@ ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ
               .section asm_code,"ax"   @ New Code section
               @ CODE32                @ ARM code
               .extern __main         @ main not defined
                                     @ in this section
               .global _start          @ global symbol
                                     @ referenced in
                                     @ ivt.s
@ ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ
_start:
               @ Set SP for Supervisor mode. Depending upon
               @ the stack the application needs this value
               @ needs to be set.
               @ stack is already set by bootloader
               @ but if this point is entered by any
               @ other means than reset, the stack pointer
               @ needs to be set explicity

               LDR SP,=0x40001000

               @ Setting up SP for IRQ and FIQ mode.
               @ Change mode before setting each one
               @ move back again to Supervisor mode
               @ Each interrupt has its own link
               @ register, stack pointer and program
               @ counter The stack pointers must be
               @ initialized for interrupts to be
               @ used later.

               @ setup for fiq and irq interrupt stacks to run
               @ below current stack by 1000.
               mov r0, sp         @ copy current stack pointer
               sub r0, r0, #1000  @ make irq stack pointer
               sub r1, r0, #1000  @ make fiq stack pointer
               msr cpsr_c, #0x12  @ switch to irq mode
               mov sp, r0         @ set irq stack pointer
               msr cpsr_c, #0x11  @ fiq mode
               mov sp, r1         @ set fiq stack pointer
               msr cpsr_c, #0x13  @ supervisor mode F,I enabled

               @ Jump to C code

               LDR lr, =__main
               MOV pc, lr

So I have Keil uVision3 SDK / Compiler set working with the micro. I reverse engineered the boot code it auto-generates.

I noticed actually, ALL you have to do to get the code I showed functioning as is setup the IVT and perform a small operation at the end of the boot code. I think the operation at the end is reserving space for the default stack defined in the bootloader and creating pointer to an instruction to switch to thumb mode. I could be wrong though.

I have been unable to translate that code to the gcc compiler.

Anybody know how I might go about doing that? I think once I get that into my bootcode in eclipse I’ll be good to go. Thanks!

Here’s the code from the Keil bootcode:

                AREA    |.text|, CODE, READONLY

                EXPORT  __user_initial_stackheap
__user_initial_stackheap

                BX      LR

                END