今天我們來(lái)說(shuō)說(shuō)ESP32 for Arduino存儲(chǔ)分布以及啟動(dòng)過(guò)程。
ESP32 for Arduino存儲(chǔ)分布
ESP32有多個(gè)不同的存儲(chǔ)配置版本,本文以ESP32 4M FLASH為例進(jìn)行分析。
ESP32的FLASH可以包含多個(gè)應(yīng)用程序以及不同類型的數(shù)據(jù),因此在FLASH默認(rèn)偏移地址的0x8000處燒寫了一個(gè)分區(qū)表,長(zhǎng)度為0xC00字節(jié),分區(qū)表數(shù)據(jù)后還保存著該表的 MD5 校驗(yàn)和,用于驗(yàn)證分區(qū)表的完整性。此外,如果芯片使能了 安全啟動(dòng) 功能,則該分區(qū)表后還會(huì)保存簽名信息。
我們?cè)贓SP32 for Arduino的工具中,有一個(gè)選項(xiàng),可以配置不同的分區(qū)表,這里已經(jīng)做好了一些,一般我們都是使用默認(rèn)的,如下圖所示:
分別代表什么意思呢?4M FLASH默認(rèn)分區(qū)方案為1.2MB的應(yīng)用程序空間,1.2MB為OTA保留,1.5MB為SPIFFS文件系統(tǒng)保留的,我們找到這個(gè)描述文件,在SDK下tools下的partitions,我們打開default.csv,對(duì)應(yīng)默認(rèn)的分區(qū)表:
表格描述的很清楚,各個(gè)分區(qū)名字,對(duì)應(yīng)的偏移地址,以及占用大小,比如,nvs分區(qū),從0x9000地址處開始,大小為0x5000,也就是20480字節(jié)的大小,具體每個(gè)分區(qū)的作用,我們下面細(xì)說(shuō)。我們這里知道的就是,在0x9000處放了一個(gè)nvs表,決定我們整個(gè)存儲(chǔ)區(qū)域怎么劃分的,每個(gè)分區(qū)分別分配多大的存儲(chǔ)空間,系統(tǒng)就根據(jù)這個(gè)表來(lái)劃分,可以根據(jù)我們的程序大小等靈活配置。
分區(qū)表說(shuō)明
網(wǎng)上找到一張ESP32的分區(qū)表,很有代表意義,這里以這一份給大家講一下。
- 0-0x1000 保留
- 0x1000-0x8000 Bootloader分區(qū)
- 0x8000-0x9000 Partition Table分區(qū),保存著分區(qū)表
- 0x9000-0xD000 NVS分區(qū),可以存儲(chǔ)一些PHY初始化數(shù)據(jù),也可以存儲(chǔ)其他數(shù)據(jù),一些斷電存儲(chǔ)的數(shù)據(jù)建議放在這里
- 0xD000-0xF000 OTA data分區(qū),系統(tǒng)從哪個(gè)app分區(qū)啟動(dòng)由這里存儲(chǔ)的數(shù)據(jù)決定
- 0xF000-0x10000 PHy_init分區(qū),用于存儲(chǔ)的PHY初始化數(shù)據(jù)
- 0x10000-0x3FFFFF Factory APP分區(qū),保存出廠應(yīng)用程序,分區(qū)表有工廠應(yīng)用程序就會(huì)啟動(dòng)這個(gè)分區(qū)的程序
- Core dump分區(qū),查找系統(tǒng)崩潰時(shí)的軟件錯(cuò)誤,以便開發(fā)者分析原因
- OTA0/OTA1分區(qū),保存OTA下載固件,交替保存在這兩個(gè)分區(qū),鏡像驗(yàn)證無(wú)誤之后,會(huì)更新OTA data分區(qū),分配好下一次應(yīng)該從哪里啟動(dòng)。
- fctry分區(qū),保存阿里云四元組,這個(gè)就是私有數(shù)據(jù)了,可以在存儲(chǔ)空間的最后分配一些空間用于保存一些APP的激活數(shù)據(jù)之類的,沒有用到就可以忽略。
到這里,大家應(yīng)該都了解了吧,正常情況下我們用系統(tǒng)內(nèi)置的一些默認(rèn)的就可以,當(dāng)然,我們也可以自定義分區(qū)表,總之就是根據(jù)自己的具體情況具體分配,這里不具體展開說(shuō),后面有需要再展開說(shuō)。
程序燒錄
代碼燒錄就是把上面的每個(gè)分區(qū)的文件分別燒錄進(jìn)FLASH芯片中,我們以一個(gè)默認(rèn)的例子,看下Arduino是怎么燒錄的:
如上圖所示,根據(jù)每個(gè)分區(qū)的地址,將用到的各個(gè)分區(qū)的內(nèi)容依次燒錄進(jìn)FLASH中,關(guān)于存儲(chǔ)空間的分配我們就講到這里。
程序啟動(dòng)過(guò)程
ESP32,是如何運(yùn)行RTOS的?
1、 第一階段bootloader(ROM中)加載第二階段bootloader(位于FLASH 0X1000)
2、 第二階段的boot loader加載分區(qū)表和MAIN APP應(yīng)用程序(其實(shí)就是freertos了)
main APP包含RAM段和Flash段
① 去0X8000加載分區(qū)表,配置兩個(gè)CPU(PRO CPU和APP CPU)的MMU,但只使能PRO cpu的flash,一旦被加載,就會(huì)跳到main APP的入口
3、執(zhí)行main APP,此時(shí),第二個(gè)CPU和RTOS調(diào)度器都會(huì)運(yùn)行
入口調(diào)用 componments/esp32/cpu_start.c中的call_start_cpu0函數(shù),
此函數(shù)會(huì)調(diào)用 call_start_cpu1.執(zhí)行后PRO CPU執(zhí)行start_cpu0,APP CPU執(zhí)行start_cpu1
最終會(huì)調(diào)用app_main函數(shù)
我們打開ESP32 SDK中的core文件夾,里面有個(gè)main.cpp文件,打開我們就知道,app_main調(diào)用了loopTask函數(shù),loopTask會(huì)先調(diào)用setup函數(shù),再調(diào)用loop函數(shù),loop函數(shù)會(huì)一直死循環(huán),所以我們可以在setup里創(chuàng)建任務(wù)。
我們Arduino中的setup與loop函數(shù)就是上面的函數(shù)中調(diào)用的,這里我們也可以看出,ESP32在Arduino下不是裸奔的,是跑的FreeRTOS操作系統(tǒng)的!
感謝大家,關(guān)于ESP32的學(xué)習(xí),希望大家Enjoy!
-
FlaSh
+關(guān)注
關(guān)注
10文章
1614瀏覽量
147652 -
存儲(chǔ)
+關(guān)注
關(guān)注
13文章
4226瀏覽量
85574 -
Arduino
+關(guān)注
關(guān)注
187文章
6457瀏覽量
186501 -
程序燒錄
+關(guān)注
關(guān)注
0文章
9瀏覽量
6837 -
ESP32
+關(guān)注
關(guān)注
17文章
950瀏覽量
16992
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論