您好,登錄后才能下訂單哦!
這篇文章主要介紹“esp8266 rtos sdk編譯后flash鏡像構(gòu)成的方法是什么”,在日常操作中,相信很多人在esp8266 rtos sdk編譯后flash鏡像構(gòu)成的方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”esp8266 rtos sdk編譯后flash鏡像構(gòu)成的方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
由于官方文件沒有說明esp8266的啟動特點(diǎn),本文根據(jù)sdk內(nèi)的flash map文檔,sdk makefile, ld文件及flash image 生成的python腳本文件,簡要分析esp8266的啟動和運(yùn)行,及flash鏡像的構(gòu)成特點(diǎn)。這里使用的sdk和編譯時(shí)配置項(xiàng)見esp8266 rtos sdk在小黃板上的使用
##sdk生成的elf文件 這里主要分析sdk根目錄下的makefile文件就可以得到elf相關(guān)信息。
在執(zhí)行make前我們已經(jīng)選擇好編譯的配置項(xiàng),這里直接給出:
boot=none
app=0
freqdiv=0
mode=0
size_map=4
flash=4096
從makefile內(nèi)可以分析到使用的ld文件是:
LD_FILE = $(LDDIR)/eagle.app.v6.ld
eagle.app.v6.ld可以看到
MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 irom0_0_seg : org = 0x40240000, len = 0x3C000 }
sdk編譯過程中會先生成eagle.app.v6.out,然后dump出段信息和符號文件
@$(RM) -r ../bin/eagle.S ../bin/eagle.dump @$(OBJDUMP) -x -s $< > ../bin/eagle.dump @$(OBJDUMP) -S $< > ../bin/eagle.S
從eagle.dump中可以找到對實(shí)際運(yùn)行有效的5個(gè)section:
Idx Name Size VMA LMA File off Algn 0 .data 00000634 3ffe8000 3ffe8000 000000e0 2**4 1 .rodata 000008b0 3ffe8640 3ffe8640 00000720 2**4 2 .bss 00006bc8 3ffe8ef0 3ffe8ef0 00000fd0 2**4 3 .text 0000776a 40100000 40100000 00000fd0 2**2 4 .irom0.text 00030928 40240000 40240000 00008740 2**4
結(jié)合ld文件的memory信息可以看到 .data, .rodata, .bbs都是放到dram0_0_seg中,.text是放到iram1_0_seg中,.irom0.text是放到irom0_0_seg中。
##將elf文件轉(zhuǎn)化為燒寫鏡像 ###makefile將以上各section copy成單個(gè)文件
$(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
###將section打包 然后使用gen_appbin.py腳本將eagle.app.v6.text.bin,eagle.app.v6.data.bin,eagle.app.v6.rodata.bin三個(gè)文件打包成一個(gè)eagle.app.flash.bin, 命令為:
python ../tools/gen_appbin.py $< 0 $(mode) $(freqdiv) $(size_map)
這里直接給出gen_appbin.py的各項(xiàng)參數(shù)
elf_file = sys.argv[1] >eagle.app.v6.out boot_mode = sys.argv[2] >0 flash_mode = sys.argv[3] >0 flash_clk_div = sys.argv[4] >0 flash_size_map = sys.argv[5] >4 BIN_MAGIC_IROM = 0xEA TEXT_ADDRESS = 0x40100000
打包過程簡要:
通過nm -g eagle.app.v6.out 產(chǎn)生eagle.app.sym,在sym文件中找出section地址和入口地址
call_user_start --> entry_addr >40100004 入口地址 _data_start --> data_start_addr >3ffe8000 .data段開始地址 _rodata_start --> rodata_start_addr >3ffe8640 .rodata段開始地址
按照如下格式打包成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.data.bin的文件長度4字節(jié)對齊
RODATA = eagle.app.v6.data.bin 的數(shù)據(jù),4字節(jié)對齊,最后不對齊的補(bǔ)0
ALIGMENT = 對齊數(shù)據(jù),保證sum前的數(shù)據(jù)16字節(jié)對齊,不對齊這里補(bǔ)0
CHKSUM = eagle.app.flash.bin的校驗(yàn)和
將生成的文件重命名為要燒寫到flash的鏡像名 @mv eagle.app.flash.bin ../bin/eagle.flash.bin @mv eagle.app.v6.irom0text.bin ../bin/eagle.irom0text.bin
##FLASH MAP 在數(shù)據(jù)下載后會寫到SPI Flash內(nèi): eagle.flash.bin下載到0x00000處 eagle.irom0text.bin下載到0x40000處
##irom說明 從前面可以看.text放到idram0中執(zhí)行,但指令內(nèi)存空間有限32K,所以在C代碼中,使用ICACHE_FLASH_ATTR定義的函數(shù)將會放到irom0內(nèi),最后也就是放到了eagle.irom0text.bin,被放到SPI flash上的0x40000處。
#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))
##啟動和運(yùn)行 現(xiàn)在可以來猜啟動和運(yùn)行的過程了:
芯片上電后會先運(yùn)行片上的ROM,完成必要初始化
片上ROM讀取SPI Flash 0x00000處的flash.bin,并解析出text,data,rodata在內(nèi)存中的位置,并將這3部分加載到片上內(nèi)存中
text加載到iram1上,因此text最大不能操過32K(0x8000), 可見內(nèi)存加載的代碼有限
data和rodata加載到dram0上,因此這二者和不能大于80K(0x14000)
在dram0上還有bbs,stack,heap,要注意使用量,在目前的狀況下:data+rodata+bbs = 634+8b0+6bc8 = 7AAC,因此stack和heap能用的內(nèi)存只有50K左右(0x14000-0x7AAC)
片上固化rom加載flash.bin完畢后跳到入口地址entry_addr處執(zhí)行
當(dāng)執(zhí)行到irom1上的代碼時(shí)(通過ICACHE_FLASH_ATTR定義的函數(shù)),會將它們從SPI Flash上讀到 cache 中運(yùn)行。**注意:**不要在 GPIO 或 UART 中斷處理函數(shù)中調(diào)用帶有 "ICACHE_FLASH_ATTR" 宏的函數(shù),否則將進(jìn)入異常。
由于片上ROM我們不能更改,因此編寫代碼時(shí)要遵循FLASH MAP地址和大小。
到此,關(guān)于“esp8266 rtos sdk編譯后flash鏡像構(gòu)成的方法是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。