<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/Learn8266ForSDK" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
說明
ESP826612F/E里面使用w25q32作為了flash存儲.
提前說下哈,bit代表位 也就是 0 1 0 1 , Bit代表字節 ,一字節就是8位
w25q32的容量是32Mbit 也就是 32/8 = 4MB字節 = 4*1024 = 4096KB字節
然后 w25q32 這個芯片規定每 64KB字節作為一個塊
所以呢w25q32總共分成了 4096/64 = 64個塊,不要問我,塊是神么.....就是一塊一塊的區域,所以就是塊...
然后 w25q32 這個芯片還規定每 4KB字節作為一個扇區.每256字節作為一頁.
所以所有的扇區個數是 64*16 = 1024個
然后,為啥做這個芯片的要規定 塊,扇區和頁這些東西呢????
因為哈,擦除的時候規定要么擦除某個扇區要么擦除某個塊
這是最小擦除的單位....
然后寫數據的時候呢是頁寫....也就是只能寫某一頁,所以最多寫256字節
假設咱需要把數據寫到第一個塊里面的第一個扇區里面的第一頁里面
那么咱呢可以直接寫命令擦除第一個塊里面的第一個扇區
然后把數據寫到里面.
或者也可以擦除第一個塊,然后把數據寫到里面
然后看看ESP8266里面怎么規定的
芯片是4096KB字節 = 4096*1024 = 4194304字節 = 0x400000
eagle.flash.bin 從flash的最開始的地址開始存儲
eagle.irom0text.bin (0x10000 = 65536) 偏移了65536字節即64KB
esp_init_data_default.bin (0x3FC000) 從倒數第4個扇區開始存儲 (注:0x400000 - 4096-4096-4096-4096 = 0x3FC000)
blank.bin (0x3FE000)從倒數第2個扇區開始存儲 (注:0x400000 - 4096-4096 = 0x3FE000)
注意,未使用區域是變化的...咱編譯完程序會顯示eagle.irom0text.bin 大小
隨着程序量的增加eagle.irom0text.bin 大小也在增加
其實呢咱使用上面的未使用區域的時候一般可以從0x3FC000地址往前推,
(提醒:以一個扇區4KB作為最小使用哈,因為擦除的時候最小擦除是4KB)
假設咱感覺存儲咱自己的數據只使用4KB就可以了,那么就是在 0x3EB000地址開始存儲咱自己的數據.
0x3FC000 - 4KB = 0x3EB000 即從倒數第5個扇區開始存儲數據
其實從0x3FC000 到 0x3FE000 總共有8KB,所有中間有兩個扇區
因為esp_init_data_default.bin 的大小是固定的哈不會超過4KB,
所以0x3FE000 左面的那個4KB的扇區也是可以使用的
開始的地址是 0x3FD000 即從倒數第三個扇區存儲數據
然后呢看下提供的API函數
1.擦除某個扇區
總共1024個扇區,扇區號從0開始,所以是 0 - 1023
列如擦除上面的倒數第5個扇區 就是 spi_flash_erase_sector (1019)
2.往扇區里面寫數據
3.從flash里面讀取數據
4.SDK還封裝了一套交替存儲API
就是使用3個扇區保存數據,第一個扇區和第三個扇區來回的保存數據
第二個扇區只保存一個標志位,標志當前數據是存儲在第一個扇區還是第二個扇區(程序內部實現)
API函數的第二個參數假設是 1017
那么就是使用第1017和1018扇區來回的保存數據,1018扇區保存標志位
注意:關於4字節對齊
如果你存儲數據,存儲的數據個數是4的倍數就可以.
一般咱都會把數據放到一個數組里面,所以咱把數組長度定義為4的倍數就可以
我上面說的是char型的數組
如果是u16型的數組,數組長度定義為2的倍數就可以
如果是u32的就隨意啦....
開始實踐(普通)
好像啥都說明白了....用戶自己實踐就可以了
//設置扇區地址 #define flash_save_sector 1019 //設置寫入flash的起始地址 #define flash_save_addr flash_save_sector*4*1024 //(該扇區的起始地址) //存儲的數據 char flash_data[16] = "test flash data"; /** * @brief system_done * @param None * @param None * @retval None * @warning None * @example **/ void system_done(void) { char temp[16]; //擦除扇區 spi_flash_erase_sector (flash_save_sector); //寫入數據 spi_flash_write(flash_save_addr,(uint32 *)flash_data,sizeof(flash_data)); //讀取數據 spi_flash_read(flash_save_addr,(uint32 *)temp,sizeof(temp)); os_printf("\r\n save data =%s \r\n",temp); } void ICACHE_FLASH_ATTR user_init(void){ uart_init_2(BIT_RATE_115200,BIT_RATE_115200); //注冊系統初始化完成回調函數 system_init_done_cb(system_done); }
開始實踐(寫保護)
1.官方給了例子
注意 priv_param_start_sec 參數是這個參數
咱使用的時候也這樣就可以