ESP32-S3的启动过程以及Flash分区浅谈

158次阅读
没有评论

首先明确,普通 esp32 和 s3 是不同的,本文并不适用于普通 esp32。

术语

单位用的都是字节,0x1000 转成 10 进制为 4096,即 4kb。

启动过程

S3 芯片上电后,首先运行芯片内部固化的微型 BootLoader,称为一级引导程序,它会读取外部 Flash 的 0 地址的程序,加载并运行。

位于外部 Flash 的 0 地址的程序,称为二级引导程序,它是由 idf 在编译过程中生成的,他可以由我们定制,他负责读取分区表,找到 app 分区后启动我们的主程序。当 ota 时,由它确定接下来跑产品出厂的代码还是 ota 后的代码。

接下来,我们的实际代码由二级引导启动,freertos 调度器开始运行。我们再代码中看到的 app_main 实际是一个 task,他紧接着启动。

二级引导所在位置

对于 S3,二级引导必须放在 flash@0x0 的位置。顺带一提,C3 和 S3 一样,但普通的 esp32,在 0x1000,而 P4 却在 0x2000。

它的大小在默认情况下,使用官方提供的引导代码,编译出来约为 20 多 kb。

分区表

从上边的启动过程可知,一级引导只知道从 0 读取二级引导,二级引导并不知道 app 分区在哪,改去哪读取程序。esp32 引入了分区表的概念,记录 Flash 的分区。

CONFIG_PARTITION_TABLE_OFFSET 可配置分区表所在位置,默认为 0x8000,这也意味着,上边而二级引导默认不能超过 0x8000,否则会越界。但是可通过调整这个配置项,让分区表后移,给二级引导更大的空间。分区表本身能够最多存储 95 个分区,占用 3kb 的空间,但实际占用了 4kb,为了对齐。也就是说下一段实际可用的地址是 0x8000+4kb=0x900。

分区表由 csv 定义,默认使用自带的 partitions_singleapp.csv 作为分区,其内容如下。我们注意到,Offset 列为空,这是让分区表生成器自动计算。

# 默认的分区表
# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     ,  0x6000,   # 简单的 kv 存储,用于量产刷 sn& 秘钥等
phy_init, data, phy,     ,  0x1000,   # 射频校准参数,不用管
factory,  app,  factory,   , 1M,      # 代码存放处 

可以用以下命令,完成 csv 到分区表后,再把分区表转成 csv。

python gen_esp32part.py partitions.csv partitions.bin
python gen_esp32part.py partitions.bin partitions-full.csv

转换后的分区表会显示出自动补全的 Offset,这也印证了,第一个分区确实在 0x9000 的位置。

# 转换后
nvs,data,nvs,0x9000,24K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1M,
正文完
 0
评论(没有评论)