简单的STM32F0闪烁程序



我试图为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.
    }
}

我可能错过了什么?

也许这里的一些东西会有所帮助,裸金属根本不使用他们的工具,任何(很多/大多数?)gnu-arm工具链都应该工作。

反汇编程序是你的朋友,你想赤手空拳,不使用他们的沙箱或工具,然后要启动它,你需要进行反汇编,以节省调试时间。

这会闪烁pa4和5,您可以根据需要进行调整。

闪烁器01.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的

;@-----------------------
.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的

;@-----------------------
.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
}

制作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。由于不同的启动条件,我有不同的引导程序代码,可以说你可以使用相同的代码,然后从一个偏移量恢复从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}

最新更新