2025-02-04 4:01 AM
Hello,
I am trying small example LED blinking written in assembly only - see below. LED is placed to PB15. I am able to compile the program without error using this commands:
arm-none-eabi-gcc -save-temps -nostdlib -nostartfiles -mcpu=cortex-m3 -ffreestanding -O2 led-stm32.s -o led-stm32.elf
arm-none-eabi-objcopy -O binary led-stm32.elf led-stm32.bin
I am using "gcc-arm-none-eabi-10.3-2021.10-win32.exe". I am able to write the program to processor STM32F103C8T6 using STLINKV2, but nothing happend. LED on PB15 is no blinking, LED is no shining. LED is off. .
Can someone help me where is problem ? :) Do you (someone) have working example in assembly ?
@@@ led-stm32.asm
@@@ Directives
.cpu cortex-m3
.code 16 @
.syntax unified
.global _start
.align 2
@@@ Equates
.equ GPIOB_CRH, 0x40010C04
.equ GPIOB_ODR, 0x40010C0C
.equ RCC_APB2ENR, 0x40021018
.equ STACKINIT, 0x20005000
.equ LEDDELAY, 0x4E20 @20000
.section .text
.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 15 so it will
@@ be a open drain output (up to 8 MHz) by setting bits 19-16
@@ to '0110'.
ldr r6, = GPIOB_CRH
ldr r0, = #0x64444444 @ 0110 0100 0100 0100 0100 0100 0100 0100
str r0, [r6]
@@ Load R2 and R3 with the "on" and "off" constants
mov r2, #0 @ 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, #1
bne delay1
str r3, [r6] @ set Port B, pin 15, turning off LED
ldr r1, = LEDDELAY
delay2:
subs r1, #1
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
2025-02-04 5:14 AM
I haven't checked your code yet due to time constraints, but you can use my ASM example that I once created for STM32G4 and the STM32CubeIDE as a guide. As Cortex-M4 and Cortex-M3 are very similar, you only need to adapt the ASM syntax to your toolchain and check the register addresses.
Hope that helps?
Regards
/Peter
2025-02-05 7:33 AM
So, I tested your program in asm + CubeIDE, but I was NOT able to get the code up and running. So I downloaded free Keil MDK 5.4:1 and I found this example
https://www.youtube.com/watch?v=Zj4-fgRph1s
on youtube and the code is working ok. Source code is in attachments. The compiler is armclang. it means that I did not use the queer GNU arm assembler.
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)
}
}
2025-02-10 6:11 AM
Hi Jerry,
I finally succeeded and LED PB15 blink example using GNU assebler is working ok :) See attached code.
gcc-arm-none-eabi-10.3-2021.10-win32.exe is used from https://developer.arm.com/downloads/-/gnu-rm
:)