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.

 

19 REPLIES 19

The registers and operations are 32-bit, but the Cortex-Mx only supports Thumb(2) which consists of 16-bit opcodes

  .syntax unified
  .cpu cortex-m3
  .fpu softvfp
  .thumb
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
KnarfB
Principal III

yes, 32-bit ALU, registers, data buses and addressing. 16-bit "compressed" thumb instructions give higher code density, less memory access for a subset of commonly used instructions. 

hth

KnarfB

 

ok, so may I use:

  .syntax unified
  .cpu cortex-m3
  .code 16
  .aligh 2

and omit the "+1" in my vector table ?

Shouldn't be necessary if the assembler is in the right mode

Perhaps look at examples in the repo

STM32Cube_FW_F1_V1.6.0\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\gcc\startup_stm32f103xb.s

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

If I omit the "+1" the processor is not runnig:

@@@ Directives
        .code 16                  @ (same as saying '.code 16')
        .cpu cortex-m3
        .syntax unified
        .fpu softvfp
        .weak _start 

@@@ Equates
        .equ GPIOB_CRH,   0x40010C04
        .equ GPIOB_ODR,   0x40010C0C
        .equ RCC_APB2ENR, 0x40021018
        .equ STACKINIT,   0x20005000

        .equ LEDDELAY,    0x80000

.section .text
        .org 0

@@@ Vectors
vectors:
        .word STACKINIT         @ stack pointer value when stack is empty
        .word _start         @ reset vector (manually adjust to odd for thumb)
        .word _nmi_handler   @
        .word _hard_fault    @
        .word _memory_fault  @
        .word _bus_fault     @
        .word _usage_fault   @

However I found in:

stm32cube_fw_f1_v160.zip\STM32Cube_FW_F1_V1.6.0\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\gcc\startup_stm32f103xb.s

that there are no "+1" for vector table. It is suspicious.

g_pfnVectors:

  .word _estack
  .word Reset_Handler
  .word NMI_Handler
  .word HardFault_Handler
  .word MemManage_Handler
  .word BusFault_Handler
  .word UsageFault_Handler
  .word 0
  .word 0
  .word 0
  .word 0
  .word SVC_Handler
  .word DebugMon_Handler
  .word 0

 

 

armclang assebmler does not need the "+1" for reset_vector see below, so where is the "odd" element in

STM32Cube_FW_F1_V1.6.0\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\gcc\startup_stm32f103xb.s

??? in gnu linker setting ???

 

 

File1.asm

stackStartAddress  EQU 0x20000100
 
      AREA mySection1, DATA, READONLY
       
      DCD stackStartAddress
      DCD myResetHandler
       
      AREA mySection2, CODE, READONLY
      ENTRY
      
      
myResetHandler   
      IMPORT myApplication
       
      B myApplication
      
      END


File2.asm

      EXPORT myApplication
       
RCC        EQU 0x40021000
Port_C     EQU 0x40010C00
 
       
      AREA mySection3, CODE, READONLY
       
myApplication
      ; enable the APB2 clock
      
      MOV r0, #0x08
      LDR r1, =RCC
      STR r0, [r1, #0x18]


      ; configure the GPIO C for output

      MOV r0, #0x20000000
      LDR r1, =Port_C
      STR r0, [r1, #0x04]


      ; set the builtin LED on/off
      
      MOV r0, #0x0000 ; #0x8000
      STR r0, [r1, #0x0C]


      B .

      ALIGN

      END


First.sct – script for linker

LR_IROM1 0x08000000 0x00010000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00010000  {  ; load address = execution address
   file1.o (mySection1, +First)
   file1.o (mySection2)
   file2.o (mySection3)
   
   ; .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00005000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

where is 

gbm
Principal

Generally you don't need to use these "+1"s if the assembler correctly recognizes the symbol as Thumb code label, which is quite easy to achieve - look at the default startupxxxx.s files supplied with STM32Cube or Keil MDK-ARM and check the "thumb" directives.

Of course every Cortex-M is a 32/bit processor but in Thumb instruction set some instructions are encoded as 16-bits and the others, more complex or less frequently used, as 32-bits.

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

>> ??? in gnu linker setting ???

No, in the symbolic assignment of addresses in the assembler and compiler

Reset_Handler, etc should be ODD

The stack pointer should be 32-bit aligned.

 

    .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function /* this should be ODD in thumb/16-bit mode */
Reset_Handler:
  ldr   sp, =_estack      /* set stack pointer */

...

  .size  Reset_Handler, .-Reset_Handler

 

The MCU will Hard Fault if you try to execute 32-bit / EVEN addressed code

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

I have correctly directed thumb instructions by:

 

  .syntax unified
  .cpu cortex-m3
  .fpu softvfp
  .thumb

in my code, but I have to use the "+1" still. If I omit it the processor does not run. My complette code is:

but I still do not see the "problem" :( I am SAD

@  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._start 

@@@ Equates
        .equ GPIOB_CRH,   0x40010C04
        .equ GPIOB_ODR,   0x40010C0C
        .equ RCC_APB2ENR, 0x40021018
        .equ STACKINIT,   0x20005000

        .equ LEDDELAY,    0x80000

.section .text
        .align
        .org 0

@@@ Vectors
vectors:
        .word STACKINIT          @ stack pointer value when stack is empty
        .word _start         + 1 @ 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 @


_start:
        @@ Enable the Port B peripheral clock by setting bit 4
        ldr r6, = RCC_APB2ENR
        mov r0, 0x08
        str r0, [r6]

        @@ Set the config and mode bits for Port B bit 31,30 to 0x00
        @@ and bits 29,28 to 0x10 to be a push-pull output (up to 20 MHz) 
        @@ to '0010'.

        ldr r6, = GPIOB_CRH
        mov r0, 0x20000000
        str r0, [r6]

        @@ Load R2 and R3 with the "on" and "off" constants, 0 is on, 1 is off
        mov r2, 0x0000         @ value to turn on LED
        mov r3, 0x8000         @ value to turn off LED

        ldr r6, = GPIOB_ODR    @  point to Port B output data register

loop:
        str r2, [r6]           @ clear Port B, pin 15, turning on LED
        ldr r1, = LEDDELAY
   
        
delay1:
        subs r1, 0x01
        bne delay1

        str r3, [r6]           @ set Port b, pin 15, turning off LED
        ldr r1, = LEDDELAY
delay2:
        subs r1, 0x01
        bne delay2

        b loop                 @ continue forever

_dummy:                        @ if any int gets triggered, just hang in a loop
_nmi_handler:
_hard_fault:
_memory_fault:
_bus_fault:
_usage_fault:
        add r0, 1
        add r1, 1
        b _dummy

 

/* Simple linker script for the STM32 ARM Cortex M3.  Link the text
   of the program into on-board flash and use on-board RAM for data and stack.
*/

SECTIONS
{
        /* interrupt vectors start at zero */
        . = 0x08000000;  /* start of flash */

        .text :  {  *(.text)   }

        /* constant data follows code but still in flash */
        .data :
        {
          *(.data)
          *(.rom)
        }

        /* internal RAM starts at 0x20000000 */
        . = 0x20000000;
        .ram : { *(.ram) }

        .bss :
        {
          *(.bss)
          *(.ram)
        }
}