2025-02-10 06:28 AM
Hi,
Can someone explain me why I have to use "+1" in vector table of STM32F103C8T6:
vectors:
.word STACKINIT @ stack pointer
.word _start + 1 @ reset vector
.word _nmi_handler + 1 @
.word _hard_fault + 1 @
.word _memory_fault + 1 @
.word _bus_fault + 1 @
.word _usage_fault + 1 @
instead of:
.word STACKINIT @ stack pointer
.word _start @ reset vector
.word _nmi_handler @
.word _hard_fault @
.word _memory_fault @
.word _bus_fault @
.word _usage_fault @
I thought that STM32F103C8T6 is 32bit processor and thus I can use:
.code 32
.cpu cortex-m3
.syntax unified
But it is NOT true. I can use only THUMB (code 16) instructions.
2025-02-10 09:23 AM
Perhaps choose if you're doing this with ARMARM (KEIL / REALVIEW) syntax, or GNU/GAS
PRESERVE8
THUMB
AREA |.text|, CODE, READONLY
Reset_Handler PROC ; A procedure/function
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
And you'll probably still need to be on-top of ALIGN ment and literal pools LTORG
2025-02-10 09:28 AM
ok, it means that both directives:
.weak Reset_Handler .type Reset_Handler, %function
are mutually bound because if I use
.weak Reset_Handler
only, the linker sees the Reser_Handler but processor does not work, but if I use both directives
.weak Reset_Handler .type Reset_Handler, %function
processor is FINALLY working ok. Am I wrok ? Or how to set an asm instruction to ODD address ?
2025-02-10 09:45 AM
ok this code is working for me:
@@@ Directives
.code 16 @ (same as saying '.code 16')
.cpu cortex-m3
.syntax unified
.fpu softvfp
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function /* this should be ODD in thumb/16-bit mode */
@ .size Reset_Handler, .-Reset_Handler /* this code does not compile my compiler it ends with error */
@@@ Equates
.equ GPIOB_CRH, 0x40010C04
.equ GPIOB_ODR, 0x40010C0C
.equ RCC_APB2ENR, 0x40021018
.equ STACKINIT, 0x20005000
.equ LEDDELAY, 0x80000
.section .text
.align 2
.org 0
@@@ Vectors
vectors:
.word STACKINIT @ stack pointer value when stack is empty
.word Reset_Handler @ reset vector (manually adjust to odd for thumb)
.word _nmi_handler + 1 @
.word _hard_fault + 1 @
.word _memory_fault + 1 @
.word _bus_fault + 1 @
.word _usage_fault + 1 @
Reset_Handler:
ldr sp, =STACKINIT
@@ Enable the Port B peripheral clock by setting bit 4
ldr r6, = RCC_APB2ENR
mov r0, 0x08
str r0, [r6]
and If I omit this command:
.type Reset_Handler, %function
the program does not work. It means that the instruction ".type Reset_Handler, %function " makes my reset ODD ?????
2025-02-10 10:06 AM
so this is working for me:
@ arm-none-eabi-as -mcpu=cortex-m3 LED.s -o LED.o
@ arm-none-eabi-ld -v -T stm32.ld -o LED.elf LED.o
@ arm-none-eabi-objcopy -O binary LED.elf LED.bin
@
@@@ Directives
.code 16 @ (same as saying '.code 16')
.cpu cortex-m3
.syntax unified
.fpu softvfp
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function /* this should be ODD in thumb/16-bit mode */
@ .size Reset_Handler, .-Reset_Handler /* this code does not compile my compiler it ends with error */
@@@ Equates
.equ GPIOB_CRH, 0x40010C04
.equ GPIOB_ODR, 0x40010C0C
.equ RCC_APB2ENR, 0x40021018
.equ STACKINIT, 0x20005000
.equ LEDDELAY, 0x80000
.section .text
@ .align 2
.org 0
@@@ Vectors
vectors:
.word STACKINIT @ stack pointer value when stack is empty
.word Reset_Handler @ reset vector (manually adjust to odd for thumb)
.word _nmi_handler @
.word _hard_fault @
.word _memory_fault @
.word _bus_fault @
.word _usage_fault @
Reset_Handler:
ldr sp, =STACKINIT
@@ Enable the Port B peripheral clock by setting bit 4
ldr r6, = RCC_APB2ENR
mov r0, 0x08
str r0, [r6]
2025-02-10 10:12 AM
The .type is the thing that infers the address based on the current instruction mode, ie from .thumb
The .weak allows you to replace the function by a stronger definition, say from the compiler, in C, see how it's used to associate Default_Handler with other interrupts you might describe in your source, say stm32f1xx_it.c, but if not want it to go to some viable code
The .section per function allows for dead-code removal
In Keil's ARMARM syntax we'd use PROC/ENDP to brace functions/procedures, for GNU/GAS it's a bit more involved
... Stuff Before
.section .text.Reset_Handler /* should have *.text* in linker script */
.weak Reset_Handler /* optional weak linkage */
.type Reset_Handler, %function /* this should be ODD in thumb/16-bit mode */
Reset_Handler:
ldr sp, =_estack /* set stack pointer */
... Body of function
.size Reset_Handler, .-Reset_Handler /* the length of the stuff above, so .MAP can show it */
... Stuff after
I'm not looking to construct an entire example, look at existing, working examples, and be a better chameleon
2025-02-10 10:13 AM
You wrote:
.type Reset_Handler, %function /* this should be ODD in thumb/16-bit mode */
and /* this should be ODD in thumb/16-bit mode */ wht is it mean ????? How I can MAKE the first instruction of my Reset_Handler to be placed to ODD address ?????
2025-02-10 11:18 AM
And why exactly don't you use the working, good startupxxx.s file as a starting point and reference. Also, you ignore all the remarks from the posts above on using some form of THUMB directive for the assembler. In addition to that, your linker script file looks strange. .data section should go to RAM - again, why don't you compare your bad files against the working ones?
2025-02-11 12:23 AM
I am trying to learn "how to" with STM32. This is my first touch. That is all.
So, I tried to add ".org 201" to "create" the "odd" address but program is not working it is very suspicious.
@@@ Directives
.code 16 @ (same as saying '.code 16')
.cpu cortex-m3
.syntax unified
.fpu softvfp
.section .text.Reset_Handler
@ .weak Reset_Handler
@ .type Reset_Handler, %function /* this should be ODD in thumb/16-bit mode */
@ .size Reset_Handler, .-Reset_Handler /* this code does not compile my compiler it ends with error */
@@@ Equates
.equ GPIOB_CRH, 0x40010C04
.equ GPIOB_ODR, 0x40010C0C
.equ RCC_APB2ENR, 0x40021018
.equ STACKINIT, 0x20005000
.equ LEDDELAY, 0x80000
.section .text
@ .align 2
.org 0
@@@ Vectors
vectors:
.word STACKINIT @ stack pointer value when stack is empty
.word Reset_Handler @ reset vector (manually adjust to odd for thumb)
.word _nmi_handler @
.word _hard_fault @
.word _memory_fault @
.word _bus_fault @
.word _usage_fault @
.org 0x201
Reset_Handler:
ldr sp, =STACKINIT
@@ Enable the Port B peripheral clock by setting bit 4
ldr r6, = RCC_APB2ENR
mov r0, 0x08
str r0, [r6]
- it is very
2025-02-11 02:24 AM
I finally found interesting information:
2.3.4 Vector table
The vector table contains the reset value of the stack pointer, and the start addresses, also
called exception vectors, for all exception handlers. Figure 11 on page 40 shows the order
of the exception vectors in the vector table. The least-significant bit of each vector must be
1, indicating that the exception handler is Thumb code.
ok, "least-significant bit of each vector" there is one simple way to add the "+1".
write: .word Reset_Handler +1 :)
or .... and tis is very QUEER - write these two commands:
.weak Reset_Handler
.type Reset_Handler, %function
:) I really do understand to GNU STM32 assembler ... :)
2025-02-11 05:54 AM
Hi Jerry I found great paper:
https://electronics.stackexchange.com/questions/689743/stm32-vector-table-with-wrong-addresses