cancel
Showing results for 
Search instead for 
Did you mean: 

Code 16 and Code 32 on STM32F103C8T6

JerryMC22
Associate III

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.

 

20 REPLIES 20

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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 ?

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]
View more

 

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 ?????

 

 

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]
View more

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 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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 ?????

gbm
Principal

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?

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

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]
View more

- it is very 

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  ... :)