|
|
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 (RCGC2) register 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 F, bit 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 F, bit 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 r0, including 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 r3, r3, #1
bne d1
str r2, [r0] @ turn STATUS LED off
@ another short delay
ldr r3, =0x100000
d2: sub r3, r3, #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
|
|