文章目錄
-
- 1.系統f複位階段需要關注的GPIO
- 2.片上存儲
- 3.位址映射
- 4.時鐘配置
- 5.入口函數
- 6,分區表
1.系統f複位階段需要關注的GPIO
ESP32-S2 系列晶片共有 3 個 Strapping 管腳(GPIO0,GPIO45,GPIO46),這幾個IO口預設都是内部上拉/下拉的,在晶片的系統複位(上電複位、RTC 看門狗複位、欠壓複位、模拟超級看門狗 (analog super watchdog) 複位、晶
振時鐘毛刺檢測複位)過程中,這3個GPIO的狀态會被寫入鎖存器中,直到MCU關機。

- GPIO45:用來選擇外部flash的供電電源,此外如果flash是1.8V的話,那麼其它信号線也要做一下電平轉換。
以esp32-s2開發需要了解的地方(esp32-s2為例) - GPIO0:用序列槽下載下傳時,需要提前将此IO短接到GND,然後在上電,即可進入下載下傳模式。
- GPIO46:用來關閉日志的操作,關閉日志列印,可以節約部分功耗。此外datasheet中說可以由 eFuse 位控制切換到 DAC_1 管腳(這個後面在研究)
2.片上存儲
ESP32-S2 系列晶片片上存儲包括:
- 128 KB ROM:用于程式啟動和核心功能調用,(樂鑫把常用的函數封裝到ROM中,這裡也有BL0,第一階段boot)
- 320 KB 片上 SRAM:用于資料和指令存儲
- RTC 快速存儲器:為 8 KB SRAM,可被主 CPU 通路,在 Deep-sleep 模式下可以儲存資料
- RTC 慢速存儲器:為 8 KB SRAM,可被主 CPU 或協處理器通路,在 Deep-sleep 模式下可以儲存資料
- 4 Kbit eFuse:其中 1792 位保留給使用者使用,例如用于存儲密鑰和裝置 ID
3.位址映射
更詳細的可以檢視官方文檔
下圖中的灰色部分為ROM預留的記憶體,不是開發給客戶的。灰色位址不可用
同時從esp-idf中發現,這些常用的c庫函數都 已經賦予了指針,是以大膽猜測,這些函數已經內建進ROM中了
.....
memccpy = 0x4001ab00;
memchr = 0x4001ab24;
memcmp = 0x4001ab40;
memcpy = 0x4001aba8;
memmove = 0x4001acb0;
memrchr = 0x4001acec;
memset = 0x4001ad3c;
在esp32s2.rom.ld中能夠看到,gpio相關的操作函數也都封裝了進去,看來樂鑫隐藏了一些寄存器的額細節。讓使用者更多的關心應用程式的編寫。
PROVIDE ( gpio_input_get = 0x400193a0 );
PROVIDE ( gpio_input_get_high = 0x400193b4 );
PROVIDE ( gpio_matrix_in = 0x40019430 );
PROVIDE ( gpio_matrix_out = 0x40019460 );
PROVIDE ( gpio_output_disable = 0x400194dc );
PROVIDE ( gpio_output_enable = 0x400194b0 );
PROVIDE ( gpio_output_set = 0x4001933c );
PROVIDE ( gpio_output_set_high = 0x40019374 );
PROVIDE ( gpio_pad_hold = 0x40019654 );
PROVIDE ( gpio_pad_input_disable = 0x400195f0 );
PROVIDE ( gpio_pad_input_enable = 0x400195cc );
PROVIDE ( gpio_pad_pulldown = 0x40019598 );
PROVIDE ( gpio_pad_pullup = 0x40019564 );
PROVIDE ( gpio_pad_select_gpio = 0x40019510 );
PROVIDE ( gpio_pad_set_drv = 0x40019538 );
PROVIDE ( gpio_pad_unhold = 0x4001961c );
PROVIDE ( gpio_pin_wakeup_disable = 0x40019404 );
PROVIDE ( gpio_pin_wakeup_enable = 0x400193c8 );
4.時鐘配置
參考官方文檔
5.入口函數
esp32内部rom已經內建了第一階段代碼,第二階段的bootloader的入口函數為下面的call_start_cpu0();
MEMORY
{
/* IRAM POOL1, used for APP CPU cache. Bootloader runs from here during the final stage of loading the app because APP CPU is still held in reset, the main app enables APP CPU cache */
iram_loader_seg (RWX) : org = 0x40078000, len = 0x8000 /* 32KB, APP CPU cache */
/* 63kB, IRAM. We skip the first 1k to prevent the entry point being
placed into the same range as exception vectors in the app.
This leads to idf_monitor decoding ROM bootloader "entry 0x40080xxx"
message as one of the exception vectors, which looks scary to users.
*/
iram_seg (RWX) : org = 0x40080400, len = 0xfc00
/* 64k at the end of DRAM, after ROM bootloader stack */
dram_seg (RW) : org = 0x3FFF0000, len = 0x10000
}
/* Default entry point: */
ENTRY(call_start_cpu0);
6,分區表
分區表如下所示,很清晰,不多說,可以看到分區表在0x8000偏移位置。
燒寫指令(可以對比上面的分區表檢視)
我編譯的helloworld.bin檔案就燒寫到了0x10000 偏移位址,這個位址對應Factory app.
D:\espressif\python_env\idf4.2_py3.9_env\Scripts\python.exe ..\..\esp-idf-v4.2.1\components\esptool_py\esptool\esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 build\bootloader\bootloader.bin 0x8000 build\partition_table\partition-table.bin 0x10000 build\hello-world.bin