读写操作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