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 06:49 AM
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
2025-02-10 06:55 AM
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
2025-02-10 06:57 AM
ok, so may I use:
.syntax unified
.cpu cortex-m3
.code 16
.aligh 2
and omit the "+1" in my vector table ?
2025-02-10 07:00 AM
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
2025-02-10 07:25 AM
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
2025-02-10 08:25 AM
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
2025-02-10 08:39 AM
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.
2025-02-10 08:56 AM - edited 2025-02-10 08:57 AM
>> ??? 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
2025-02-10 08:58 AM
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)
}
}