ESP8266 Flash的分布及其读写操作

读写操作API

基本操作

(1) spi_flash_erase_sector

功能    擦除 Flash 的某个扇区。
函数定义    SpiFlashOpResult spi_flash_erase_sector (uint16 sec)
参数    uint16 sec- 扇区号,从0 开始计数,每个扇区大小为4KB。
返回值    SpiFlashOpResult
(2)spi_flash_write

功能    将数据写入Flash 。
请先调用spi_flash_erase_sector 擦除待写区域,再写入数据。
函数定义    SpiFlashOpResult spi_flash_write (uint32 des_addr, uint32 *src_addr, uint32size)
参数    uint32 des_addr – 写入Flash 的地址,起始位置。
uint32 *src_addr – 写入Flash 的数据指针。
uint32 size – 写入数据的长度,单位:byte。
返回值    SpiFlashOpResult
(3)spi_flash_read

功能    从 Flash 读取数据。
函数定义    SpiFlashOpResult spi_flash_read(uint32 src_addr, uint32 * des_addr, uint32 size)
参数    uint32 src_addr – 读取Flash 的地址,起始位置。
uint32 *des_addr – 读取Flash 的数据指针。
uint32 size – 读取数据的长度,单位:byte。
返回值    SpiFlashOpResult
(4)返回值

Typedef enum{
SPI_FLASH_RESULT_OK,
SPI_FLASH_RESULT_ERR,
SPI_FLASH_RESULT_TIMEOUT
}SpiFlashOpResult;

注意事项

每个扇区的大小为4kB,即4*1024 bytes。
Flash读写数据要以四字节对齐。
Flash要先擦除再写入。
示例代码

/*
* 方式一
*/

#define LEN 1            //以读写4字节的数据为例


#define SEC 123           //读写的扇区(Sector)号


#define SEC_OFFSET 0       //扇区内偏移量(必须是4的倍数)

uint32 write_data[LEN];
uint32 read_data[LEN];

//TODO
//Fill the write_data

//读取数据
spi_flash_read(SEC*4*1024+SEC_OFFSET, read_data, LEN*4); 

//写入数据
spi_flash_erase_sector(SEC);
spi_flash_write(SEC*4*1024+SEC_OFFSET, write_data, LEN*4); 


/*
* 方式二
*/

#define LEN 1             //以读写4字节的数据为例


#define SEC 123           //读写的扇区(Sector)号


#define SEC_OFFSET 0      //扇区内偏移量(必须是4的倍数)

uint8 write_data[LEN*4];
uint8 read_data[LEN*4];

//TODO
//Fill the write_data

//读取数据
spi_flash_read(SEC*4*1024+SEC_OFFSET, (uint32 *)&read_data, LEN*4); 

//写入数据
spi_flash_erase_sector(SEC);
spi_flash_write(SEC*4*1024+SEC_OFFSET, (uint32 *)&write_data, LEN*4); 

【总结】读写地址scr_addr=SEC*4*1024+SEC_OFFSET

Flash地址映射

ESP8266提供了读写Flash的接口,操作很简单,但不能随便找个地方就开始擦除然后写入自己的数据,这样很容易把数据写到不该写入的地方,造成一些潜在的问题,因此难点在于确定读写数据的安全位置。

这里以8M bits即1M bytes(1024 bytes)的Flash为例做以说明,其Flash布局如下。

bin    烧录地址    说明
boot.bin(boot_v1.6.bin)    0x00000    启动程序,SDK中提供。
user1.bin(user1.1024.new.2.bin)    0x01000    主程序,编译代码生成。
esp_init_data_default.bin    0x0fc000    初始化射频参数,SDK中提供。
blank.bin    0x0fe000    初始化系统参数,SDK中提供。
[注]上表参考ESP8266 Flash的维基百科的第三节(Layout With OTA)以及实际烧录配置。

程序区    boot.bin 起始地址0x00000
user1.bin起始地址0x01000
系统参数区    Flash最后4个扇区(即Flash最后16K Bytes)
esp_init_data_default.bin位于Flash倒数第4个 sector
blank.bin位于Flash倒数第2个sector
[注]软件支持云端升级(boot),上表参考自《ESP8266 Flash 读写说明》。

下面的图更加直观地展示了1024KB Flash的分布情况:


结合这张图,说明两个问题。

[注]对于1024KB的Flash,可以分为256(1024/4)个扇区,扇区号为0~255。

确定各个文件的烧录地址

(1)boot.bin,启动程序,烧录地址固定为Flash的开始位置,即0x00000;

(2)user1.bin,用户程序,紧跟在boot之后,boot占用第0个扇区(4KB),则user1.bin的起始地址应为第一个扇区的起始地址:
1×4×1024=4096
1×4×1024=4096

4096换算成十六进制就是0x01000;
(3)esp_init_data_default.bin,初始化射频参数,位于Flash倒数第4个 sector(即252号扇区),则烧录地址应为:
252×4×1024=1032192
252×4×1024=1032192

1032192换算成十六进制就是0x0fc000;
(4)blank.bin,初始化系统参数,位于Flash倒数第2个sector(即254号扇区),则烧录地址为:
254×4×1024=1040384
254×4×1024=1040384

1040384换算成十六进制就是0x0fe000;
用户存储数据的安全区域

如果用户程序user1.bin小于492KB,则剩余的空间可以用于存储用户数据;

假设用户程序大小为480KB,则存储数据可用区域起始地址为:
(4+480)×1024=495616
(4+480)×1024=495616

起始地址为:495616 —-> 0x79000,可用空间大小为此后的3个扇区(121号、122号、123号)。
[推荐]存储在用户参数区(该区域专门用于上层应用程序存储用户参数),起始扇区号为:
512−164=124
512−164=124

则可用起始地址为:
124×4×1024=507904
124×4×1024=507904

起始地址为507904–> 0x7C000,可用此后的4个扇区(124号、125号、126号、127号)。
[注]由上述计算可知,用户参数区是与程序区是相连的,因此用户程序大小不能超过492KB。

【参考资料】
1. ESP8266 Flash 读写说明
2. ESP8266 Flash
————————————————
版权声明:本文为CSDN博主「羽墨志」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011852211/article/details/81390009

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值