我尝试为STM32F030F4制作一个简单的闪烁程序(对于整个STM32F0系列,它可能是相同的)。我尽量避免使用HAL并设置任何不必要的东西,但我无法使其工作。
硬件和工具链工作正常,问题似乎出现在程序本身。
以下是代码:
/*Include definitions for core and peripheral registers*/
#include <core_cm0.h>
#include <stm32f030x6.h>
/*This function launches first after reset*/
void SystemInit (void)
{
RCC -> AHBENR |= RCC_AHBENR_GPIOAEN; //Enable clock for IO port A
GPIOA -> MODER |= GPIO_MODER_MODER4_0; //A4 to Push-Pull
}
/*Simple delay procedure*/
void wait (int x)
{
while (x--); //Delay by wasting cycles
}
/*Launches right after SystemInit()*/
int main (void)
{
while (1) //Repeat forever
{
GPIOA -> BSRR = GPIO_BSRR_BS_4; //Set A4 to HIGH
wait(10000); //Waste 1e4 cycles
GPIOA -> BSRR = GPIO_BSRR_BR_4; //Set A4 to LOW
wait(10000); //Waste again.
}
}
我可能错过了什么?
答案 0 :(得分:0)
也许这里的东西会有所帮助,裸机根本不使用他们的工具,任何(很多/大多数?)gnu arm工具链应该有效。
反汇编程序是你的朋友,你想要裸机并且不使用他们的沙箱或工具然后启动你需要反汇编以节省调试时间。
这会使pa4和5闪烁,您可以根据需要进行调整。
blinker01.c
void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
void dummy ( unsigned int );
#define GPIOABASE 0x48000000
#define RCCBASE 0x40021000
int notmain ( void )
{
unsigned int ra;
unsigned int rx;
ra=GET32(RCCBASE+0x14);
ra|=1<<17; //enable port a
PUT32(RCCBASE+0x14,ra);
//moder
ra=GET32(GPIOABASE+0x00);
ra&=~(3<<8); //PA4
ra&=~(3<<10); //PA5
ra|=1<<8; //PA4
ra|=1<<10; //PA5
PUT32(GPIOABASE+0x00,ra);
//OTYPER
ra=GET32(GPIOABASE+0x04);
ra&=~(1<<4); //PA4
ra&=~(1<<5); //PA5
PUT32(GPIOABASE+0x04,ra);
//ospeedr
ra=GET32(GPIOABASE+0x08);
ra|=3<<8; //PA4
ra|=3<<10; //PA5
PUT32(GPIOABASE+0x08,ra);
//pupdr
ra=GET32(GPIOABASE+0x0C);
ra&=~(3<<8); //PA4
ra&=~(3<<10); //PA5
PUT32(GPIOABASE+0x0C,ra);
for(rx=0;;rx++)
{
PUT32(GPIOABASE+0x18,(1<<5)|(1<<4));
for(ra=0;ra<200000;ra++) dummy(ra);
PUT32(GPIOABASE+0x18,(1<<(5+16))|(1<<(4+16)));
for(ra=0;ra<200000;ra++) dummy(ra);
}
return(0);
}
flash.s
;@-----------------------
.cpu cortex-m0
.thumb
;@-----------------------
.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.thumb_func
reset:
bl notmain
b hang
.thumb_func
hang: b .
;@-----------------------
.align
;@-----------------------
.thumb_func
.globl PUT16
PUT16:
strh r1,[r0]
bx lr
;@-----------------------
.thumb_func
.globl PUT32
PUT32:
str r1,[r0]
bx lr
;@-----------------------
.thumb_func
.globl GET32
GET32:
ldr r0,[r0]
bx lr
;@-----------------------
.thumb_func
.globl dummy
dummy:
bx lr
;@-----------------------
.end
;@-----------------------
sram.s
;@-----------------------
.cpu cortex-m0
.thumb
;@-----------------------
.thumb_func
.global _start
_start:
ldr r0,stacktop
mov sp,r0
bl notmain
b hang
.thumb_func
hang: b .
;@-----------------------
.align
stacktop: .word 0x20001000
;@-----------------------
.thumb_func
.globl PUT16
PUT16:
strh r1,[r0]
bx lr
;@-----------------------
.thumb_func
.globl PUT32
PUT32:
str r1,[r0]
bx lr
;@-----------------------
.thumb_func
.globl GET32
GET32:
ldr r0,[r0]
bx lr
;@-----------------------
.thumb_func
.globl dummy
dummy:
bx lr
;@-----------------------
.end
;@-----------------------
flash.ld
MEMORY
{
ram : ORIGIN = 0x08000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
.rodata : { *(.rodata*) } > ram
.bss : { *(.bss*) } > ram
}
sram.ld
MEMORY
{
ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > ram
.rodata : { *(.rodata*) } > ram
.bss : { *(.bss*) } > ram
}
Makefile gnu工具或clang + llvm + gnu ld。
将ARMGNU替换为您的交叉编译器。
ARMGNU = arm-none-eabi
#ARMGNU = arm-linux-gnueabi
AOPS = --warn --fatal-warnings -mcpu=cortex-m0
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0
LOPS = -Wall -m32 -emit-llvm -target arm-none-eabi -mcpu=cortex-m0 -mthumb
LLCOPS = -march=thumb -mcpu=cortex-m0
#LLCOPS = -mcpu=cortex-m0
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding
OOPS = -std-compile-opts
gcc : blinker01.gcc.thumb.flash.bin blinker01.gcc.thumb.sram.bin
all : gcc clang
clang : blinker01.clang.thumb.norm.flash.bin blinker01.clang.thumb.opt.flash.bin blinker01.clang.thumb.norm.sram.bin blinker01.clang.thumb.opt.sram.bin
clean:
rm -f *.bin
rm -f *.o
rm -f *.elf
rm -f *.list
rm -f *.bc
rm -f *.opt.s
rm -f *.norm.s
#---------------------------------
flash.o : flash.s
$(ARMGNU)-as $(AOPS) flash.s -o flash.o
sram.o : sram.s
$(ARMGNU)-as $(AOPS) sram.s -o sram.o
blinker01.gcc.thumb.o : blinker01.c
$(ARMGNU)-gcc $(COPS) -mthumb -c blinker01.c -o blinker01.gcc.thumb.o
blinker01.gcc.thumb.flash.bin : flash.ld flash.o blinker01.gcc.thumb.o
$(ARMGNU)-ld -o blinker01.gcc.thumb.flash.elf -T flash.ld flash.o blinker01.gcc.thumb.o
$(ARMGNU)-objdump -D blinker01.gcc.thumb.flash.elf > blinker01.gcc.thumb.flash.list
$(ARMGNU)-objcopy blinker01.gcc.thumb.flash.elf blinker01.gcc.thumb.flash.bin -O binary
blinker01.gcc.thumb.sram.bin : sram.ld sram.o blinker01.gcc.thumb.o
$(ARMGNU)-ld -o blinker01.gcc.thumb.sram.elf -T sram.ld sram.o blinker01.gcc.thumb.o
$(ARMGNU)-objdump -D blinker01.gcc.thumb.sram.elf > blinker01.gcc.thumb.sram.list
$(ARMGNU)-objcopy blinker01.gcc.thumb.sram.elf blinker01.gcc.thumb.sram.bin -O binary
#---------------------------------
blinker01.clang.bc : blinker01.c
clang $(LOPS) -c blinker01.c -o blinker01.clang.bc
blinker01.clang.thumb.norm.flash.bin : flash.ld flash.o blinker01.clang.bc
#llc $(LLCOPS) blinker01.clang.bc -o blinker01.clang.thumb.norm.s
#$(ARMGNU)-as $(AOPS) blinker01.clang.thumb.norm.s -o blinker01.clang.thumb.norm.o
llc $(LLCOPS) blinker01.clang.bc -filetype=obj -o blinker01.clang.thumb.norm.o
$(ARMGNU)-ld -o blinker01.clang.thumb.norm.flash.elf -T flash.ld flash.o blinker01.clang.thumb.norm.o
$(ARMGNU)-objdump -D blinker01.clang.thumb.norm.flash.elf > blinker01.clang.thumb.norm.flash.list
$(ARMGNU)-objcopy blinker01.clang.thumb.norm.flash.elf blinker01.clang.thumb.norm.flash.bin -O binary
blinker01.clang.thumb.opt.flash.bin : flash.ld flash.o blinker01.clang.bc
opt $(OOPS) blinker01.clang.bc -o blinker01.clang.thumb.opt.bc
#llc $(LLCOPS) blinker01.clang.thumb.opt.bc -o blinker01.clang.thumb.opt.s
#$(ARMGNU)-as $(AOPS) blinker01.clang.thumb.opt.s -o blinker01.clang.thumb.opt.o
llc $(LLCOPS) blinker01.clang.thumb.opt.bc -filetype=obj -o blinker01.clang.thumb.opt.o
$(ARMGNU)-ld -o blinker01.clang.thumb.opt.flash.elf -T flash.ld flash.o blinker01.clang.thumb.opt.o
$(ARMGNU)-objdump -D blinker01.clang.thumb.opt.flash.elf > blinker01.clang.thumb.opt.flash.list
$(ARMGNU)-objcopy blinker01.clang.thumb.opt.flash.elf blinker01.clang.thumb.opt.flash.bin -O binary
blinker01.clang.thumb.norm.sram.bin : sram.ld sram.o blinker01.clang.bc
#llc $(LLCOPS) blinker01.clang.bc -o blinker01.clang.thumb.norm.s
#$(ARMGNU)-as $(AOPS) blinker01.clang.thumb.norm.s -o blinker01.clang.thumb.norm.o
llc $(LLCOPS) blinker01.clang.bc -filetype=obj -o blinker01.clang.thumb.norm.o
$(ARMGNU)-ld -o blinker01.clang.thumb.norm.sram.elf -T sram.ld sram.o blinker01.clang.thumb.norm.o
$(ARMGNU)-objdump -D blinker01.clang.thumb.norm.sram.elf > blinker01.clang.thumb.norm.sram.list
$(ARMGNU)-objcopy blinker01.clang.thumb.norm.sram.elf blinker01.clang.thumb.norm.sram.bin -O binary
blinker01.clang.thumb.opt.sram.bin : sram.ld sram.o blinker01.clang.bc
opt $(OOPS) blinker01.clang.bc -o blinker01.clang.thumb.opt.bc
#llc $(LLCOPS) blinker01.clang.thumb.opt.bc -o blinker01.clang.thumb.opt.s
#$(ARMGNU)-as $(AOPS) blinker01.clang.thumb.opt.s -o blinker01.clang.thumb.opt.o
llc $(LLCOPS) blinker01.clang.thumb.opt.bc -filetype=obj -o blinker01.clang.thumb.opt.o
$(ARMGNU)-ld -o blinker01.clang.thumb.opt.sram.elf -T sram.ld sram.o blinker01.clang.thumb.opt.o
$(ARMGNU)-objdump -D blinker01.clang.thumb.opt.sram.elf > blinker01.clang.thumb.opt.sram.list
$(ARMGNU)-objcopy blinker01.clang.thumb.opt.sram.elf blinker01.clang.thumb.opt.sram.bin -O binary
在stm32f0上闪烁pa4和5。因为不同的启动条件,我有不同的bootstrap代码,可以说你可以使用相同的一个,只是从一个偏移恢复从sram(jtag)运行。
flash版本反汇编小心这里检查第一项是堆栈指针加载值,然后我认为必须是奇数的地址(拇指模式)但不确定,可以轻松测试。当使用时,lsbit被剥离,因此0x08000040是复位向量,这就是我们在反汇编中看到的,sp由逻辑加载,所以我们可以直接进入notmain(只是来自旧工具链的习惯,如果它会添加垃圾)看到一个名为main的函数
08000000 <_start>:
8000000: 20001000 andcs r1, r0, r0
8000004: 08000041 stmdaeq r0, {r0, r6}
8000008: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800000c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000010: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000014: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000018: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800001c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000020: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000024: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000028: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800002c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000030: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000034: 08000047 stmdaeq r0, {r0, r1, r2, r6}
8000038: 08000047 stmdaeq r0, {r0, r1, r2, r6}
800003c: 08000047 stmdaeq r0, {r0, r1, r2, r6}
08000040 <reset>:
8000040: f000 f80a bl 8000058 <notmain>
8000044: e7ff b.n 8000046 <hang>
08000046 <hang>:
8000046: e7fe b.n 8000046 <hang>
08000048 <PUT16>:
8000048: 8001 strh r1, [r0, #0]
800004a: 4770 bx lr
0800004c <PUT32>:
800004c: 6001 str r1, [r0, #0]
800004e: 4770 bx lr
08000050 <GET32>:
8000050: 6800 ldr r0, [r0, #0]
8000052: 4770 bx lr
08000054 <dummy>:
8000054: 4770 bx lr
8000056: 46c0 nop ; (mov r8, r8)
08000058 <notmain>:
8000058: b570 push {r4, r5, r6, lr}
800005a: 4824 ldr r0, [pc, #144] ; (80000ec <notmain+0x94>)
800005c: f7ff fff8 bl 8000050 <GET32>
8000060: 2180 movs r1, #128 ; 0x80
8000062: 0289 lsls r1, r1, #10
8000064: 4301 orrs r1, r0
8000066: 4821 ldr r0, [pc, #132] ; (80000ec <notmain+0x94>)
8000068: f7ff fff0 bl 800004c <PUT32>
800006c: 2090 movs r0, #144 ; 0x90
800006e: 05c0 lsls r0, r0, #23
8000070: f7ff ffee bl 8000050 <GET32>
8000074: 21a0 movs r1, #160 ; 0xa0
8000076: 4c1e ldr r4, [pc, #120] ; (80000f0 <notmain+0x98>)
8000078: 00c9 lsls r1, r1, #3
800007a: 4020 ands r0, r4
800007c: 4301 orrs r1, r0
800007e: 2090 movs r0, #144 ; 0x90
8000080: 05c0 lsls r0, r0, #23
8000082: f7ff ffe3 bl 800004c <PUT32>
8000086: 481b ldr r0, [pc, #108] ; (80000f4 <notmain+0x9c>)
8000088: f7ff ffe2 bl 8000050 <GET32>
800008c: 2330 movs r3, #48 ; 0x30
800008e: 0001 movs r1, r0
8000090: 4818 ldr r0, [pc, #96] ; (80000f4 <notmain+0x9c>)
8000092: 4399 bics r1, r3
8000094: f7ff ffda bl 800004c <PUT32>
8000098: 4817 ldr r0, [pc, #92] ; (80000f8 <notmain+0xa0>)
800009a: f7ff ffd9 bl 8000050 <GET32>
800009e: 21f0 movs r1, #240 ; 0xf0
80000a0: 0109 lsls r1, r1, #4
80000a2: 4301 orrs r1, r0
80000a4: 4814 ldr r0, [pc, #80] ; (80000f8 <notmain+0xa0>)
80000a6: f7ff ffd1 bl 800004c <PUT32>
80000aa: 4814 ldr r0, [pc, #80] ; (80000fc <notmain+0xa4>)
80000ac: f7ff ffd0 bl 8000050 <GET32>
80000b0: 0001 movs r1, r0
80000b2: 4812 ldr r0, [pc, #72] ; (80000fc <notmain+0xa4>)
80000b4: 4021 ands r1, r4
80000b6: f7ff ffc9 bl 800004c <PUT32>
80000ba: 4d11 ldr r5, [pc, #68] ; (8000100 <notmain+0xa8>)
80000bc: 2130 movs r1, #48 ; 0x30
80000be: 4811 ldr r0, [pc, #68] ; (8000104 <notmain+0xac>)
80000c0: f7ff ffc4 bl 800004c <PUT32>
80000c4: 2400 movs r4, #0
80000c6: 0020 movs r0, r4
80000c8: 3401 adds r4, #1
80000ca: f7ff ffc3 bl 8000054 <dummy>
80000ce: 42ac cmp r4, r5
80000d0: d1f9 bne.n 80000c6 <notmain+0x6e>
80000d2: 21c0 movs r1, #192 ; 0xc0
80000d4: 480b ldr r0, [pc, #44] ; (8000104 <notmain+0xac>)
80000d6: 0389 lsls r1, r1, #14
80000d8: f7ff ffb8 bl 800004c <PUT32>
80000dc: 2400 movs r4, #0
80000de: 0020 movs r0, r4
80000e0: 3401 adds r4, #1
80000e2: f7ff ffb7 bl 8000054 <dummy>
80000e6: 42ac cmp r4, r5
80000e8: d1f9 bne.n 80000de <notmain+0x86>
80000ea: e7e7 b.n 80000bc <notmain+0x64>
80000ec: 40021014 andmi r1, r2, r4, lsl r0
80000f0: fffff0ff ; <UNDEFINED> instruction: 0xfffff0ff
80000f4: 48000004 stmdami r0, {r2}
80000f8: 48000008 stmdami r0, {r3}
80000fc: 4800000c stmdami r0, {r2, r3}
8000100: 00030d40 andeq r0, r3, r0, asr #26
8000104: 48000018 stmdami r0, {r3, r4}