Привет, народ. Давайте с вопросами программирования stm32 здесь расположимся.
А то про конструкции на stm32 темы имеются, а про программирование - нет. Одни и те же вопросы поднимаются в разных темах.
Для затравки. (-:
В последнее время штудировал stm32. Наработанные с avr методики пригодились даже больше, чем ожидал. С ассемблером разницы особой нет. Инструкции, ну да, отличаются, не кардинально. Как avr программировал под gas (gnu assembly), так и stm32 продолжил.
Представляю простую лабу - "БарэмЕтал блиньк".
Кто не знает - "baremetal", это значит "чисто железячный". Подход к задаче без излишеств. Даже без особого мнения на чём правильно программировать вместо ассемблера.
Voila! Поехали!
Код:
oleg@tower ~/ $ tree
.
├── Makefile
├── linker.ld
└── main.S
0 directories, 3 files
Код:
oleg@tower ~/ $ cat Makefile
TARGET = main
LD_SCRIPT = linker.ld
TOOLCHAIN = /usr
CC = $(TOOLCHAIN)/bin/arm-none-eabi-gcc
AS = $(TOOLCHAIN)/bin/arm-none-eabi-as
LD = $(TOOLCHAIN)/bin/arm-none-eabi-ld
OC = $(TOOLCHAIN)/bin/arm-none-eabi-objcopy
OD = $(TOOLCHAIN)/bin/arm-none-eabi-objdump
OS = $(TOOLCHAIN)/bin/arm-none-eabi-size
ASFLAGS += -c
ASFLAGS += -specs=nosys.specs
ASFLAGS += -g
ASFLAGS += -O0
ASFLAGS += -mcpu=cortex-m3
ASFLAGS += -mthumb
ASFLAGS += -Wall
ASFLAGS += -Wextra
ASFLAGS += -fmessage-length=0
ASFLAGS += -no-pie
ASFLAGS += -march=armv7-m
ASFLAGS += -masm-syntax-unified
ASFLAGS += -fno-exceptions
ASFLAGS += -fno-unwind-tables
ASFLAGS += -mlittle-endian
ASFLAGS += -fno-rtti
LFLAGS += -mcpu=cortex-m3
LFLAGS += -march=armv7-m
LFLAGS += -mlittle-endian
LFLAGS += -masm-syntax-unified
LFLAGS += -fno-rtti
LFLAGS += -fno-exceptions
LFLAGS += -fno-unwind-tables
LFLAGS += -mthumb
LFLAGS += -Wall
LFLAGS += -specs=nosys.specs
LFLAGS += -nostdlib
LFLAGS += -nostartfiles
LFLAGS += -lgcc
LFLAGS += -T$(LD_SCRIPT)
LFLAGS += -no-pie
AS_SRC = main.S
INCLUDE = -I./
OBJS = $(AS_SRC:.S=.o)
.PHONY: all
all: $(TARGET).bin
%.o: %.S
$(CC) -x assembler-with-cpp $(ASFLAGS) $< -o $@
$(TARGET).elf: $(OBJS)
$(CC) $^ $(LFLAGS) -o $@
$(TARGET).bin: $(TARGET).elf
$(OC) -S -O binary $< $@
$(OS) $<
.PHONY: clean
clean:
rm -f $(OBJS)
rm -f $(TARGET).elf
rm -f $(TARGET).bin
flash: all
st-flash --reset write $(TARGET).bin 0x8000000
Код:
oleg@tower ~/ $ cat linker.ld
ENTRY(main)
_estack = 0x20005000;
MEMORY
{
FLASH ( rx ) : ORIGIN = 0x08000000, LENGTH = 64K
RAM ( rxw ) : ORIGIN = 0x20000000, LENGTH = 20K
}
SECTIONS
{
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
. = ALIGN(4);
} >FLASH
}
Код:
oleg@tower ~/ $ cat main.S
.syntax unified
.cpu cortex-m3 @ stm32f103c6t6
.global main @
.section .text @ only section
boot: @ word
.word _estack @ see linker script
.word main @ reset address
.thumb_func @ aka +1 offset to reset
main: @ thumb code
ldr r0, =(1<<4) @ mask GPIOC clock enable
ldr r2, =0x40021000 @ bus clock reg
ldr r1, =0x18 @ gpioc clock reg offset
ldr r3, [r2, r1] @ read clock reg
orr r0, r0, r3 @ set clock enable
str r0, [r2, r1] @ update clock reg
ldr r0, [r2, r1] @ just delay a bit
ldr r0, [r2, r1] @ just delay a bit
ldr r0, =(1<<21) @ mask C13 output push-pull at 2MHz
ldr r2, =0x40011000 @ (GPIO offset)
ldr r1, =0x04 @ (GPIOC_CRH offset)
ldr r3, [r2, r1] @ read
orr r0, r0, r3 @ modify
str r0, [r2, r1] @ write
loop:
ldr r0, =(1<<13) @ mask C13 high
ldr r2, =0x40011000 @ (GPIO offset)
ldr r1, =0x10 @ (GPIOC_BSRR offset)
str r0, [r2, r1] @ write
bl delay
ldr r0, =(1<<29) @ mask C13 low
ldr r2, =0x40011000 @ (GPIO offset)
ldr r1, =0x10 @ (GPIOC_BSRR offset)
str r0, [r2, r1] @ write
bl delay
b loop @ infinite loop
delay:
ldr r4, =0x100000
again:
subs r4, r4, 1
bne again
bx lr
.end
Код:
oleg@tower ~/ $ make clean all
rm -f main.o
rm -f main.elf
rm -f main.bin
/usr/bin/arm-none-eabi-gcc -x assembler-with-cpp -c -specs=nosys.specs -g -O0 -mcpu=cortex-m3 -mthumb -Wall -Wextra -fmessage-length=0 -no-pie -march=armv7-m -masm-syntax-unified -fno-exceptions -fno-unwind-tables -mlittle-endian -fno-rtti main.S -o main.o
/usr/bin/arm-none-eabi-gcc main.o -mcpu=cortex-m3 -march=armv7-m -mlittle-endian -masm-syntax-unified -fno-rtti -fno-exceptions -fno-unwind-tables -mthumb -Wall -specs=nosys.specs -nostdlib -nostartfiles -lgcc -Tlinker.ld -no-pie -o main.elf
/usr/bin/arm-none-eabi-objcopy -S -O binary main.elf main.bin
/usr/bin/arm-none-eabi-size main.elf
text data bss dec hex filename
100 0 0 100 64 main.elf
Код:
oleg@tower ~/ $ make flash
st-flash --reset write main.bin 0x8000000
st-flash 1.7.0
2023-04-14T20:38:44 INFO common.c: F1xx High-density: 64 KiB SRAM, 256 KiB flash in at least 2 KiB pages.
file main.bin md5 checksum: 78946d427b4d276feeea02bb3ff59e0, stlink checksum: 0x00001f46
2023-04-14T20:38:44 INFO common.c: Attempting to write 100 (0x64) bytes to stm32 address: 134217728 (0x8000000)
2023-04-14T20:38:44 INFO common.c: Flash page at addr: 0x08000000 erased
2023-04-14T20:38:44 INFO common.c: Finished erasing 1 pages of 2048 (0x800) bytes
2023-04-14T20:38:44 INFO common.c: Starting Flash write for VL/F0/F3/F1_XL
2023-04-14T20:38:44 INFO flash_loader.c: Successfully loaded flash loader in sram
2023-04-14T20:38:44 INFO flash_loader.c: Clear DFSR
1/ 1 pages written
2023-04-14T20:38:44 INFO common.c: Starting verification of write complete
2023-04-14T20:38:44 INFO common.c: Flash written and verified! jolly good!
2023-04-14T20:38:44 WARN common.c: NRST is not connected
Мигает.
Резюме то же, что и для микрочипов:
Кто считает, что cortex-m это вынос мозга, а для "вхождения" нужно что-то большее, чем старый линуксовый ноут или распбери, сторублевый программатор и блю-пил с китайским клоном, того вынужден разочаровать. Было бы желание. Из документации - даташит на мк, референс на мк, руководство по программированию на мк. Все от разработчика. Из софта, как обычно - make, gcc, gdb, stlink, vim.
P.S. Чуть не забыл. Обязательно нужен кусочек синей изоленты. Аккурат между блю-пилом и программатором. У программатора алюминиевый корпус. Краска постепенно прошкрябается и может коротнуть. Удачи.