ESP8266学习笔记(2)——内存分布及Flash读写接口

一、存储芯片W25Q系列

esp8266-12f

w25q 系列生产的加工的商家很多,但是里面的分布和命名规则都是一样的。比如华邦的w25q64,spi通讯接口,64就是指 64Mbit 也就是 8M 的容量。而我们平时的8266-12f的 32Mbit 就是 4M 容量。

w25q32 为例,里面的存储分布。w25q32把4M容量分为了 64 块,每一块又分为 16 个扇区,而每个扇区占 4K 大小。由此可计算到,w25q32有 32Mbit / 8 * 1024 / 16 / 4 = 64 块 ,有 64 * 16 = 1024 个扇区。

注:1B=8 Bit ,1KB=1024B ,1MB=1024KB


二、ESP8266内存分布

程序区:代码编译生成的 bin 文件,烧录到 Flash 占用的区域,请勿改写

系统参数区: esp_iot_sdk 中底层用于存放系统参数的区域,请勿改写

用户参数区:上层应用程序存储用户参数的区域。开发者请根据实际使用的 Flash size 设置,可 以参考文档“2A-ESP8266__IOT_SDK_User_Manual” 中的 “Flash Map” 一章。

2.1 Non-FOTA

2.2 FOTA


更多图查看:

链接:https://blog.csdn.net/k7arm/article/details/51812021


三、Flash读写接口

SPI Flash 接口位于 /ESP8266_NONOS_SDK/include/spi_flash.h

system_param_xxx 接口位于 /ESP8266_NONOS_SDK/include/user_interface.h

3.1 spi_flash_erase_sector

3.2 spi_flash_write

注意:

    • Flash 请先擦再写。

    • Flash 读写必须 4 字节对齐。

示例代码:

    #define N 0x7C

    uint32 data[M];

    spi_flash_erase_sector (N);

    spi_flash_write (N*4*1024, data, M*4);

3.3 spi_flash_read

3.4 system_param_save_with_protect

3.5 system_param_load

示例代码:

/***************Flash 读写结构体声明***************/

struct esp_platform_saved_param {

// 服务器参数

uint8 devkey[40];

uint8 token[40];

uint8 activeflag;

char server_domain[64];

ip_addr_t server_ip;

int server_port;

 // AP参数

uint8 ssid[32];

uint8 password[64];

int authmode;

uint8 ssid_hidden;

// 填充

uint8 pad[2];

};

/***************Flash 读写结构体定义***************/

struct esp_platform_saved_param esp_param;

/***************Flash 写入数据***************/

system_param_save_with_protect(0x7D, &esp_param, sizeof(esp_param));

/***************Flash 读出数据***************/

system_param_load(0x7D, 0, &esp_param, sizeof(esp_param)); 


四、Flash读写保护

4.1 Espressif Flash读写保护示例

4.1.1 实现原理

Espressif Flash 读写保护示例,使用 三个 sector(扇区)实现(每 sector 4KB),提供 4KB 的可靠存储空间。 将 sector 1 和 sector 2 作为数据 sector,轮流读写,始终分别存放“本次”数据和“前一次”数据, 确保了至少有一份数据存储安全;sector 3 作为 flag sector,标志最新的数据存储 sector。

保护机制如下:

1. 初始上电时,数据存储在 sector 2 中,从 sector 2 中将数据读到 RAM。

2. 第一次写数据时,将数据写入 sector 1。此时若突然掉电,sector 1写入失败,sector 2 & 3数据未改变;重新上电时,仍是从 sector 2 中 读取数据,不影响使用。

3. 改写 sector 3,将标志置为 0,表示数据存于 sector 1。此时若突然掉电,sector 3 写入失败,sector 1 & 2 均存有一份完整数据;重新上电时,因 sector 3 无有效 flag,默认从 sector 2 中读取数据,则仍能正常使用,只是未能包含掉电前对 sector 1 写入的数据。

4. 再一次写数据时,先从 sector 3 读取 flag,若 flag 为0,则上次数据存于 sector 1,此次应将数据写入 sector 2;若 flag 为非 0,则认为上次数据存于 sector 2,此次应将数据写入 sector 1。此时若写数据出错,请参考步骤 2、 3的说明,同理。

5. 写入 sector 1(或 sector 2)完成后,才会写 sector 3,重置 flag。注意:只有数据扇区(sector 1或 sector 2)写完之后,才会写 flag sector(sector 3),这样即使 flag sector 写入出错,两个数据扇区都已存有完整数据内容,目前默认会读取 sector 2。

4.1.2 软件示例

IOT_Demo 中,使用 0x3C000 开始的 4 个 sector(每 sector 4KB),作为用户参数存储区。 其中 0x3D000、 0x3E000、 0x3F000 这 3 个 sector 实现了读写保护的功能,并存储了应用级参数 esp_platform_saved_param

图中“有读写保护的存储区”, IOT_Demo 中建议调用 system_param_load system_param_save_with_protect 进行读写。

system_param_load - 读 Flash 用户参数区数据

system_param_save_with_protect - 写 Flash 用户参数区数据

参数 struct esp_platform_saved_param 定义了目前乐鑫存储于 Flash 的用户应用级数据,用户只需将自己要存储的数据添加到结构体 struct esp_platform_saved_param 后面,调用上述两个函数进行 Flash 读写即可。

4.2 Flash读写保护参考一

方法: “轮流写入”+“首部记数”+“尾部校验”

占用空间: 2 个 sector,共计 8KB;提供 4KB 的带数据保护存储空间。

原理:

仍然 采用两个数据 sector 轮流写入来做备份数据保护,只是不再专门设立 flag sector。 记一个 counter,写入数据 sector 的首部,每次写入时计数加一,用记数比较来判别下一次应写入哪个 sector;在数据尾部加入校验码(CRC、checksum 等任一种校验方式),用以验证数据的完整性。

(1) 假设初次上电,数据存储在 sector A, sector A 的记数为初始值 0xFF,从 sector A 将数据读入 RAM。

(2) 第一次数据写入 sector B,则在 sector B 首部信息中记录 counter 为 1,尾部加入校验码。

(3) 再次写入数据时,先分别读取 sector A/B 的 counter 值进行比较,此次应当将数据写入 sector A, sector A 首部记录 counter 为 2,尾部加入校验码。

(4) 若发生突然掉电,当前正在写入的 sector 数据丢失,重新上电时,先比较 sector A/B 的 counter 值,读取 counter 值较大的完整 sector,根据 sector 尾部的校验码进行校验,当前 sector 数据是否可靠,若校验通过,则继续执行;若校验失败,则读取另一个 sector 的数据,校验,并执行。

4.3 Flash读写保护参考二

方法: “备份扇区”+“尾部校验”

占用空间: 2 个 sector,共计 8KB;提供 4KB 的带数据保护存储空间。

原理:

始终往 sector A 读写数据,每次写入时,同样写一遍 sector B 作为 sector A 的备份扇区,每个 sector 尾部均加入校验码(CRC、checksum等任一种校验方式)。

(1) 从 sector A 读取数据,并进行校验。

(2) 数据写入 sector A,尾部为校验码。

(3) sector A 写入完成后,同样的数据也写入 sector B 进行备份。

(4) 若发生突然掉电,当前正在写入的 sector 数据丢失,重新上电时,先从 sector A 读取数据,根据尾部的校验码进行校验,sector A 数据是否可靠,若校验通过,则继续执行;若校验失败,则读取 sector B 的数据,校验,并执行。



• 由 Leung 写于 2018 年 9 月 14 日

• 参考:《ESP8266 Flash 读写说明》[25l1]

             《ESP8266 Non-OS SDK IoT_Demo 指南》[q878]

             《ESP8266 Non-OS SDK API 参考》[7qq6]

             《Esp8266 进阶之路24》

             《ESP8266 Flash》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,667评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,361评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,700评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,027评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,988评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,230评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,705评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,366评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,496评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,405评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,453评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,725评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,803评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,015评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,514评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,111评论 2 341

推荐阅读更多精彩内容