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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【ESP8266】ESP8266_NONOS_SDK开发包生成的镜像文件构建步骤分析

發(fā)布時(shí)間:2025/3/21 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【ESP8266】ESP8266_NONOS_SDK开发包生成的镜像文件构建步骤分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ESP8266有官方提供的軟件開發(fā)包。下面是對該開發(fā)包ESP8266_NONOS_SDK生成的鏡像文件構(gòu)建步驟分析。


一、Flash布局

首先參考官方提供編號為2A的文檔,對于4MB(32Mbit) SPI Flash,其布局如下:


User Data區(qū)域:當(dāng)程序(flash.bin和irom0text.bin)未占滿整個(gè)空間時(shí),空閑區(qū)域均可用于存放用戶數(shù)據(jù)。
上圖irom0text.bin默認(rèn)最大為200KB;ESP8266目前程序最大支持1024 KB,因此對于4096 KB Flash,用戶可修改編譯,使其最大支持到 1024 - 256 = 768 KB。


ld文件夾的eagle.app.v6.ld文件,其中irom0_0_seg的len為設(shè)置irom0text.bin上限值。對于4096 KB Flash,此len最大可修改為0xC0000,irom0text.bin最大支持到 768 KB。



題外話:編譯官方的AT固件時(shí),如果出現(xiàn)irom0_0seg的報(bào)錯(cuò)信息,可能就是因?yàn)閕rom0_0seg的大小空間不夠,增大irom0_0seg的len就好。

二、Makefile

這里簡單分析一下主目錄里的Makefile內(nèi)容:



23~27行:

BOOT?=none

APP?=0

SPI_SPEED?=40

SPI_MODE?=QIO

SPI_SIZE_MAP?=0

說明:Makefile已經(jīng)默認(rèn)配置好了的選項(xiàng)


131行:

LD_FILE = $(LDDIR)/eagle.app.v6.ld

說明:使用的鏈接文件是\esp_iot_sdk\ld\eagle.app.v6.ld


238~240行:

@$(RM) -r ../bin/eagle.S ../bin/eagle.dump

@$(OBJDUMP) -x -s $< > ../bin/eagle.dump

@$(OBJDUMP) -S $< > ../bin/eagle.S

說明:sdk編譯過程中會(huì)先生成eagle.app.v6.out,然后dump出段信息和符號文件。下面用一小節(jié)介紹一下生成ELF文件的步驟:


生成ELF文件


從bin\eagle.dump中摘取部分有有用的信息,為了方便閱讀,轉(zhuǎn)換為表格格式。
Sections:

Idx

Name

Size

VMA

LMA

File off

Algn

0

.data

00000b34

3ffe8000

3ffe8000

000000e0

2**4

1

.rodata

00000d70

3ffe8b40

3ffe8b40

00000c20

2**4

2

.bss

00006cd0

3ffe98b0

3ffe98b0

00001990

2**4

3

.text

00006d6e

40100000

40100000

00001990

2**2

4

.irom0.text

00033230

40240000

40240000

00008700

2**4


結(jié)合ld文件的memory信息(本文第一節(jié)有圖片)可以看到

.data的LMA(Load Memory Address,裝載內(nèi)存地址)為3ffe8000,正好是dram0_0_seg的org;

.rodata的LMA為3ffe8b40,.bss是3ffe98b0,在dram0_0_seg的大小內(nèi);

.text是40100000,正好對應(yīng)iram1_0_seg;

.irom0.text是40240000,正好對應(yīng)irom0_0_seg;


因此,data、rodata、bbs段都是放到dram0_0_seg中,text段是放到iram1_0_seg中,.irom0.text段是放到irom0_0_seg中。


由于iram1_0_seg大小為0x8000,即32KB,因此,程序段(.text)不能超過32KB;同理,數(shù)據(jù)段(.data+.rodata)不能超過0x14000,即80KB


將ELF文件轉(zhuǎn)化為燒寫鏡像

下面回到對Makefile的分析。

第248到251行:

@$(OBJCOPY) --only-section .text -O binary $< eagle.app.v6.text.bin

@$(OBJCOPY) --only-section .data -O binary $< eagle.app.v6.data.bin

@$(OBJCOPY) --only-section .rodata -O binary $< eagle.app.v6.rodata.bin

@$(OBJCOPY) --only-section .irom0.text -O binary $< eagle.app.v6.irom0text.bin

說明:Makefile將以上各個(gè)section copy成單個(gè)文件。


257行:

@python ../tools/gen_appbin.py $< 0 $(mode) $(freqdiv) $(size_map) $(app)

說明:使用tools/gen_appbin.py腳本文件將eagle.app.v6.text.bin、eagle.app.v6.data.bin和eagle.app.v6.rodata.bin三個(gè)文件打包成一個(gè)eagle.app.flash.bin。


打包過程簡要


在toos/gen_appbin.py腳本文件中,需要給之各項(xiàng)參數(shù),由

@python ../tools/gen_appbin.py $< 0 $(mode) $(freqdiv) $(size_map) $(app)

這條語句可知給了什么參數(shù),源文件如下(121~126行):

elf_file = sys.argv[1]# < eagle.app.v6.out
boot_mode = sys.argv[2] # < 0
flash_mode = sys.argv[3] # < mode=0
flash_clk_div = sys.argv[4] # < freqdiv=0
flash_size_map = sys.argv[5] # < size_map=0
user_bin = sys.argv[6] # < app=0


之后使用nm -g eagle.app.v6.out產(chǎn)生eagle.app.sym文件,并在sym文件中找出section地址和入口地址。

(cmd = 'xt-nm -g ' + elf_file + ' > eagle.app.sym')


最后按照如下格式打包成eagle.app.flash.bin。(代碼略)


HEAD0 = BIN_MAGIC_FLASH
HEAD1 = 3
HEAD2 = flash_mode
HEAD3 = flash_size_map<<4 | flash_clk_div
ENTRY = entry_addr 入口地址

TEXTADDR = TEXT_ADDRESS
TEXTLEN = eagle.app.v6.text.bin的文件長度4字節(jié)對齊
TEXT = eagle.app.v6.text.bin 的數(shù)據(jù),4字節(jié)對齊,最后不對齊的補(bǔ)0

DATAADDR = data_start_addr
DATALEN = eagle.app.v6.data.bin的文件長度4字節(jié)對齊
DATA = eagle.app.v6.data.bin 的數(shù)據(jù),4字節(jié)對齊,最后不對齊的補(bǔ)0

RODATAADDR = data_start_addr
RODATALEN = eagle.app.v6.rodata.bin的文件長度4字節(jié)對齊
RODATA = eagle.app.v6.rodata.bin 的數(shù)據(jù),4字節(jié)對齊,最后不對齊的補(bǔ)0

ALIGMENT = 對齊數(shù)據(jù),保證sum前的數(shù)據(jù)16字節(jié)對齊,不對齊這里補(bǔ)0

CHKSUM = eagle.app.flash.bin的校驗(yàn)和


其他

回到Makefile,258~259行:

@mv eagle.app.flash.bin ../bin/eagle.flash.bin

@mv eagle.app.v6.irom0text.bin ../bin/eagle.irom0text.bin

說明:最后兩個(gè)mv指令是把生成的兩個(gè)bin文件,改成相應(yīng)的名字并移動(dòng)到esp_iot_sdk/bin/目錄下。


自此,整個(gè)Makefile執(zhí)行結(jié)束,生成eagle.flash.bin和eagle.irom0text.bin文件。



三、啟動(dòng)運(yùn)行過程

1、芯片上電后會(huì)先運(yùn)行片上的ROM,完成必要初始化;
2、片上ROM讀取SPI Flash 0x00000處的flash.bin,并解析出text、data、rodata在內(nèi)存中的位置,并將這3部分加載到片上內(nèi)存中
- text會(huì)加載到iram1上,因此text最大不能超過32KB(0x8000);(解決方法參見注意事項(xiàng)和建議的第一條)
- data和rodata加載到dram0上,因此這二者和不能大于80KB(0x14000);
- 在dram0上還有bbs、stack、heap,要注意使用量。
以IoT_Demo固件來看:data+rodata+bbs = 0xb34+0xd70+0x6cd0 = 0x8574,因此stack和heap能用的內(nèi)存只有46K左右(0x14000-0x8574),如果是空白的固件,則大約有50KB左右;

3、片上固化rom加載flash.bin完畢后跳到入口地址entry_addr處執(zhí)行;
4、當(dāng)執(zhí)行到irom1上的代碼時(shí)(通過ICACHE_FLASH_ATTR定義的函數(shù)),會(huì)將它們從SPI Flash上加載到cache中運(yùn)行;


四、注意事項(xiàng)和建議

1、標(biāo)注「ICACHE_FLASH_ATTR」宏的函數(shù)存儲(chǔ)在irom0里面(Flash里面),表示將其存放在Flash中,僅調(diào)用時(shí)才加載到cache 運(yùn)行;

沒有標(biāo)注的會(huì)放在iram1里面,iram1大小只有32KB,IoT_Demo固件使用了大約27KB,還剩下5KB,而irom0最大支持768KB。所以如果自己用SDK開發(fā),請盡量給函數(shù)都標(biāo)注該宏,不然會(huì)出現(xiàn)內(nèi)存不夠用的錯(cuò)誤信息:「.output/eagle/debug/image/eagle.app.v6.out section `.text' will not fit in region `iram1_0_seg'」


2、不要在GPIO或UART中斷處理函數(shù)中調(diào)用帶有「ICACHE_FLASH_ATTR」宏的函數(shù),否則可能會(huì)進(jìn)入異常導(dǎo)致重啟。


3、上電時(shí)會(huì)以串口波特率76800bps(和晶振有關(guān))打印「ets Jan 8 2013,rst cause:2, boot mode:(1,7)」等信息,這一上電信息是保存在片上固化ROM的,無法屏蔽。

總結(jié)

以上是生活随笔為你收集整理的【ESP8266】ESP8266_NONOS_SDK开发包生成的镜像文件构建步骤分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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