文章轉自:https://zhuanlan.zhihu.com/p/26292456
如有侵權,請聯繫刪除
/*
操作系統:Ubuntu16.04
硬件平臺:原子Stm32F767+7‘RGB屏幕
其他操作系統與開發板搭建環境基本差不多,注意的地方我會提到的。
工程Github
*/
一、軟件安裝
l VSCode
爲什麼用VSCode,相信大家都知道,沒用過的同學下載下來用用。(推薦)
這個軟件不管是什麼系統都有,安裝比較簡單,不再贅述。
詳情和下載請點擊:Visual Studio Code - Code Editing. Redefined
貼一張VSCode的圖
資源管理器+和vs studio一樣的代碼高亮+集成終端
l Arm-none-eabi-gcc
下載鏈接:GNU ARM Embedded Toolchain
Windows下安裝傻瓜式的就不說了。
下面說下Ubuntu下安裝方法:
1> 解壓gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2
$ tar -xvf gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2
2> 將解壓得得文件夾複製到/usr/bin
$ sudo cp -r gcc-arm-none-eabi-5_4-2016q3 /usr/bin
3> 添加環境變量
$ vim /etc/profile
添加:
export PATH=/usr/bin/gcc-arm-none-eabi-5_4-2016q3/bin:$PATH
4> 使環境變量生效
$ source /etc/profile
$ reboot
5>測試
$ arm-none-eabi-gcc -v
出現如下信息說明成功
二、建立工程
就拿我的F7來說,我用的是最新的V1.6的HAL庫
大體跟之前差不多,添加了些LL庫的文件
其實呢,這麼多LL庫的文件並不是所有都用得到,參考官方的模板例程,也就使用了3個如圖:
參考官方模板我們建立自己的工程結構
大體是這樣的一個結構,大家可以根據自己的想法構建。 要注意的就是一下幾點
啓動文件:用GCC編譯所需的啓動文件跟再MDK編譯的啓動文件是不同的具體在Cube庫的這裏
裏面就是常用開發環境用的啓動文件。
然後就是就是一些CMSIS標準所需的頭文件
根據自己板子的型號可以刪除一些不必要的文件。
其中cmsis_gcc.h是用gcc編譯所需的頭文件。
工程目錄到這一步就差不多了。
三、編寫Makfile
首先在HAL庫文件下新建一個Makfile,爲的就是將HAL庫編譯成一個靜態的lib.
代碼如下
CC=arm-none-eabi-gcc
AR=arm-none-eabi-ar
###########################################
vpath %.c Src
CFLAGS = -g -O2 -Wall
CFLAGS += -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16
CFLAGS += -mlittle-endian -mthumb-interwork
CFLAGS += -ffreestanding -nostdlib
CFLAGS += -IInc -I../INC -IInc/Legacy -I../STM32F767
CFLAGS += -DSTM32F767xx -DUSE_HAL_DRIVER
SRCS = $(wildcard Src/*.c)
OBJS = $(SRCS:.c=.o)
.PHONY: libstm32f7.a
all: libstm32f7.a
%.o : %.c
$(CC) $^ $(CFLAGS) -c -o $@
libstm32f7.a: $(OBJS)
$(AR) -r $@ $(OBJS)
clean:
rm -f $(OBJS) libstm32f7.a
這個Makfile相對簡單,值得注意的是CFLAGS中的幾個編譯選項,device有關的可以查看圖中的readme.txt
其中一個預處理選項即CFLAGS += -DSTM32F767xx -DUSE_HAL_DRIVER -D選項表示預定義,爲什麼添加這兩個?
很熟悉不是?其實這些最根源的是由於
然後再工程根目錄新建一個頂層的Makefile。代碼如下:
PROJ_NAME = main
CC=arm-none-eabi-gcc
OBJCOPY=arm-none-eabi-objcopy
CFLAGS = -g -O2 -Wall -TSTM32F767ZITx_FLASH.ld
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m7 -mthumb-interwork
CFLAGS += -mfloat-abi=hard -mfpu=fpv5-d16
CFLAGS += --specs=nosys.specs
LFLAGS += --specs=nosys.specs
SRCS = stm32f7xx_it.c system_stm32f7xx.c stm32f7xx_hal_msp.c sys.c usart.c delay.c ltdc.c sdram.c tftlcd.c main.c
vpath %.c USER SYSTEM/usart SYSTEM/delay SYSTEM/sys LCD STM32F767
vpath %.a HAL
ROOT=$(shell pwd)
CFLAGS += -ILCD -ISYSTEM/sys -ISYSTEM/usart -ISYSTEM/delay -IUSER
CFLAGS += -IHAL/Inc -IHAL/Inc/Legacy -IINC -ISTM32F767
CFLAGS += -DSTM32F767xx
SRCS += STM32F767/gcc/startup_stm32f767xx.s
OBJS = $(SRCS:.c=.o)
.PHONY: lib proj
all: lib proj
lib:
$(MAKE) -C HAL
proj: $(PROJ_NAME).elf
$(PROJ_NAME).elf: $(SRCS)
$(CC) $(CFLAGS) $^ -o $@ -LHAL -lstm32f7
$(OBJCOPY) -O ihex -S $(PROJ_NAME).elf $(PROJ_NAME).hex
$(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin
clean:
$(MAKE) -C HAL clean
rm -f $(PROJ_NAME).elf
rm -f $(PROJ_NAME).hex
rm -f $(PROJ_NAME).bin
這裏需要注意的幾點是 -TSTM32F767ZITx_FLASH.ld 這是來加載linkerscript文件的。
後面會說到Linkerscript文件怎麼寫。
還有就是關於這個選項--specs=nosys.specs,它是關於使用重定向要用的選項具體還是看之前那個readme.txt,在Github中的GNU_DOC目錄中
到這兒Makefile差不多介紹完了,Makefile就是起統籌的作用。如圖所示:
四、Linkerscript介紹
代碼如下:
/* Generated by LinkerScriptGenerator [http://visualgdb.com/tools/LinkerScriptGenerator]
* Target: STM32F767IG
* The file is provided under the BSD license.
*/
ENTRY(Reset_Handler)
MEMORY
{
FLASH (RX) : ORIGIN = 0x08000000, LENGTH = 1M
SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 512K
ITCMRAM (RWX) : ORIGIN = 0x00000000, LENGTH = 16K
/* --- begin generated external memories -- */
SDRAM (RWX) : ORIGIN = 0xc0000000, LENGTH = 32M
/* --- end generated external memories -- */
}
_estack = 0x20080000;
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} > FLASH
.text :
{
. = ALIGN(4);
_stext = .;
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
_etext = .;
} > FLASH
.ARM.extab :
{
. = ALIGN(4);
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
. = ALIGN(4);
} > FLASH
.exidx :
{
. = ALIGN(4);
PROVIDE(__exidx_start = .);
*(.ARM.exidx*)
. = ALIGN(4);
PROVIDE(__exidx_end = .);
} > FLASH
.ARM.attributes :
{
*(.ARM.attributes)
} > FLASH
.preinit_array :
{
PROVIDE(__preinit_array_start = .);
KEEP(*(.preinit_array*))
PROVIDE(__preinit_array_end = .);
} > FLASH
.init_array :
{
PROVIDE(__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array*))
PROVIDE(__init_array_end = .);
} > FLASH
.fini_array :
{
PROVIDE(__fini_array_start = .);
KEEP(*(.fini_array*))
KEEP(*(SORT(.fini_array.*)))
PROVIDE(__fini_array_end = .);
} > FLASH
. = ALIGN(4);
_sidata = .;
.data : AT(_sidata)
{
. = ALIGN(4);
_sdata = .;
PROVIDE(__data_start__ = _sdata);
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
PROVIDE(__data_end__ = _edata);
} > SRAM
.bss :
{
. = ALIGN(4);
_sbss = .;
PROVIDE(__bss_start__ = _sbss);
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
PROVIDE(__bss_end__ = _ebss);
} > SRAM
/* --- begin generated external memory sections -- */
. = _sidata + SIZEOF(.data);
. = ALIGN(4);
_sisdram_text = .;
.sdram_text : AT(_sisdram_text)
{
. = ALIGN(4);
_ssdram_text = .;
PROVIDE(__sdram_text_start = _ssdram_text);
*(.sdram_text)
*(.sdram_text*)
. = ALIGN(4);
_esdram_text = .;
PROVIDE(__sdram_text_end = _esdram_text);
} > SDRAM
. = _sisdram_text + SIZEOF(.sdram_text);
. = ALIGN(4);
_sisdram_data = .;
.sdram_data : AT(_sisdram_data)
{
. = ALIGN(4);
_ssdram_data = .;
PROVIDE(__sdram_data_start = _ssdram_data);
*(.sdram_data)
*(.sdram_data*)
. = ALIGN(4);
_esdram_data = .;
PROVIDE(__sdram_data_end = _esdram_data);
} > SDRAM
.sdram_bss (NOLOAD) :
{
. = ALIGN(4);
_ssdram_bss = .;
PROVIDE(__sdram_bss_start = _ssdram_bss);
*(.sdram_bss)
*(.sdram_bss*)
. = ALIGN(4);
_esdram_bss = .;
PROVIDE(__sdram_bss_end = _esdram_bss);
} > SDRAM
/* --- end generated external memory sections -- */
PROVIDE(end = .);
.heap (NOLOAD) :
{
. = ALIGN(4);
PROVIDE(__heap_start__ = .);
KEEP(*(.heap))
. = ALIGN(4);
PROVIDE(__heap_end__ = .);
} > SRAM
.reserved_for_stack (NOLOAD) :
{
. = ALIGN(4);
PROVIDE(__reserved_for_stack_start__ = .);
KEEP(*(.reserved_for_stack))
. = ALIGN(4);
PROVIDE(__reserved_for_stack_end__ = .);
} > SRAM
}
關於官方的linkerscript在這裏:
我這個Linker script只是在官方的基礎添加對SDRAM的支持。
爲什麼呢,因爲要使用RGB屏
一下子定義了這麼大的數組,顯然RAM是放不下的,只有放在SDRAM中了,圖中被註釋的部分是在MDK Keil的用法。
當然在ubuntu下裝上st-link驅動或其他的再加上debug server進行調試也是沒有問題的,我還沒有嘗試,先就寫到這兒了。