日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

esp8266 SDK开发之编译流程

發(fā)布時間:2025/4/5 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 esp8266 SDK开发之编译流程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近剛完成自己8266的小項目,已經(jīng)發(fā)布在github上,有興趣的朋友可以看一下

github地址:esp-ujn

1. 通過MQTT協(xié)議與服務器交互

2. 內(nèi)置HTTP服務器,支持通過瀏覽器進行參數(shù)配置

編譯流程分析


我們在編譯8266代碼時可以使用項目中的gen_misc.sh(Windows下為gen_misc.bat)腳本,選擇合適的參數(shù)后就會在sdk/bin/文件夾中生成可燒錄的文件,如eagle.flash.bineagle.irom0text.bin。 但這樣存在的問題是每次編譯時都需要選擇一遍編譯參數(shù),所以一般會使用make命令進行編譯,如:

make COMPILE=gcc BOOT=none APP=0 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=4

這是因為gen_misc.sh的作用僅僅是供用戶選擇編譯參數(shù),最終的編譯過程是通過make命令依據(jù)Makefile文件中定義的若干規(guī)則來進行的。接下來通過如下幾個方面來探討整個編譯流程

  • Makefile的組織形式
  • 燒錄文件的生成過程
  • Makefile的執(zhí)行過程
  • 一、Makefile的組織形式

    SDK中Makefile文件以樹形結構組織。總體上分為3類:主文件,項目配置文件,庫配置文件。

    |--sdk/ |----Makefile |----project/ |------Makefile |------user/ |--------Makefile |------json/ |--------Makefile

    如上圖所示

    • sdk/Makefile 主文件
    • sdk/project/Makefile 項目配置文件
    • sdk/project/json/Makefile?庫配置文件

    平常開發(fā)過程中,一般我們只需要關注項目配置文件與庫配置文件即可。如有時為了程序的模塊化,需要將不同的功能模塊編譯成獨立的庫。這時需要修改項目配置文件,并創(chuàng)建對應的庫配置文件。例如我們需要添加一個json庫。這時就需要:

  • sdk/project/下創(chuàng)建文件夾sdk/project/json/
  • sdl/project/user/Makefile拷貝到sdk/project/json/
  • 修改sdk/project/json/Makefile
  • 修改sdk/project/Makefile
  • 需要在兩個Makefile中做出的改動如下:

    #sdk/project/json/Makefile GEN_LIBS = libjson.a #庫名#sdk/project/Makefile SUBDIRS = user \json #庫目錄 COMPONENTS_eagle.app.v6 = user/libuser.a \json/libjson.a #庫路徑

    二、燒錄文件的生成過程

    對于Non-FOTA模式,編譯完成后會在sdk/bin/目錄下生成eagle.flash.bineagle.irom0text.bin。顯然這兩個文件并不是編譯器的直接產(chǎn)物,一般來說編譯器會通過我們的代碼生成一個可執(zhí)行程序。那么這兩個文件是從何而來的呢?實際上這兩個文件是編譯后生成的可執(zhí)行文件的一部分。可執(zhí)行文件被拆解成了多個部分,然后拼湊出了這兩個文件供我們燒錄。我們的代碼經(jīng)過編譯后會生成一個elf文件,它的路徑在sdk/project/.output/eagle/debug/image/eagle.app.v6.out。這個一個標準的elf文件,可以使用readelf命令查看它的一些信息。

    #readelf -h ELF 頭:Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 類別: ELF32數(shù)據(jù): 2 補碼,小端序 (little endian)版本: 1 (current)OS/ABI: UNIX - System VABI 版本: 0類型: EXEC (可執(zhí)行文件)系統(tǒng)架構: Tensilica Xtensa Processor版本: 0x1入口點地址: 0x40100004程序頭起點: 52 (bytes into file)Start of section headers: 549292 (bytes into file)標志: 0x300本頭的大小: 52 (字節(jié))程序頭大小: 32 (字節(jié))Number of program headers: 5節(jié)頭大小: 40 (字節(jié))節(jié)頭數(shù)量: 19字符串表索引節(jié)頭: 16#readelf -S 共有 19 個節(jié)頭,從偏移量 0x861ac 開始: 節(jié)頭: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al[ 0] NULL 00000000 000000 000000 00 0 0 0[ 1] .data PROGBITS 3ffe8000 0000e0 000804 00 WA 0 0 16[ 2] .rodata PROGBITS 3ffe8810 0008f0 0015d0 00 A 0 0 16[ 3] .bss NOBITS 3ffe9de0 001ec0 006f18 00 WA 0 0 16[ 4] .irom0.text PROGBITS 40210000 0092c0 038b44 00 AX 0 0 16[ 5] .text PROGBITS 40100000 001ec0 0073fc 00 AX 0 0 4[ 6] .xtensa.info NOTE 00000000 041e04 000038 00 0 0 1[ 7] .comment PROGBITS 00000000 041e3c 001bbd 00 0 0 1[ 8] .debug_frame PROGBITS 00000000 0439fc 00211c 00 0 0 4[ 9] .debug_info PROGBITS 00000000 045b18 014bec 00 0 0 1[10] .debug_abbrev PROGBITS 00000000 05a704 003f8a 00 0 0 1

    將可執(zhí)行文件eagle.app.v6.out轉變?yōu)榭蔁浳募倪^程定義在sdk/Makefile,也就是在主文件中。大體流程如下:

    #將.text、.data、.rodata和.irom0.text節(jié)的數(shù)據(jù)轉存到文件 objcopy --only-section .text -O binary eagle.app.v6.out eagle.app.v6.text.bin objcopy --only-section .data -O binary eagle.app.v6.out eagle.app.v6.data.bin objcopy --only-section .rodata -O binary eagle.app.v6.out eagle.app.v6.rodata.bin objcopy --only-section .irom0.text -O binary eagle.app.v6.out eagle.app.v6.irom0text.bin #通過eagle.app.v6.text.bin、eagle.app.v6.data.bin和eagle.app.v6.rodata.bin生成eagle.app.flash.bin python sdk/tools/gen_appbin.py eagle.app.v6.text.bin eagle.app.v6.data.bin eagle.app.v6.rodata.bin #將最后生成的可燒錄文件放到sdk/bin/目錄下 mv eagle.app.flash.bin sdk/bin/eagle.flash.bin mv eagle.app.v6.irom0text.bin sdk/bin/eagle.irom0text.bin

    通過上邊readelf -S獲取到的節(jié)區(qū)表信息可以看到,實際在內(nèi)存中出現(xiàn)的節(jié)只有.text.data.bss.rodata.irom0.text

    .text + .data + .rodata? =>?eagle.flash.bin

    .irom0.text?=> eagle.irom0text.bin

    通過比較這幾個節(jié)的大小與燒錄文件大小的關系可以得到相同的結果(eagle.flash.bin文件中除了包含程序節(jié)數(shù)據(jù),還有少量的配置數(shù)據(jù))。.bss節(jié)雖然在內(nèi)存中出現(xiàn)但是在程序初始化時會被整個清零,所以不必出現(xiàn)在燒錄文件中。這幾個節(jié)包含的數(shù)據(jù)內(nèi)容如下:

    節(jié)名作用
    .text存放代碼
    .data存放已初始化的全局變量
    .bss存放未初始化的全局變量
    .rodata存放只讀數(shù)據(jù)
    .irom0.text存放標注有ICACHE_FLASH_ATTR的代碼或ICACHE_RODATA_ATTR的變量

    三、Makefile的執(zhí)行過程

    在前邊已經(jīng)提到,我們寫的代碼最終會編譯為一個elf格式的可執(zhí)行文件(eagle.app.v6.out),接下我們通過具體Makefile文件中的代碼對整個編譯的執(zhí)行過程進行分析。之前講到sdk/Makefile為主文件,也就是所有編譯時用到的邏輯都在其中定義。我們整個的編譯流程中需要按順序產(chǎn)生如下幾類目標:二進制目標文件、庫文件、elf文件、燒錄文件。那么如何通過一個主Makefile來完成這些工作呢,這里需要先看一下其余兩類起配置作用的Makefile。這兩類Makefile的最后都會有如下代碼:

    PDIR := ../$(PDIR) sinclude $(PDIR)Makefile

    它的作用是包含自己父文件夾中的Makefile文件,那么最后主Makefile文件中的內(nèi)容會被包含到庫配置文件與項目配置文件中。在項目配置文件中,它的作用是產(chǎn)生elf可執(zhí)行文件與燒錄文件,在庫配置文件中,它的作用是產(chǎn)生靜態(tài)鏈接庫。主Makefile中,最主要的顯式規(guī)則如下,通過這兩條規(guī)則產(chǎn)生了所有我們需要的文件。

    ...
    314
    all: .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
    ...
    324 .subdirs: 325 @set -e; $(foreach d, $(SUBDIRS), $(MAKE) -C $(d);)

    這兩條規(guī)則的目標都是偽目標,并不會產(chǎn)生任何文件,我們所需要的所有文件都是目標all的依賴文件。

    $(OBJS)二進制目標文件
    $(OLIBS)靜態(tài)鏈接庫
    $(OIMAGES)elf可執(zhí)行文件
    $(OBINS)燒錄文件
    $(SPECIAL_MKTARGETS)一直為空

    第一個依賴文件.subdirs是一個偽目標,也就是每次編譯時都會先執(zhí)行.subdirs中定義的操作,也就是遍歷所有含Makefile文件的子文件夾,執(zhí)行make命令。通過這種方式產(chǎn)生的結果就是make工具的當前路徑發(fā)生了改變。拿上邊列出的項目結構為例,我們一次編譯過程可分為

  • 我們在sdk/project/文件夾下執(zhí)行make命令編譯源碼
  • sdk/project/Makefile包含sdk/Makefile的內(nèi)容
  • 構建目標all
  • 依賴文件.subdirs不存在,進行構建
  • 遍歷sdk/project/下所有含Makefile文件的子文件并執(zhí)行make命令
  • 這時如果執(zhí)行了sdk/project/json/Makefile,那么此時make工具的當前路徑變?yōu)榱?span style="margin:0px;padding:0px;">sdk/project/json/。此時sdk/project/json/Makefile對上層Makefile進行包含后再次構建目標all。一般來說sdk/project/json/中不會再有包含Makefile的子文件夾,那么此時目標all的第一個依賴項.subdirs會立刻返回,然后再對其余的依賴項進行構建。

    還有一點需要說明的是目標all的依賴項并不是全都有值的,比如$(SPECIAL_MKTARGETS)的值就一直為空,表示不存在此依賴項。繼續(xù)拿上邊的項目結構舉例:

    make當前路徑$(OBJS)$(OLIBS)$(OIMAGES)$(OBINS)
    sdk/project/eagle.app.v6.outeagle.app.v6.bin
    sdk/project/json/json.olibjson.a

    根據(jù)make當前路徑的不同,目標all有不同的依賴項,然后再根據(jù)主Makefile中定義隱式規(guī)則對依賴項進行構建,即完成了整個項目的構建過程。

    ?


    有的朋友可能對Makefile的語法不熟悉,這里推薦一個網(wǎng)站

    https://www.gnu.org/s/make/manual/make.html

    官方的教程很詳細

    總結

    以上是生活随笔為你收集整理的esp8266 SDK开发之编译流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。