[esp8266]官方SDK与arduino ROM或Flash布局,Vscode+platformio 如何设置

flash布局有哪些

  1. 乐鑫官方的SDK flash布局
  2. 在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结构

avatar
avatar
avatar
(图来自他人帖子,没找到原图,觉着画的很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
}

参考链接

详细ram与rom内存映射
[]

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中。

修改过程

  1. 首先了解上面的官方的SDK结构后,发现起始flash是可以修改的,然后通过arduino与官方SDK falsh布局解析发现实际上
    的flash起始是被arduino重新配置过。
  2. 在此之前得了解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(只是取其中一种配置方式说明,文件夹里有很多这样的配置文件)

  1. 那么用户视角是哪里修改,而真实的配置文件是哪个?
    通过寻找发现实际上用户界面只需要勾选即可,而真正起作用的文件是:eagle.flash.4m1m.ld(取其中一个文件)。
    avatar

  2. 发现其实arduino下的spifs实际上是文件系统而已,通过以上界面修改可以达到代码选择需要的***.ld文件,如:eagle.flash.4m3m.ld。

  3. 那么在VsCode+platformio上如何做到这样的修改。

  4. 起初发现之前在目录C:\Users\PX_Lenovo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2下发现很多*.py文件,猜想是否
    由这些python代码来实现编译选择正确的,翻看了一些代码,确实由有相关操作,我想是否可以在python代码中加入打印,判断platformio调用这些代码
    结果发现,加入代码,使用platformio编译无效。

  5. 我发现编译时会有一些打印,打印给了许多的网址,找到platformio手册 然后仔细在网站上
    寻找了一些资料,发现**.ld文件其实就是ld(gnu 链接器),知道链接器的朋友肯定知道,其实platformio使用界面选择替代输入命令行。

  6. 那么我是否能在platformio中设置它选择文件eagle.flash.4m3m.ld,首先想到platformio.ini文件是配置环境变量文件,在网上找寻一番,还真有一点,
    在该文件下加入board_build.ldscript = eagle.flash.4m3m.ld就能实现加载该脚本。试图加入,发现无任何变化:
    avatar
    avatar

  7. 第二天,继续思考,看看能不能在vscode的终端手动添加ld命令,发现只有gcc.exe,没有ld命令。

  8. 注意到点击编译,终端会打印: 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打开该文件:

  9. 赫然发现"ldscript": "eagle.flash.4m1m.ld",这个应该就是寻找的文件,尝试修改该字段为:"ldscript": "eagle.flash.4m3m.ld",发现编译没有任何变化
    ,发现编译时会打印一些板子信息:
    avatar

  10. 那么尝试修改这些信息,在nodemcuv2.json中"name": "NodeMCU 1.0 (ESP-12E Module)"修改为:"name": "NodeMCU 1.0 (ESP-12E Module, Hello!)",发现终端打印同样的信息,那么确定是该文件无疑,尝试再修改一些其他信息,打印发现也会变动。

  11. 突然注意到修改为eagle.flash.4m3m.ld其实是spi fs的大小修改了,实际上终端是不会打印出文件系统的任何信息的。那么到这里其实修改已经完成了。

  12. 那么实际上可能在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使用方法

附录

posted @ 2022-03-21 20:45  邪恶法师  阅读(2477)  评论(0编辑  收藏  举报