文档章节

esp8266 rtos sdk编译后flash镜像构成

lgl88911
 lgl88911
发布于 2015/07/25 17:40
字数 1137
阅读 1799
收藏 4

由于官方文件没有说明esp8266的启动特点,本文根据sdk内的flash map文档,sdk makefile, ld文件及flash image 生成的python脚本文件,简要分析esp8266的启动和运行,及flash镜像的构成特点。这里使用的sdk和编译时配置项见esp8266 rtos sdk在小黄板上的使用

##sdk生成的elf文件 这里主要分析sdk根目录下的makefile文件就可以得到elf相关信息。
在执行make前我们已经选择好编译的配置项,这里直接给出:

  • boot=none
  • app=0
  • freqdiv=0
  • mode=0
  • size_map=4
  • flash=4096
    从makefile内可以分析到使用的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中可以找到对实际运行有效的5个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

结合ld文件的memory信息可以看到 .data, .rodata, .bbs都是放到dram0_0_seg中,.text是放到iram1_0_seg中,.irom0.text是放到irom0_0_seg中。

##将elf文件转化为烧写镜像 ###makefile将以上各section copy成单个文件

$(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三个文件打包成一个eagle.app.flash.bin, 命令为:

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

这里直接给出gen_appbin.py的各项参数

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

打包过程简要:

  1. 通过nm -g eagle.app.v6.out 产生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段开始地址
  1. 按照如下格式打包成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字节对齐
TEXT = eagle.app.v6.text.bin 的数据,4字节对齐,最后不对齐的补0
DATAADDR = data_start_addr
DATALEN = eagle.app.v6.data.bin的文件长度4字节对齐
DATA = eagle.app.v6.data.bin 的数据,4字节对齐,最后不对齐的补0
RODATAADDR = data_start_addr
RODATALEN = eagle.app.v6.data.bin的文件长度4字节对齐
RODATA = eagle.app.v6.data.bin 的数据,4字节对齐,最后不对齐的补0
ALIGMENT = 对齐数据,保证sum前的数据16字节对齐,不对齐这里补0
CHKSUM = eagle.app.flash.bin的校验和

  1. 将生成的文件重命名为要烧写到flash的镜像名 @mv eagle.app.flash.bin ../bin/eagle.flash.bin @mv eagle.app.v6.irom0text.bin ../bin/eagle.irom0text.bin

##FLASH MAP 在数据下载后会写到SPI Flash内: eagle.flash.bin下载到0x00000处 eagle.irom0text.bin下载到0x40000处
输入图片说明

##irom说明 从前面可以看.text放到idram0中执行,但指令内存空间有限32K,所以在C代码中,使用ICACHE_FLASH_ATTR定义的函数将会放到irom0内,最后也就是放到了eagle.irom0text.bin,被放到SPI flash上的0x40000处。

#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))

##启动和运行 现在可以来猜启动和运行的过程了:

  1. 芯片上电后会先运行片上的ROM,完成必要初始化
  2. 片上ROM读取SPI Flash 0x00000处的flash.bin,并解析出text,data,rodata在内存中的位置,并将这3部分加载到片上内存中
  • text加载到iram1上,因此text最大不能操过32K(0x8000), 可见内存加载的代码有限
  • data和rodata加载到dram0上,因此这二者和不能大于80K(0x14000)
  • 在dram0上还有bbs,stack,heap,要注意使用量,在目前的状况下:data+rodata+bbs = 634+8b0+6bc8 = 7AAC,因此stack和heap能用的内存只有50K左右(0x14000-0x7AAC)
  1. 片上固化rom加载flash.bin完毕后跳到入口地址entry_addr处执行
  2. 当执行到irom1上的代码时(通过ICACHE_FLASH_ATTR定义的函数),会将它们从SPI Flash上读到 cache 中运行。**注意:**不要在 GPIO 或 UART 中断处理函数中调用带有 "ICACHE_FLASH_ATTR" 宏的函数,否则将进入异常。

由于片上ROM我们不能更改,因此编写代码时要遵循FLASH MAP地址和大小。

© 著作权归作者所有

lgl88911
粉丝 17
博文 83
码字总数 50237
作品 0
成都
高级程序员
私信 提问
加载中

评论(1)

m
marktsai0316
非常詳盡的說明, 感謝您的分享.0
SuperGIS/ESP8266App

<<<<<<< HEAD #ESP8266App This project is a app collections of ESP8266 WiFi SoC. Include: 1.App as fireware using SDK. but not include SDK,which provide by www.espressif.com. 2.A......

SuperGIS
2015/03/24
0
0
esp8266 rtos sdk在小黄板上的使用

下载RTOS SDK代码 2. 下载编译器 http://bbs.espressif.com/viewtopic.php?f=5&t=2 3. ubuntu下安装编译器 将xtensa-lx106-elf.tar.bz2解压缩到/opt/下 4. 编译代码 4.1设置编译器环境变量 ...

lgl88911
2015/07/23
4K
0
ESP8266App重要更新,目录结构调整

ESP8266App包含了基于ESP8266的多个开源的重要项目,包括对LUA/MicroPython及MQTT消息协议的支持。 ESP8266App进行了2015年的第一次重要更新(2015-04-17),改动如下: 1、ESP8266SDK加入主...

openthings
2015/04/17
1K
0
ESP8266-12F wifi模块烧录AT指令固件过程总结

由于在淘宝https://item.taobao.com/item.htm?spm=2013.1.w4004-14363447044.2.3d6d3e6dftfu0z&id=536609386865上买了几个乐鑫 ESP8266-12F 串口透传 wifi模块。到手后发现默认都被烧录的所谓...

baidu_17220503
2018/04/20
0
0
用Docker容器进行IoT开发

随着IoT新的硬件平台和开发板的不断更新,SDK交付越来越多地转向零碎化以及“按需组装”解决方案。大多数的硬件公司很难提供能够正常运行的Software Development Kits (SDKs)。 Docker为硬件...

Mrexamo
2015/09/16
313
0

没有更多内容

加载失败,请刷新页面

加载更多

vue入门--简单路由配置

本文转载于:专业的前端网站➜vue入门--简单路由配置   在初始化vue init webpack <工程名>时,有一步是询问是否安装vue-router,选择yes,如果没有安装的话,后面需要自己安装。然后在目录...

前端老手
14分钟前
2
0
怎么给视频配音

很多刚开始尝试视频制作的小伙伴,帮助到怎么给制作完成的视频配音,其实给视频配音的方法非常简单,在手机上可以进行制作,下面一起来看看给视频配音的方法吧! 具体步骤如下: 1、首先在手...

白米稀饭2019
23分钟前
2
0
windows批处理bat脚本编写

什么是bat脚本 .bat结尾的文件其实就是windows上的批处理脚本,Windows中的bat文件相当于 Linux中shell编程的.sh脚本,批量执行DOS命令。 其最简单的例子,是逐行书写在命令行中会用到的各种...

孙幼凌
31分钟前
2
0
华为手机翻译功能怎么使用?这三种方法请务必收藏

华为手机翻译功能怎么使用?在我们的生活中会经常遇到翻译问题,许多外语不好的朋友该怎么办呢?华为手机已经为我们解决了这个问题,今天小编就教大家学会使用华为手机中的三种翻译技巧,需要...

翻译小天才
39分钟前
4
0
企业服务软件开发中需要注意的三个问题

在开发企业服务软件时,我们需要分为:业务需求、用户需求、产品需求,三大需求层次,三个层次互相关联,企业服务软件开发首先要服务业务,需要满足业务的需求,再关注用户体验,也就是用户需...

积木创意科技
42分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部