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.

 

1 ACCEPTED SOLUTION

Accepted Solutions

I finally found interesting solution - see below, it is possible to fix the reset handler address as e.g. 0x301 and reset handler place to .org 0x300 :)  cute solution

 

@@@ Vectors vectors: .word STACKINIT @ stack pointer value when stack is empty .word 0x301 @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 0x300 Reset_Handler: ldr sp, =STACKINIT

 

View solution in original post

20 REPLIES 20

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
Super User

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) } }
View more

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

 

/* 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) } }