简单的STM32F0闪烁程序

时间:2015-11-09 18:42:35

标签: microcontroller stm32 cortex-m

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

我可能错过了什么?

1 个答案:

答案 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}