Home arrow Support arrow Forums

Luminary Micro Forums

dalewheat

Gold Boarder

2007/09/23 21:08

Q: bit 0 of reset vector must be "1"?

Why does the least significant bit of the reset vector in the Cortex-M3 vector table need to be set to "1"?

I've been playing with minimalist assembler programs for my EK-LM3S6965 and having nothing but troubles til I added a "+ 1" to the reset vector. Now everything works fine. Here's an example:

Code:

 hello.s .cpu cortex-m3 .code 16 minimum vector table .word    0x20010000                        stack pointer .word    reset 1                        reset vector .word    endless_loop                    interrupt handler .word    endless_loop                    hard fault handler reset:                                    @ reset vector spin up GPIO Port F SYSCTL_RCGC2    0x400FE108            run mode clock gating control register 2 RCGC2_GPIOF        1<<5                    bit position for GPIO Port F clock gating control     ldr        r0, =SYSCTL_RCGC2            load system control (RCGC2register address in r0     ldr        r1, =RCGC2_GPIOF            load data to write in r1     str        r1, [r0]                    @ 0x400FE108 <= 0x20 GPIO_PORTF        0x40025000            GPIO Port F base address GPIODATA        0x0000                GPIO data register offset GPIODIR            0x0400                GPIO data direction register offset GPIODEN            0x051c                GPIO digital enable register offset PF0                1<<0                    bit position for PF0 GPIO_MASK        PF0<<2                bit mask configure Port Fbit 0 as output     ldr        r0, =GPIO_PORTF GPIODIR    load GPIODIR for Port F register address in r0     ldr        r1, =PF0                    load data to write in r1     str        r1, [r0]                    @ store data in r1 to address pointed to by r0 enable digital output for Port Fbit 0     ldr        r0, =GPIO_PORTF GPIODEN    load GPIODEN for Port F register address in r0     ldr        r1, =PF0                    load data to write in r1     str        r1, [r0] @ prepare for loop: @    load r0 with GPIO data register address (plus mask bits) for Port F @    load r1 with bit pattern to turn LED on @    load r2 with bit pattern to turn LED off     ldr        r0, =GPIO_PORTF GPIODATA GPIO_MASK    load GPIODATA for Port F register address in r0including mask bits     ldr        r1, =PF0                    load data to write in r1     ldr        r2, =0x00      loop:     str        r1, [r0]                    @ turn STATUS LED on a short delay     ldr        r3, =0x100000 d1:    sub        r3r3#1     bne        d1          str        r2, [r0]                    @ turn STATUS LED off another short delay     ldr        r3, =0x100000 d2:    sub        r3r3#1     bne        d2          b        loop                        @ do it again again      endless_loop:     b        .                            @ loop forever ever .end                                    @ [end-of-file]



Without the "+ 1" added to the reset vector, the program never runs. I only ran across this by disassembling working programs built using the Keil tools, noticing that their vector tables had "odd" values for the reset vector, even though I knew they had to be halfword aligned.

Do I need to add "+ 1" to the other vectors? Isn't there a better way to do this with some sort of directive? What am I missing here?

Thanks,

Dale Wheat

login or register to reply

dawilson

Fresh Boarder

2007/09/24 12:37

Re:Q: bit 0 of reset vector must be "1"?

Dale,

This is an ARM CPU thing. On all ARM cores which support ARM (32bit) and Thumb (16bit) instruction sets, the lsb of a branch address tells the core what instruction set is in use at that location - 0 implies ARM, 1 implies Thumb. This allows you to mix functions using different instruction sets in the same binary without too many problems.

The convention has been carried forward to the Cortex-M3 core too but, since it only supports Thumb(2) instruction set, all jump targets need to have the lsb set to 1 indicating that the target function is encoded using Thumb.

Regards,

Dave

login or register to reply

TI Eric

Moderator

2007/09/24 13:02

Re:Q: bit 0 of reset vector must be "1"?

Dave is absolutely right. If you want to avoid having to put the "func + 1" in your code, add ".thumb_func" before the labels. That will tell GCC to automatically add the +1 for you.

Post edited by: LMI Eric, at: 2007/09/24 13:03

login or register to reply

dalewheat

Gold Boarder

2007/09/24 16:24

Re:Q: bit 0 of reset vector must be "1"?

Thanks Dave, Eric.

That's what I was guessing at, sort of the equivalent of the "BX" instruction instead of the "B" instruction.

I had already tried using ".thumb_func" to qualify the routine, but it doesn't (seem to) work with the GCC compiler or the assembler directly. If I declare the routine with the ".thumb_func" specifier, the vector gets written as all zeros and doesn't work.

The source code and the makefile have already been posted if anyone else would like to take a swing at it.

Is this something that gets fixed up by the linker?

I know it's a trivial example, but I'm writing a training guide for Cortex-M3 programming and starting with the very basics. Any help is appreciated.

Thanks,

Dale Wheat

login or register to reply

dalewheat

Gold Boarder

2007/09/24 16:30

Re:Q: bit 0 of reset vector must be "1"?

Why, yes, it *is* something that is "fixed up" by the linker.

I had been omitting the link step in these trivial examples because it was redundant. There is only a single, contiguous, non-relocated section (.text) that begins at location 0. The code in the object file will run on the device.

".thumb_func" does exactly what it is supposed to do -- but it's the linker that actually does the magic part.

Thanks for everyone's help in solving this mystery!

Dale Wheat

login or register to reply