0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux下開發(fā)STM32 使用gcc-arm-none-eabi工具鏈編譯生成bin、hex文件

黃工的嵌入式技術(shù)圈 ? 來源:黃工的嵌入式技術(shù)圈 ? 作者:黃工的嵌入式技術(shù) ? 2020-02-28 15:08 ? 次閱讀

1.為什么不是gcc

在開發(fā)stm32的時候,編譯工具鏈要使用gcc-arm-none-eabi,為什么不是gcc呢?這就要說到linux下的交叉編譯了,因為我們要在PC機上編譯出可以運行在ARM上的程序,使用gcc編譯出的是在PC上運行的程序,所以我們要使用gcc-arm-none-eabi進行交叉編譯~

2.gcc-arm-none-eabi toolchain 介紹及安裝

gcc-arm-none-eabi是一個開源的ARM開發(fā)工具鏈,適用于Arm Cortex-M和Coretex-A系列處理器,包括GNU編譯器(GCC),以及GDB,可用于Windows,Linux,MacOS上的交叉編譯。
gcc-arm-none-eabi在ubuntu軟件源倉庫中就有,但是版本比較陳舊:

在此我們從[ARM官方下載鏈接](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads)選擇合適的版本下載(這里我選擇Linux64):

解壓下來是tar.ba2格式包,使用命令tar -jxf <要解壓的文件>解壓到我們要安裝的目錄:

為了以后使用方便,將文件夾重命名:

它下面的bin目錄就是我們要使用的編譯工具鏈:

share目錄的doc下包含了大量的使用幫助文檔,可以先略讀一二,特別是readme.txt:

接下來我們要將bin目錄添加到環(huán)境變量,這樣可以直接在命令行輸入要使用的工具名,然后系統(tǒng)就可以找到該工具,在此我們僅為當前用戶添加環(huán)境變量,使用vim ~/.bashrc編輯當前用戶配置文件,在最后添加export PATH=$PATH:/home/mculover666/gcc-arm-none-eabi/bin:

然后使用命令source ~/.bashrc更新系統(tǒng)路徑,使添加的環(huán)境變量立即生效:

然后輸入命令arm-none,然后按三下Tab(一定不要輸入全部),檢查系統(tǒng)是否可以自動補全:

如果系統(tǒng)可以提示,說明環(huán)境變量配置成功,可以開心的使用arm-none-eabi工具鏈啦~

3.從裸機工程開始

3.1.硬件說明

這里我使用的是野火霸道開發(fā)板,板載芯片為STM32F103ZET6,下載器使用e-link,這個下載器使用CMSIS-DAP下載程序,同時并帶有一個串口,非常好用~

板載RGB-LED的原理圖如圖所示:

3.2.新建空的裸機工程

首先新建一個文件夾mkdir 00-template-reg用來存放整個工程,然后整個工程包含三個文件:

startup_stm32f10x_hd.s:從固件庫中拷貝,注意不是arm文件夾下的,因為truestudio使用的是gcc編譯器,所以我們選擇truestudio文件夾下的啟動文件;

stm32f10x.h:空文件;

main.c:代碼如下:

#include"stm32f10x.h" intmain() { /*開啟GPIOB時鐘*/ *(unsignedint*)(0x40021000+0x18)|=1<<3; ????/*?配置PB0為推挽輸出?*/ ????*(unsigned?int*)(0x40010c00+0x00)?|=?1<<(4*0); ????/*?PB0輸出低電平,點亮綠色LED?*/ ????*(unsigned?int*)(0x40010c00+0x0c)?&=?~(1<<0); ????while(1); } void?SystemInit(void) { }

4.編譯

接下來就是激動人心的編譯步驟了~編譯的時候有兩種文件,一種是匯編啟動文件,一種是c源文件,接下來分別編譯:
首先需要說明一些編譯任何一個文件都需要帶上的參數(shù)

參數(shù) 說明
-mthumb 表明使用的指令集(必需)
-mcpu=cortex-m3 表明芯片內(nèi)核(必需)
-g 產(chǎn)生調(diào)試信息

4.1.啟動文件編譯

啟動文件一般是由匯編寫成,此處需要注意的是,匯編文件的格式有.S和.s之分:

大寫S:表明文件中含有預處理指令(比如#define),需要先進行處理;

小寫s:表明文件不需要處理,可以直接編譯;

之前我們添加的啟動文件是小寫.s,所以直接進行編譯,另外說一下,如果使用的是.S文件,那么需要帶上-x assembler-with-cpp參數(shù)。

接下來說明一些匯編文件gcc編譯器使用的參數(shù):

參數(shù) 說明
-x assembler-with-cpp 先對文件進行預處理
-Wa,option 向匯編器Assembler傳遞參數(shù)

注:可以向匯編器傳遞的參數(shù):

參數(shù) 說明
-W或--no-warn 關(guān)閉所有告警
--fatal-warnings 將所有的警告提示為錯誤
--warn 正常提示告警信息

所以,接下來我們可以使用如下的參數(shù)組合來編譯啟動文件(不進行預處理,并且正常提示告警信息):

arm-none-eabi-gcc-c-mthumb-mcpu=cortex-m3-g-Wa,--warn-ostartup_stm32f10x_hd.ostartup_stm32f10x_hd.s

4.2.C文件編譯

因為main.c中沒有特殊的東西,只是兩個函數(shù),所以簡單的編譯一下就可以了:

參數(shù) 描述
-Wall 允許輸出所有警告

arm-none-eabi-gcc-c-mthumb-mcpu=cortex-m3-g-Wall-omain.omain.c

5.鏈接

鏈接重要的部分有兩點:鏈接文件和傳遞給鏈接器的參數(shù)。
鏈接文件在固件庫中給的示例工程中有,在下面這個目錄:


其中stm32_flash.ld是針對于STM32F103ZE的鏈接文件,如果是別的芯片,需要進行修改,將它復制到我們的工程中去:


然后就要讓鏈接器開始根據(jù)stm32_flash.ld這個文件對startup_stm32f10x_hd.o和main.o這兩個文件開始鏈接,生成包含了調(diào)試信息的elf文件,同時,我們還需要給鏈接器傳遞一些參數(shù):

參數(shù) 描述
-T 指定鏈接文件

arm-none-eabi-gcc-otest.elfmain.ostartup_stm32f10x_hd.o-mthumb-mcpu=cortex-m3-Tstm32_flash.ld-specs=nosys.specs-static-Wl,-cref,-u,Reset_Handler-Wl,-Map=test.map-Wl,--gc-sections-Wl,--defsym=malloc_getpagesize_P=0x80-Wl,--start-group-lc-lm-Wl,--end-group

6.生成bin文件和hex文件

利用arm-none-eabi-objcopy工具可以將elf文件轉(zhuǎn)化為適合于單片機的bin文件和hex文件,其中參數(shù)-O(大寫o)用于指定輸出文件的格式(默認是bin格式)

arm-none-eabi-objcopytest.elftest.bin arm-none-eabi-objcopytest.elf-Oihextest.hex

7.編寫一個makefile雛形

TARGET=test CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy RM=rm-f CORE=3 CPUFLAGS=-mthumb-mcpu=cortex-m$(CORE) LDFLAGS=-Tstm32_flash.ld-Wl,-cref,-u,Reset_Handler-Wl,-Map=$(TARGET).map-Wl,--gc-sections-Wl,--defsym=malloc_getpagesize_P=0x80-Wl,--start-group-lc-lm-Wl,--end-group CFLAGS=-g-o $(TARGET):startup_stm32f10x_hd.omain.o $(CC)$^$(CPUFLAGS)$(LDFLAGS)$(CFLAGS)$(TARGET).elf startup_stm32f10x_hd.o:startup_stm32f10x_hd.s $(CC)-c$^$(CPUFLAGS)$(CFLAGS)$@ main.o:main.c $(CC)-c$^$(CPUFLAGS)$(CFLAGS)$@ bin: $(OBJCOPY)$(TARGET).elf$(TARGET).bin hex: $(OBJCOPY)$(TARGET).elf-Oihex$(TARGET).hex clean: $(RM)*.o$(TARGET).*

使用命令make編譯生成elf文件;

使用命令make bin將elf文件轉(zhuǎn)化生成bin文件;

使用命令make hex將elf文件轉(zhuǎn)化生成hex文件;

使用命令make clean即可清除掉所有編譯產(chǎn)生的文件。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11304

    瀏覽量

    209521
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10900

    瀏覽量

    356046
收藏 人收藏

    評論

    相關(guān)推薦

    stm32cubmx生成的makefile編譯無法啟動線程怎么解決?

    f103vct6 的 make編譯環(huán)境是 windows + gcc-arm-none-eabi-10.3-2021.10-win32 + xpack-windows-build-tools-4.4.1-2-win32-x64 有沒有人遇到同樣的問題,求解,謝謝!
    發(fā)表于 09-27 09:27

    使用vscode始終無法找到頭文件怎么解決?

    為“windows-gcc-arm”:“D:/env-windows/tools/gnu_gcc/arm_gcc/mingw/bin/arm-non
    發(fā)表于 09-27 06:33

    【米爾NXP i.MX 93開發(fā)板試用評測】2、異構(gòu)通信環(huán)境搭建和源碼編譯

    build_all.sh和clean_all.sh兩個腳本添加運行權(quán)限,然后設(shè)置編譯器環(huán)境變量 export ARMGCC_DIR=\"/mnt/MyNAS/walker/.bin/tools/gcc-arm-none-eabi
    發(fā)表于 09-20 23:19

    【飛凌嵌入式OK3576-C開發(fā)板體驗】應(yīng)用編譯運行

    源碼需要下載的庫文件編譯前準備 環(huán)境說明 開發(fā)環(huán)境操作系統(tǒng):Ubuntu24.04 64 位版 交叉工具:aarch64-non-
    發(fā)表于 08-26 17:55

    openharmony移植AT32F407編譯時錯誤

    /gcc-arm-none-eabi-10-2020-q4-major-master/bin/../lib/gcc/arm-none-eabi/12.3.1/../../../../
    發(fā)表于 08-18 17:04

    百問網(wǎng)全志T113-PRO LVGL環(huán)境配置

    。 進入gcc工具文件目錄的bin目錄中查看交叉編譯工具
    發(fā)表于 08-01 10:11

    在ubuntu 24.04嘗試使用riscv64-linux-musleabi_for_x86_64-pc-linux-gnu工具編譯cv1800大核出現(xiàn)報錯的原因?

    在ubuntu 24.04嘗試使用riscv64-linux-musleabi_for_x86_64-pc-linux-gnu工具編譯c
    發(fā)表于 07-16 08:20

    X-CUBE-CRYPTOLIB V4庫文件無法添加,鏈接錯誤的原因?

    Toolchain 13.2.rel1 (Build arm-13.7)),但是編譯工程的時候提示鏈接錯誤 opt/gcc-arm-none-eabi/bin/../lib/
    發(fā)表于 05-31 07:54

    在全志V851SE開發(fā)板TinyVision上 使用 SyterKit 啟動 Linux 6.7 主線內(nèi)核

    零構(gòu)建 SyterKit 構(gòu)建 SyterKit 非常簡單,只需要在 Linux 操作系統(tǒng)中安裝配置環(huán)境即可編譯。SyterKit 需要的軟件包有: gcc-arm-none-eabi CMake
    發(fā)表于 05-20 09:35

    STM32CubeMX如何在*.c源文件中使用c++特性?

    開發(fā)環(huán)境:Visual Studio 2015 + VisualGDB (編譯器為arm-eabi GCC 7.2.0)+ STM32Cub
    發(fā)表于 04-25 06:15

    使用RT-Thread studio編譯Vision-Board例程后報錯的原因?

    /2.12-20190422-1053/bin/sh: arm-none-eabi-gcc: not found d:/software/work/rt-threadstudio/platform
    發(fā)表于 03-26 08:15

    Eclipse環(huán)境STM32工程編譯報錯undefined references to `assert_failed\'的原因?

    2020-q2-update/bin/../lib/gcc/arm-none-eabi/9.3.1/../../../../arm-none-eabi/
    發(fā)表于 03-20 07:51

    怎么在NanoEdge AI Studio設(shè)定交叉編譯器呢?

    20231009\", 那么問題來了,怎么在NanoEdge AI Studio設(shè)定交叉編譯器呢,比如設(shè)置為armcc、armclang、iccram,因為我需要將庫加到keil或者iar工程里面。 看樣子這個軟件生成的庫是arm-g
    發(fā)表于 03-07 06:28

    鴻蒙輕內(nèi)核源碼分析:Newlib C

    功能,通過加上 - nostdinc 與 - nostdlib 強制使用我們自己改造后的 musl-C。 社區(qū)及三方廠商開發(fā)多使用公版工具 arm-none-eabi-gcc 加上私
    的頭像 發(fā)表于 02-18 15:41 ?715次閱讀
    鴻蒙輕內(nèi)核源碼分析:Newlib C

    全志R128 SDK架構(gòu)與目錄結(jié)構(gòu)

    /lichee/rtos/tools/gcc-arm-none-eabi-8-2019-q3-update/bin/../lib/gcc/arm-none-eabi/8.3.1
    發(fā)表于 01-05 10:05