EmbeddedRelated.com
Forums

Newbee: bootloader locked.

Started by planiup March 21, 2006
Hello all:

I'm a developer of 8 bit microcontrollers applications that wants to 
switch to ARM. So I'm learning my own all this stuff, and as a 
newbee, I have some problems. Probably the most stupid ones.

I have a Macraigor Wiggler clone made by myself, and a development 
board with an LPC2103, also made by myself. I've checked all 
circuitry and it seems to be OK.

I use the IAR KickStart downloaded from IAR, rev 4.30A, and when 
trying to debug any program with my system, I always start at the 
bootloader.
Can somebody point me in the right direction or give me some starting 
point to avoid that?

I did not initialize the vector table, since I'm only trying to 
toggle pin P0.0.

Thanks in advance,

Guillem.
	

An Engineer's Guide to the LPC2100 Series

planiup wrote:
> Hello all:
> 
> I'm a developer of 8 bit microcontrollers applications that wants to 
> switch to ARM. So I'm learning my own all this stuff, and as a 
> newbee, I have some problems. Probably the most stupid ones.
> 
> I have a Macraigor Wiggler clone made by myself, and a development 
> board with an LPC2103, also made by myself. I've checked all 
> circuitry and it seems to be OK.
> 
> I use the IAR KickStart downloaded from IAR, rev 4.30A, and when 
> trying to debug any program with my system, I always start at the 
> bootloader.
> Can somebody point me in the right direction or give me some starting 
> point to avoid that?
> 
> I did not initialize the vector table, since I'm only trying to 
> toggle pin P0.0.
> 

Hi Guillem,

The LPCs expect the vectors area to contain a valid checksum
at the old 24-bit address exception vector location. The
Philips serial port bootloader tool fills in that checksum
when you program a device. The first time I wrote a
simple assembler program to turn on some I/O pins it
didn't work. I filled in the vectors table properly and
then it did. So, I would suggest installing default vectors
that branch to themselves, except for the vector to
start your program of course.

I've attached that example below.

Regards
Dave

# -----------------------------
# Makefile for ex1.elf
# -----------------------------

CC      = arm-elf-gcc
CFLAGS  = -Wall -O2 -mcpu=arm7tdmi

# Override the default linker script .text section start address
LDFLAGS = -Ttext=0 -nostartfiles

# Uncomment this and the linker will output the linker script used
#LDFLAGS += -Wl,--verbose

all: ex1.hex

ex1.elf: ex1.s
	$(CC) $(CFLAGS) $(LDFLAGS) ex1.s -o ex1.elf
	
ex1.hex: ex1.elf
	arm-elf-objcopy -O ihex ex1.elf ex1.hex
	
# Use 'make ex1.size' to see the section sizes 	
ex1.size: ex1.elf
	@echo -n "-------------------------------"
	@echo    "-------------------------------"
	@echo "Object section sizes:"
	@echo -n "-------------------------------"
	@echo    "-------------------------------"
	@echo ""
	arm-elf-size ex1.elf
	@echo ""
	@echo -n "-------------------------------"
	@echo    "-------------------------------"
	@echo ""
	arm-elf-objdump -h ex1.elf
	
clean:
	-rm -rf *.o *.elf *.hex
	/* ex1.s */

/* ----------------------------
  * Exception vectors
  * ----------------------------
  */
	.text
	.arm
	.global _start
_start:
	/* Vectors (8 total) */
	b reset   /* reset */
	b loop    /* undefined instruction */
	b loop    /* software interrupt */
	b loop    /* prefetch abort */
	b loop    /* data abort */
	nop       /* reserved for the bootloader checksum */
	b loop    /* IRQ */
	b loop    /* FIQ */

/* ----------------------------
  * Test code
  * ----------------------------
  */
reset:	
	ldr r0, IODIR1
	ldr r1, IODIR1_VALUE
	str r1, [r0]
	ldr r0, IOCLR1
	str r1, [r0]
	ldr r0, IOSET1
	ldr r1, IOSET1_VALUE
	str r1, [r0]

loop:   b   loop

/* ----------------------------
  * Constants
  * ----------------------------
  */
/* LED control registers */
IOSET1:         .word   0xE0028014
IODIR1:         .word   0xE0028018
IOCLR1:         .word   0xE002801C
IODIR1_VALUE:   .word   0x00FF0000
IOSET1_VALUE:   .word   0x00550000

	.end
	
Hello:

First of all, thanks for your fast response.

I had tried what you say, but with the same results. What I do is 
include this file in my project (I'm not usign GNU-GCC but IAR):

MODE_BITS	DEFINE	0x1F		; Bit mask for mode bits in 
CPSR
USR_MODE	DEFINE	0x10		; User mode
FIQ_MODE	DEFINE	0x11		; Fast Interrupt Request mode
IRQ_MODE	DEFINE	0x12		; Interrupt Request mode
SVC_MODE	DEFINE	0x13		; Supervisor mode
ABT_MODE	DEFINE	0x17		; Abort mode
UND_MODE	DEFINE	0x1B		; Undefined Instruction mode
SYS_MODE	DEFINE	0x1F		; System mode
	;---------------------------
; ?RESET
; Reset Vector.
; Normally, segment INTVEC is linked at address 0.
; For debugging purposes, INTVEC may be placed at other
; addresses.
; A debugger that honors the entry point will start the
; program in a normal way even if INTVEC is not at address 0.
;---------------------------

		MODULE	?RESET
		COMMON	INTVEC:CODE:NOROOT(2)
		PUBLIC  __program_start
		EXTERN	?cstartup
;		EXTERN	undef_handler, swi_handler, prefetch_handler
;		EXTERN	data_handler, fiq_handler
;		EXTERN	irq_handler
		CODE32	; Always ARM mode after reset	
		org	0x00
__program_start
		ldr	pc,=?cstartup  ; Absolute jump can reach 4 
GByte
;		ldr	b,?cstartup    ; Relative branch allows 
remap, limited to 32 MByte
		org	0x04
undef_handler	ldr	pc,=undef_handler
		org	0x08
swi_handler	ldr	pc,=swi_handler
		org	0x0c
prefetch_handler ldr	pc,=prefetch_handler
		org	0x10
data_handler	ldr	pc,a_handler
		org	0x18
irq_handler	ldr	pc,=irq_handler
		org	0x1c
fiq_handler	ldr	pc,=fiq_handler

		; Constant table entries (for ldr pc) will be placed 
at 0x20
		org	0x20
		LTORG
;		ENDMOD	__program_start
                ENDMOD
	;---------------------------
; ?CSTARTUP
;---------------------------
		MODULE	?CSTARTUP

		RSEG	IRQ_STACK:DATA(2)
		RSEG	SVC_STACK:DATA:NOROOT(2)
		RSEG	CSTACK:DATA(2)
		RSEG	ICODE:CODE:NOROOT(2)
		PUBLIC	?cstartup
		EXTERN	?main

; Execution starts here.
; After a reset, the mode is ARM, Supervisor, interrupts disabled.
			CODE32
?cstartup

; Add initialization nedded before setup of stackpointers here
	; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS.
; The stack segments must be defined in the linker command file,
; and be declared above.
                mrs     r0,cpsr                             ; 
Original PSR value
                bic     r0,r0,#MODE_BITS                    ; Clear 
the mode bits
                orr     r0,r0,#IRQ_MODE                     ; Set IRQ 
mode bits
                msr     cpsr_c,r0                           ; Change 
the mode
                ldr     sp,=SFE(IRQ_STACK) & 0xFFFFFFF8     ; End of 
IRQ_STACK

                bic     r0,r0,#MODE_BITS                    ; Clear 
the mode bits
                orr     r0,r0,#SYS_MODE                     ; Set 
System mode bits
                msr     cpsr_c,r0                           ; Change 
the mode
                ldr     sp,=SFE(CSTACK) & 0xFFFFFFF8        ; End of 
CSTACK

#ifdef __ARMVFP__
; Enable the VFP coprocessor.
                mov     r0, #0x40000000                 ; Set EN bit 
in VFP
                fmxr    fpexc, r0                       ; FPEXC, 
clear others.

; Disable underflow exceptions by setting flush to zero mode.
; For full IEEE 754 underflow compliance this code should be removed
; and the appropriate exception handler installed.
                mov     r0, #0x01000000		        ; Set FZ bit 
in VFP
                fmxr    fpscr, r0                       ; FPSCR, 
clear others.
#endif

; Add more initialization here
	; Continue to ?main for more IAR specific system startup

                ldr     r0,=?main
                bx      r0

                LTORG

                ENDMOD
	                END
	This is a file called TinyC_Start_LPC210X or something similar and 
that cames with IAR, and they use for they LPC2106 demo project.

Anyway, I could not work with my program, since it still runs the 
bootloader. In the dissasembly window, I could see that:

__program_start:
  00000000  00000000  ANDEQ        R0, R0, R0               ; RESET 
undef_handler ldr pc,=undef_handler
undef_handler:
  00000004  00000004  ANDEQ        R0, R0, R4               ; UND   
swi_handler ldr pc,=swi_handler
swi_handler:
  00000008  00000008  ANDEQ        R0, R0, R8               ; SWI   
prefetch_handler ldr pc,=prefetch_handler
prefetch_handler:
  0000000C  0000000C  ANDEQ        R0, R0, R12              ; P ABT 
data_handler ldr pc,a_handler
data_handler:
  00000010  00000010  ANDEQ        R0, R0, R0, LSL R0       ; D ABT 
  00000014  00000014  ANDEQ        R0, R0, R4, LSL R0
irq_handler ldr pc,=irq_handler
irq_handler:
  00000018  00000018  ANDEQ        R0, R0, R8, LSL R0       ; IRQ   
fiq_handler ldr pc,=fiq_handler
fiq_handler:
  0000001C  0000001C  ANDEQ        R0, R0, R12, LSL R0      ; FIQ   
_?0:
  00000020  00000020  ANDEQ        R0, R0, R0, LSR #32
_?1:
  00000024  00000024  ANDEQ        R0, R0, R4, LSR #32
_?2:
  00000028  00000028  ANDEQ        R0, R0, R8, LSR #32
_?3:
  0000002C  0000002C  ANDEQ        R0, R0, R12, LSR #32
_?4:
  00000030  00000030  ANDEQ        R0, R0, R0, LSR R0
_?5:
  00000034  00000034  ANDEQ        R0, R0, R4, LSR R0
_?6:
  00000038  00000038  ANDEQ        R0, R0, R8, LSR R0
  0000003C  0000003C  ANDEQ        R0, R0, R12, LSR R0

so this looks like the checksum is not loaded.

Any suggestions?

Thanks again,

Guillem Planisi.
	
> First of all, thanks for your fast response.
No problem!

> I had tried what you say, but with the same
results. What I do is 
> include this file in my project (I'm not usign GNU-GCC but IAR):

Ok.

>  In the dissasembly window, I could see that:
> so this looks like the checksum is not loaded.
> 
> Any suggestions?

Post a new question with the request:

   Setting checksum with IAR/J-Link?

Or whatever tool you use to load the image.

You could always first try the Philips FlashTools utility
to confirm that your code works and that this is the
problem.

Dave
	
SOMETHING is responsible for setting up the checksum.  It is done
automatically when using the Philips ISP programmer.  I don't know how
Keil does it but it should be documented somewhere.

Rowley does it by hard coding the constant in the device specific
startup code.  In my case this is Philips_LPC210X_Startup.s.

There is no getting around having a proper checksum if you want to
start the program automatically.

Richard
	
Thanks again, Dave:

I will download Philips FlashTools and try it. It's a good idea.

Also, I think perhaps I have some hardware problem, since sometimes 
I receive a messaga regarding that the system can't be put in 
background mode. I suspect about the decoupling capacitor on the 
1.8V line, but I can't check it now.

I will give it a try and will post results.

Guillem.

--- In lpc2000@lpc2..., David Hawkins <dwh@...> wrote:
>
> 
> > First of all, thanks for your fast response.
> No problem!
> 
> > I had tried what you say, but with the same results. What I do 
is 
> > include this file in my project (I'm not
usign GNU-GCC but IAR):
> 
> Ok.
> 
> >  In the dissasembly window, I could see that:
> > so this looks like the checksum is not loaded.
> > 
> > Any suggestions?
> 
> Post a new question with the request:
> 
>    Setting checksum with IAR/J-Link?
> 
> Or whatever tool you use to load the image.
> 
> You could always first try the Philips FlashTools utility
> to confirm that your code works and that this is the
> problem.
> 
> Dave
>
	
Thanks Richard:

I suspected it, and as far as I could see that IAR examples for LPC2106 
uses the TinyC_startup.asm (or something similar), I use the same. I 
read the program and I tried to use it. What I thought about that is 
the debuger sets the checksum automatically, but I'm not shure. I will 
ask about that with a different post about IAR/Wiggler issue, as Dave 
suggessted.

Also I will try do download the code using Philips FlashTools in order 
to see if it is the problem.

Anyway, I suspect that maybe there is another problem with the 1.8V 
line that can cause a wrong behavior, but now I couldn't check. I 
suspect this because sometimes appears some error message regarding 
that the system can't be put in background mode, or even that the cable 
is disconnected or no target present.

I will post results when I could.

Guillem.
	--- In lpc2000@lpc2..., "rtstofer" <rstofer@...> wrote:
>
> 
> SOMETHING is responsible for setting up the checksum.  It is done
> automatically when using the Philips ISP programmer.  I don't know how
> Keil does it but it should be documented somewhere.
> 
> Rowley does it by hard coding the constant in the device specific
> startup code.  In my case this is Philips_LPC210X_Startup.s.
> 
> There is no getting around having a proper checksum if you want to
> start the program automatically.
> 
> Richard
>
	
On Mar 21, 2006, at 11:53 AM, planiup wrote:

>  I did not initialize the vector table, since
I'm only trying to
>  toggle pin P0.0.
>

The bootloader will always get entered on boot-up if the proper 
checksum word is not written. The checksum is the 2's complement of the 
sum of all the vectors.

However, another problem might arise: what is the state on your P0.14 
pins ? If it is floating, the bootloader might start always since a LOW 
on P0.14 on reset causes entry in the bootloader. Add a switch to 
ground on P0.14 with a pull-up to Vdd and keep it depressed while you 
reset to enter bootloader mode.

Of course, if the checksum is not right, it will also enter bootloader. 
The Philips flash utility calculates it for you, though.

Best Regards,

Tennessee Carmel-Veilleux