flash布局有哪些
- 樂鑫官方的SDK flash布局
- 在arduino開發上的FS(file spilt)布局
樂鑫官方儲存結構(非OTA)
在esp8266上有一個spi總線的w25q32芯片(或者其他大小的),支持:512KB, 1M, 2M, 4M.
esp8266有內部儲存器,但是以及用掉了,應該時燒錄了樂鑫自己的板載程序,所以我們只能燒錄程序在
外部的spi flash(如:w25q32)上。
對於RAM則是芯片內部有160K的RAM
一些詞語解釋
詞語名 | 解釋 |
---|---|
RMA | 160K,RAM = IRAM + DRAM |
DRAM | 起始:0x3FFE8000 96K,對於 Non-OS_SDK,前 80 KB 用來存放 .data/.bss/.rodata/heap,heap 區的大小取決於 .data/.bss/.rodata 的大小;還有 16 KB 給 ROM code 使用。 |
對於 RTOS_SDK,96 KB ,用來存放 .data/.bss/.rodata/heap,heap 區的大小取決於 .data/.bss/.rodata 的大小。 | |
IRAM | 起始:0x40100000 ,64K, instruct RAM,有時候會把它當作64K,有時候會32K,這里區分,IRAM=icache+iram |
iram | 起始:0x40100000 ,32K,被icache分去后的instruct RAM |
icache | 起始:0x40200000,32K,IRAM分出后的用作映射作用,ICACHE_FLASH_ATTR字段(section)會被加載到cache中。 |
動態內存結構
RAM
內部的RAM(160KB)被分為兩部分:IRMA與DRAM,其中IRAM(64K),從其中抽取32K用作icache,其余32K任然作為iram,
icache 映射一部分falsh(wa25q32)上的內存到其中,以加速讀取。
cahce映射
esp8266 支持多種 cache 映射機制,當前默認的使用的是 1MB + 1MB 的方式。
即將 spi flash 中的:
0x000000~0x0FFFFF 映射到 0x40200000~0x402FFFFF,
0x100000~0x1FFFFF 映射到 0x40200000~0x402FFFFF。
Flash結構
(圖來自他人帖子,沒找到原圖,覺着畫的很OK,隨手用了,原帖主人介意來聯系我刪除)
falsh在bin線性上一共分布為(按flash從0x000000開始):
燒錄bin檔名 | flash地址 | 扇區號 | 默認長度(KB) | 最大長度(KB) | 區域說明 |
---|---|---|---|---|---|
eagle.flash.bin | 0x00000 | 0- | 64 | 64 | |
eagle.irom0text.bin | 0x10000 | 16-? | 200 | 768 | |
esp_init_data_default.bin | 0x3FE000 | 1020 | 4 | 4 | |
blank.bin | 0x3FE000 | 1022 | 4 | 4 |
falsh在邏輯上一共分布為(按flash從0x000000開始):
區域名 | flash地址 | 扇區號 | 長度(KB) | 區域說明 |
---|---|---|---|---|
系統程序 | 0x00000 | 0 | 64 | eagle.flash.bin |
系統程序 | 0x10000 | 16-? | 768 | eagle.irom0text.bin |
用戶數據 | 0x? | ? | ? | ? |
系統自己校准后保存RF參數區域 | 0x3FB000 | 1019 | 1 | RF_CAL |
默認RF參數 | 0x3FC000 | 1020 | 1 | esp_init_data_default.bin |
balnk.bin | 0x3FD000 | 1021 | 1 | 圖中被划去的 |
balnk.bin | 0x3FE000 | 1022 | 1 | 初始化系統參數區 |
以上與網上有些版本有些差異,但我感覺問題差異不大。
代碼中的字段
MEMORY
{
dport0_0_seg : org = 0x3FF00000, len = 0x10
dram0_0_seg : org = 0x3FFE8000, len = 0x18000
iram1_0_seg : org = 0x40100000, len = 0x8000
irom0_0_seg : org = 0x40220000, len = 0x5C000
}
參考鏈接
arduino儲存結構
一些詞語解釋
詞語名 | 解釋 |
---|---|
RMA | 160K,RAM = IRAM + DRAM |
DRAM | 起始:0x3FFE8000 96K,對於 Non-OS_SDK,前 80 KB 用來存放 .data/.bss/.rodata/heap,heap 區的大小取決於 .data/.bss/.rodata 的大小;還有 16 KB 給 ROM code 使用。 |
對於 RTOS_SDK,96 KB ,用來存放 .data/.bss/.rodata/heap,heap 區的大小取決於 .data/.bss/.rodata 的大小。 | |
IRAM | 起始:0x40100000 ,64K, instruct RAM,有時候會把它當作64K,有時候會32K,這里區分,IRAM=icache+iram |
iram | 32K,被icache分去后的instruct RAM |
icache | 32K,IRAM分出后的用作映射作用,ICACHE_FLASH_ATTR字段(section)會被加載到cache中。 |
修改過程
- 首先了解上面的官方的SDK結構后,發現起始flash是可以修改的,然后通過arduino與官方SDK falsh布局解析發現實際上
的flash起始是被arduino重新配置過。 - 在此之前得了解arduino的falsh配置,flash(4M舉例)被分為6區域:
區域 | 作用 | 內存起始 |
---|---|---|
sketch | 這塊區域主要是OTA或者板載代碼(就是用戶程序) | 0x40200000(esp8266內存的映射) |
empty | 空白區域 | |
spifs | 文件系統區域 | |
eeprom | eeprom區域,可以使用arduino的EEPROM讀寫 | |
rfcal | 射頻校准參數 | |
wifi | wifi配置參數,如密碼等。 |
該文件配置位置在:C:\Users\PX_Lenovo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\sdk\ld\eagle.flash.4m3m.ld(只是取其中一種配置方式說明,文件夾里有很多這樣的配置文件)
-
那么用戶視角是哪里修改,而真實的配置文件是哪個?
通過尋找發現實際上用戶界面只需要勾選即可,而真正起作用的文件是:eagle.flash.4m1m.ld(取其中一個文件)。
-
發現其實arduino下的spifs實際上是文件系統而已,通過以上界面修改可以達到代碼選擇需要的***.ld文件,如:eagle.flash.4m3m.ld。
-
那么在VsCode+platformio上如何做到這樣的修改。
-
起初發現之前在目錄
C:\Users\PX_Lenovo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2
下發現很多*.py文件,猜想是否
由這些python代碼來實現編譯選擇正確的,翻看了一些代碼,確實由有相關操作,我想是否可以在python代碼中加入打印,判斷platformio調用這些代碼
結果發現,加入代碼,使用platformio編譯無效。 -
我發現編譯時會有一些打印,打印給了許多的網址,找到platformio手冊 然后仔細在網站上
尋找了一些資料,發現**.ld文件其實就是ld(gnu 鏈接器),知道鏈接器的朋友肯定知道,其實platformio使用界面選擇替代輸入命令行。 -
那么我是否能在platformio中設置它選擇文件
eagle.flash.4m3m.ld
,首先想到platformio.ini文件是配置環境變量文件,在網上找尋一番,還真有一點,
在該文件下加入board_build.ldscript = eagle.flash.4m3m.ld
就能實現加載該腳本。試圖加入,發現無任何變化:
-
第二天,繼續思考,看看能不能在vscode的終端手動添加ld命令,發現只有gcc.exe,沒有ld命令。
-
注意到點擊編譯,終端會打印:
Executing task in folder SmallDesktopDisplay: C:\Users\PX_Lenovo\.platformio\penv\Scripts\platformio.exe run <
是否platformio插件就在這里,打開該文件,隨意翻動一下,在C:\Users\PX_Lenovo\.platformio\platforms\espressif8266\boards
中發現很多json文件,那么
聯想到platformio.ini中字段board = nodemcuv2
,自然而然在C:\Users\PX_Lenovo\.platformio\platforms\espressif8266\boards
打開該文件: -
赫然發現
"ldscript": "eagle.flash.4m1m.ld"
,這個應該就是尋找的文件,嘗試修改該字段為:"ldscript": "eagle.flash.4m3m.ld"
,發現編譯沒有任何變化
,發現編譯時會打印一些板子信息:
-
那么嘗試修改這些信息,在nodemcuv2.json中
"name": "NodeMCU 1.0 (ESP-12E Module)"
修改為:"name": "NodeMCU 1.0 (ESP-12E Module, Hello!)"
,發現終端打印同樣的信息,那么確定是該文件無疑,嘗試再修改一些其他信息,打印發現也會變動。 -
突然注意到修改為
eagle.flash.4m3m.ld
其實是spi fs的大小修改了,實際上終端是不會打印出文件系統的任何信息的。那么到這里其實修改已經完成了。 -
那么實際上可能在paltformio.ini文件中加入
board_build.ldscript = eagle.flash.4m3m.ld
是生效的。
總結
在platformio中使用arduino開發esp8266,其修改板子配置只需要修改paltformio.ini:board_build.ldscript
,並且代碼的區域只有sketch這塊(我使用esp12s只有1044464Byte)。
其他
在開發過程中發現,80KB RAM(應該是DRAM)實際上用不了多少,我申請一個8KB的動態緩沖區已經是極限了,那么預測實際上可使用的50KB左右,大了就會無限重啟
可能是某些函數會申請大內存吧,實際情況以后有需要再測試。
修改linker腳本
在platformio.ini加入:
board_build.ldscript = C:\Users\PX_Lenovo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\tools\sdk\ld\eagle.flash.4m3m.ld
文件位置:
arduino配置文件:C:\Users\PX_Lenovo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\cores\esp8266
platformio:C:\Users\PX_Lenovo\.platformio\platforms\espressif8266\boards
參考鏈接
arduino與官方SDK falsh布局解析
官方arduino esp8266falsh 布局參考文檔
腳本.ld使用方法