cancel
Showing results for 
Search instead for 
Did you mean: 

Code 16 and Code 32 on STM32F103C8T6

JerryMC22
Associate II

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.

 

18 REPLIES 18

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]

 

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]

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]

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