https://github.com/txson/ubuntu-stm32
欢迎大家参与修改
stm32 属于arm cortex-m系列thumb指令集,使用的编译工具是arm-none-eabi,不同的内核的板子都是不一样的.在下面的地址可以下载到:
https://launchpad.net/gcc-arm-embedded/+download
在电脑目录上解压,并在使用的到的bash配置文件下,设置相应的路径环境变量,比如我使用的是zsh就在相应的~/.zshrc里面加上:
export PATH=$PATH:/home/raoxu/tool/gcc-arm-none-eabi-5_4-2016q3/bin
任意目录下测试是否可以使用
arm-none-eabi-gcc -v
我的工程目录
├── \
├── include
│ ├── stm32f4xx_hal_conf.h
│ └── stm32f4xx_hal.h
├── lib
│ ├── libapp.a
│ └── libstm32.a
├── makefile
├── makefile.common
├── STM32Cube_FW_F4_V1.10.0
│ ├── Documentation
│ ├── Drivers
│ ├── _htmresc
│ ├── Makefile
│ ├── Middlewares
│ ├── package.xml
│ ├── Projects
│ ├── Release_Notes.html
│ ├── tags
│ └── Utilities
├── STM32F407VGTx_FLASH.ld
├── tags
└── user
├── app.a
├── main.c
├── main.h
├── makefile
├── startup_stm32f407xx.s
├── stm32f4xx_it.c
├── stm32f4xx_it.h
└── system_stm32f4xx.c
先看根目录下的makefile.common这里是几个目录下公用的
TOP = $(shell pwd)
PROGRAM = stm32f4_out
LIBDIR = $(TOP)/lib
TypeOfMCU=STM32F407xx
TC=arm-none-eabi
CC=$(TC)-gcc
LD=$(TC)-ld -v
OBJCOPY=$(TC)-objcopy
AR=$(TC)-ar
GDB=$(TC)-gdb
INCLUDE=-I$(TOP)/include
COMMONFLAGS=-g -mcpu=cortex-m3 -mthumb
COMMONFLAGSlib=$(COMMONFLAGS)
CFLAGS+=$(COMMONFLAGS) -Wall -Werror $(INCLUDE)
CFLAGS+=-D $(TypeOfMCU)
CFLAGS+=-D VECT_TAB_FLASH
CFLAGSlib+=$(COMMONFLAGSlib) -Wall -Werror $(INCLUDE)
CFLAGSlib+=-D $(TypeOfMCU)
CFLAGSlib+=-D VECT_TAB_FLASH
# libs Makefile
include ../makefile.common
CFLAGSlib+=-c
STM32LIB = $(shell pwd)
obj1 = $(STM32LIB)/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/*.o
obj2 = $(STM32LIB)/Drivers/STM32F4xx_HAL_Driver/Src/*.o
inc1 = $(STM32LIB)/Drivers/STM32F4xx_HAL_STM32LIB/Inc
inc2 = $(STM32LIB)/Drivers/CMSIS/Device/ST/STM32F4xx/Include/
inc3 = $(STM32LIB)/Drivers/CMSIS/Include
inc4 = $(STM32LIB)/Drivers/STM32F4xx_HAL_Driver/Inc
libstm32.a: $(obj1) $(obj2)
echo "comlile stm32lib.a"
$(AR) cr $(STM32LIB)/Drivers/$@ $^
echo "make stm32lib success"
$(obj1) :
echo "comlile obj1"
cd $(STM32LIB)/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/ && \
$(CC) $(CFLAGSlib) \
-I$(inc1) -I$(inc2) -I$(inc3) \
system_stm32f4xx.c
$(obj2) :
echo "comlile obj2"
cd $(STM32LIB)/Drivers/STM32F4xx_HAL_Driver/Src && \
$(CC) $(CFLAGSlib) \
-I$(inc4) -I$(inc2) -I$(inc3) \
-I../../../../include \
*.c
.PHONY: clean
clean:
rm -f $(STM32LIB)/Drivers/libstm32.a $(obj1) $(obj2)
编译的结果:
make clean;make
rm -f /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/libstm32.a /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/*.o /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Src/*.o
echo "comlile obj1"
comlile obj1
cd /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/ && \
arm-none-eabi-gcc -g -mcpu=cortex-m3 -mthumb -Wall -Werror -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/include -D STM32F407xx -D VECT_TAB_FLASH -c \
-I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_STM32LIB/Inc -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include/ -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
system_stm32f4xx.c
echo "comlile obj2"
comlile obj2
cd /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Src && \
arm-none-eabi-gcc -g -mcpu=cortex-m3 -mthumb -Wall -Werror -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/include -D STM32F407xx -D VECT_TAB_FLASH -c \
-I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Inc -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include/ -I/home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
-I../../../../include \
*.c
echo "comlile stm32lib.a"
comlile stm32lib.a
arm-none-eabi-ar cr /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/libstm32.a /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/*.o /home/raoxu/self_education/stm32_project/STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Src/*.o
echo "make stm32lib success"
make stm32lib success
可以找到./STM32Cube_FW_F4_V1.10.0/Drivers/libstm32.a这样静态库就编译成功了
/* Configure the GPIO_LED pin */
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* Infinite loop */
while (1)
{
if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) == 1) {
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, SET);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, SET);
} else {
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, RESET);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, RESET);
}
}
我是用的是正点原子的板子,按键pe4就会点亮pf9和pf10,之后下载程序后可以单步调试,看效果
接下来是user目录下的makefile
include ../makefile.common
CFLAGSlib+=-c
USER = $(shell pwd)
src += ./*.c
src += ./*.s
obj = ./*.o
.PHONY :obj
libapp.a : $(obj)
$(AR) cr $@ \
$^
$(obj):
$(CC) $(CFLAGSlib) \
-I../include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Inc \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
$(src)
.PHONY :clean
clean :
rm libapp.a $(obj)
make clean;make 之后
rm libapp.a ./*.o
rm: cannot remove 'libapp.a': No such file or directory
rm: cannot remove './*.o': No such file or directory
makefile:25: recipe for target 'clean' failed
make: *** [clean] Error 1
arm-none-eabi-gcc -g -mcpu=cortex-m3 -mthumb -Wall -Werror -I/home/raoxu/self_education/stm32_project/user/include -D STM32F407xx -D VECT_TAB_FLASH -c \
-I../include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/STM32F4xx_HAL_Driver/Inc \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Device/ST/STM32F4xx/Include \
-I../STM32Cube_FW_F4_V1.10.0/Drivers/CMSIS/Include \
./*.c ./*.s
arm-none-eabi-ar cr libapp.a \
*.o
可以看到user目录下生成了libapp.a的静态库
boot文件使用hal库里自带的汇编文件(启动文件)
链接脚本使用的是hal库在带的链接脚本
注意的是不同的芯片都需要使用不同的boot文件和链接脚本
根目录下的makefile
# general Makefile
include makefile.common
LDFLAGS=$(COMMONFLAGS) -fno-exceptions -ffunction-sections -fdata-sections -L$(LIBDIR) -nostartfiles -Wl,--gc-sections,-TSTM32F407VGTx_FLASH.ld
LDLIBS+=-lstm32
LDLIBS+=-lapp
all: user STM32Cube_FW_F4_V1.10.0
$(CC) -o $(PROGRAM).elf $(LDFLAGS) \
-Wl,--whole-archive \
user/libapp.a \
-Wl,--no-whole-archive \
$(LDLIBS)
$(OBJCOPY) -O ihex $(PROGRAM).elf $(PROGRAM).hex
$(OBJCOPY) -O binary $(PROGRAM).elf $(PROGRAM).bin
#Extract info contained in ELF to readable text-files:
arm-none-eabi-readelf -a $(PROGRAM).elf > $(PROGRAM).info_elf
arm-none-eabi-size -d -B -t $(PROGRAM).elf > $(PROGRAM).info_size
arm-none-eabi-objdump -S $(PROGRAM).elf > $(PROGRAM).info_code
arm-none-eabi-nm -t d -S --size-sort -s $(PROGRAM).elf > $(PROGRAM).info_symbol
STM32Cube_FW_F4_V1.10.0:
$(MAKE) -C STM32Cube_FW_F4_V1.10.0 $@
user:
$(MAKE) -C user $@
.PHONY: clean
# 总控的makefile使用$(MAKE)这个宏调用,子目录下的makefile
# 这里的意思是先进入-C之后的目录中然后执行该目录下的makefile
clean:
rm $(PROGRAM).*
将两个静态库拷贝到lib目录下面去,make clean;make 运行的结果是:
rm stm32f4_out.*
rm: cannot remove 'stm32f4_out.*': No such file or directory
makefile:34: recipe for target 'clean' failed
make: *** [clean] Error 1
arm-none-eabi-gcc -o stm32f4_out.elf -g -mcpu=cortex-m3 -mthumb -fno-exceptions -ffunction-sections -fdata-sections -L/home/raoxu/self_education/stm32_project/lib -nostartfiles -Wl,--gc-sections,-TSTM32F407VGTx_FLASH.ld \
-Wl,--whole-archive \
user/libapp.a \
-Wl,--no-whole-archive \
-lstm32 -lapp
arm-none-eabi-objcopy -O ihex stm32f4_out.elf stm32f4_out.hex
arm-none-eabi-objcopy -O binary stm32f4_out.elf stm32f4_out.bin
#Extract info contained in ELF to readable text-files:
arm-none-eabi-readelf -a stm32f4_out.elf > stm32f4_out.info_elf
arm-none-eabi-size -d -B -t stm32f4_out.elf > stm32f4_out.info_size
arm-none-eabi-objdump -S stm32f4_out.elf > stm32f4_out.info_code
arm-none-eabi-nm -t d -S --size-sort -s stm32f4_out.elf > stm32f4_out.info_symbol
这样就算成功了,elf文件和bin文件都有了.但是过程比较麻烦,之后我会写个脚本,简化工作.接下来搭建,下载调试的环境
1.安装libusb
sudo apt-get install libusb-dev
使用源码安装:
地址:
解压之后:
./configure
make
sudo make install
安装openocd
使用命令安装就可以了
sudo apt-get install openocd
telnet localhost 4444
下载程序
reset halt
flash probe 0
stm32f4x mass_erase 0
flash write_bank 0 /home/raoxu/self_education/stm32_project/stm32f4_out.elf 0
reset run
结果如下
➜ ~ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> reset halt
Unable to match requested speed 2000 kHz, using 1800 kHz
Unable to match requested speed 2000 kHz, using 1800 kHz
adapter speed: 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08002068 msp: 0x2001fffc
> flash probe 0
device id = 0x10076413
flash size = 1024kbytes
flash 'stm32f2x' found at 0x08000000
> stm32f4x mass_erase 0
stm32x mass erase complete
> flash write_bank 0 /home/raoxu/self_education/stm32_project/stm32f4_out.elf 0
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000046 msp: 0x2001fffc
wrote 171784 bytes from file /home/raoxu/self_education/stm32_project/stm32f4_out.elf to flash bank 0 at offset 0x00000000 in 1.898081s (88.383 KiB/s)
> reset run
Unable to match requested speed 2000 kHz, using 1800 kHz
Unable to match requested speed 2000 kHz, using 1800 kHz
adapter speed: 1800 kHz
>
上面就是下载成功的注意下载好之后,断电重启,程序就可以正常跑了.
在需要调试的工程下加上.gdbinit文件,内容很简单
target remote localhost:3333
monitor reset
monitor halt
load
然后
arm-none-eabi-gdb stm32f4_out.elf
source .gdbinit
b main
c
具体调试结果如下
➜ stm32_project git:(master) ✗ arm-none-eabi-gdb stm32f4_out.elf
GNU gdb (GNU Tools for ARM Embedded Processors) 7.10.1.20160923-cvs
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from stm32f4_out.elf...done.
warning: File "/home/raoxu/self_education/stm32_project/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
add-auto-load-safe-path /home/raoxu/self_education/stm32_project/.gdbinit
line to your configuration file "/home/raoxu/.gdbinit".
To completely disable this security protection add
set auto-load safe-path /
line to your configuration file "/home/raoxu/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual. E.g., run from the shell:
info "(gdb)Auto-loading safe path"
(gdb) source .gdbinit
0x00000000 in ?? ()
Unable to match requested speed 2000 kHz, using 1800 kHz
Unable to match requested speed 2000 kHz, using 1800 kHz
adapter speed: 1800 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x080012c4 msp: 0x2001ffbc
Loading section .isr_vector, size 0x188 lma 0x8000000
Loading section .text, size 0x1f30 lma 0x8000188
Loading section .rodata, size 0x10 lma 0x80020b8
Loading section .data, size 0x14 lma 0x80020c8
Start address 0x8002068, load size 8412
Transfer rate: 14 KB/sec, 2103 bytes/write.
(gdb) b main
Breakpoint 1 at 0x800018e: file ./main.c, line 77.
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.
Breakpoint 1, main () at ./main.c:77
77 HAL_Init();
(gdb) n
81 SystemClock_Config();
(gdb)
86 __GPIOF_CLK_ENABLE();
(gdb)
87 __GPIOE_CLK_ENABLE();
(gdb)
90 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
(gdb)