《ESP32-S3使用指南—IDF版 V1.6》第三章 ESP32-S3基礎知識

正点原子發表於2025-01-22

第三章 ESP32-S3基礎知識

1)實驗平臺:正點原子DNESP32S3開發板

2)章節摘自【正點原子】ESP32-S3使用指南—IDF版 V1.6

3)購買連結:https://detail.tmall.com/item.htm?&id=768499342659

4)全套實驗原始碼+手冊+影片下載地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32S3.html

5)正點原子官方B站:https://space.bilibili.com/394620890

6)正點原子DNESP32S3開發板技術交流群:132780729

在本章中,我們將深入探索ESP32-S3這款備受矚目的微控制器。我們將詳細闡述其定義、核心資源、功能應用,以及如何選擇適合您專案的ESP32-S3型號。透過本章的學習,您將全面瞭解ESP32-S3,為您的物聯網專案選擇合適的硬體平臺奠定堅實基礎。
本章分為如下幾個小節:
3.1 為什麼選擇ESP32-S3
3.2初識ESP32-S3
3.3 ESP32-S3資源簡介
3.4 S3系列型號對比
3.5 ESP32-S3功能概述
3.6 ESP32-S3啟動例程

3.1 為什麼選擇ESP32-S3
在研發之初,作者也對比過樂鑫官方推出的幾款MCU系列,經過它們各自的功能及應用場景來分析,最終作者選擇S系列的S3型號。
下面,作者比較一下樂鑫推出的晶片有哪些特點:

表3.1.1 樂鑫各系列MCU硬體區別

在上述表格中,我們可以看到樂鑫推出的各系列MCU在硬體方面存在一些差異。下面我將繼續分析這些差異及其對應用場景的影響。
1,在核心數量方面:S系列和ESP32系列支援單核和雙核處理器,而C系列和H系列僅支援單核處理器。這意味著S系列和ESP32系列在處理多工和高強度計算方面具有更強的效能。對於需要高效能、多工處理的應用場景,如複雜演算法處理、大資料分析等,S系列和ESP32系列可能更合適。
2,在時脈頻率方面,S系列和ESP32系列的時脈頻率範圍為80~240MHz,而C系列和H系列的時脈頻率分別為120MHz和96MHz。較高的時脈頻率意味著更快的處理速度和更高的效能。對於需要高速處理的應用場景,如實時訊號處理、高速資料採集等,S系列和ESP32系列可能更合適。
3,在引出程式設計IO方面,S系列和ESP32系列的引出程式設計IO數量較多,而C系列和H系列的引出程式設計IO數量較少。這表明S系列和ESP32系列在程式設計介面的多樣性和靈活性方面具有優勢。對於需要連線多種外設和感測器的應用場景,S系列和ESP32系列可能更合適。
4,在神經網路加速方面,只有S系列支援神經網路加速功能。這意味著選擇S系列可以更好地滿足深度學習、影像識別等應用場景的需求。對於需要加速神經網路運算的應用場景,如智慧家居控制、智慧安防等,S系列可能更合適。
5,在通訊協議方面,所有系列都支援2.4G Wi-Fi和藍芽(BLE),這意味著它們在無線通訊方面具有良好的相容性。
6,在儲存器方面,各系列MCU的SRAM和ROM大小有所不同。較大的儲存器可以提供更多的程式執行空間和資料儲存空間,以滿足更復雜的應用需求。對於需要處理大量資料和執行復雜程式的應用場景,如物聯網閘道器、智慧儀表等,S系列和ESP32系列可能更合適。
綜上所述,樂鑫推出的各系列MCU在硬體方面各有特點,選擇哪個系列取決於具體的應用場景和需求。對於需要高效能、多核處理和神經網路加速的應用場景,S系列可能是更好的選擇;而對於簡單的物聯網應用場景,C系列或H系列可能更合適。
正點原子選擇S系列的S3型號作為開發板的核心晶片,是為了讀者提供更好的學習資源和開發體驗,幫助讀者更好地掌握物聯網和嵌入式開發的相關技術。
另外,樂鑫科技還提供了一個線上選型工具(https://products.espressif.com/#/product-selector?language=zh),名為ESP Product Selector。它可以幫助使用者全面瞭解樂鑫產品與方案、提高產品選型和開發效率,如下圖所示。

圖3.1.1 樂鑫線上選型工具

上圖①顯示了篩選工具的選擇,左邊是產品選型,右邊是產品對比。上圖②表示產品選型的功能篩選,主要根據客戶的需求來選擇,例如工作溫度、單/雙核、是否具備天線等條件,來選擇自己心儀的晶片/模組或者開發板。上圖③表示功能篩選之後的結果選擇,例如晶片/模組或者滿足條件的開發板。最後,上圖④表示篩選的結果,如果篩選結果是晶片/模組,那麼它就會顯示符合篩選的晶片型號或者模組。

3.2 初識ESP32-S3
ESP32-S3是一款由樂鑫公司開發的物聯網晶片,它具有一些非常獨特的功能和特點。下圖為晶片的功能框圖。

圖3.2.1 ESP32-S3 功能框圖

結合《esp32-s3_datasheet_cn.pdf》資料手冊和上圖的內容,簡單歸納5個內容。
1,架構和效能:ESP32-S3採用Xtensa® LX7 CPU,這是一個哈佛結構的雙核系統。它具有獨立的指令匯流排和資料匯流排,所有的內部儲存器、外部儲存器以及外設都分佈在這兩條匯流排上。這種架構使得CPU可以同時讀取指令和資料,從而提高了處理速度。
2,儲存:ESP32-S3具有豐富的儲存空間。它內部有384 KB的內部ROM,512 KB的內部SRAM,以及8 KB的RTC快速儲存器和8 KB的RTC慢速儲存器。此外,它還支援最大1 GB的片外FLASH和最大1 GB的片外RAM。
3,外設:ESP32-S3具有許多外設,總計有45個模組/外設。其中11個具有GDMA(Generic DMA)功能,可以用來進行資料塊的傳輸,減輕CPU的負擔,提高整體效能。
4,通訊:ESP32-S3同時支援WIFI和藍芽功能,應用領域貫穿移動裝置、可穿戴電子裝置、智慧家居等。在2.4GHz頻帶支援20MHz和40MHz頻寬。
5,向量指令:ESP32-S3增加了用於加速神經網路計算和訊號處理等工作的向量指令。這些向量指令可以大大提高晶片在AI方面的計算速度和效率。
ESP32-S3是一款功能強大、效能豐富的物聯網晶片,適用於各種物聯網應用場景。以上資訊僅供參考,如需瞭解更多資訊,請訪問樂鑫公司官網查詢相關資料。

3.3 ESP32-S3資源簡介
下面來看看ESP32-S3具體的內部資源,如下表所示。

表4.3.1 ESP32-S3內部資源表

由表可知,ESP32內部資源還是非常豐富的,本書將針對這些資源進行詳細的使用介紹,並提供豐富的例程,供大家參考學習,相信經過本書的學習,您會對ESP32-S3系列晶片有一個全面的瞭解和掌握。
關於ESP32-S3內部資源的詳細介紹,請大家參考“光碟A 盤7,硬體資料2,晶片資料esp32-s3_technical_reference_manual_cn.pdf”,該文件即《ESP32-S3的技術手冊》,裡面有 ESP32-S3詳細的資源說明和相關效能引數。

3.4 S3系列型號對比
樂鑫S3系列型號包括ESP32-S3、ESP32-S3R2、ESP32-S3R8和ESP32-S3FN8等。這些型號在硬體配置、功能和應用場景方面略有不同。不同型號的MCU都有不同的應用場景,下面我們來看一下這些型號的命名規則,如下圖所示。

圖3.4.1 ESP32-S3系列晶片命名規則

從上圖可以看到,F表示內建FLASH;H/N表示FLASH溫度(H:高溫,N:常溫);x表示內建FLASH大小(MB);R表示內建PSRAM;x表示內建PSRAM大小(MB);V表示僅支援外部1.8v spi flash。為了讓讀者更清晰瞭解ESP32-S3命名規則,這裡作者以ESP32-S3FH4R2這一款晶片為例,繪畫一副清晰的命名示意圖,如下圖所示。

圖3.4.2 ESP32-S3FH4R2命名解析

根據上述兩張圖的分析,我們可以瞭解到樂鑫S3系列的命名規則和特點。除了S3系列的晶片之外,樂鑫還推出了S3系列的模組,它是S3系列晶片的簡易系統。
樂鑫S3系列模組是基於S3系列晶片的子系統,它已經設計好了外圍電路,簡化了開發過程,讓開發者可以更快速地使用S3系列晶片進行開發。透過使用S3系列模組,開發者可以更容易地實現特定功能,縮短開發週期,提高開發效率。
樂鑫推出了ESP32-S3-WROOM-1和ESP32-S3-WROOM-1U兩款通用型Wi-Fi+低功耗藍芽MCU模組,如下圖所示,它們搭載ESP32-S3系列晶片。除具有豐富的外設介面外,模組還擁有強大的神經網路運算能力和訊號處理能力,適用於AIoT領域的多種應用場景,例如喚醒詞檢測和語音命令識別、人臉檢測和識別、智慧家居、智慧家電、智慧控制皮膚、智慧揚聲器等。


圖3.4.3 ESP32-S3-WROOM-1和ESP32-S3-WROOM-1U的功能框圖

從上圖可知,ESP32-S3-WROOM-1採用PCB板載天線,而ESP32-S3-WROOM-1U採用聯結器連線外部天線。兩款模組均有多種晶片型號可供選擇,具體見下表所示:

表3.4.1 通用型模組的命名

根據上表,可以看出這兩款模組的主控晶片是ESP32-S3和ESP32-S3Rx,它們都屬於樂鑫的ESP32-S3系列晶片。之前作者已經詳細講解了ESP32-S3系列晶片的命令規則,可以得出這兩款通用模組都是外接Flash儲存器,並且內建有PSRAM(主控晶片ESP32-S3沒有內建PSRAM)。下面我們以ESP32-S3-WROOM-1-N16R8模組為例,來講解模組的命名規則,如下圖所示。

圖3.4.3 模組的命令規則

透過了解模組內建的主控晶片型別,開發者可以更好地理解該模組的功能和特點,並根據需要進行相應的開發和應用。正點原子ESP32-S3開發板是以ESP32-S3-WROOM-1-N16R8模組作為主控,它可以提供穩定的控制系統和高效的資料處理能力,同時引出的IO可以滿足各種應用需求。

3.5 ESP32-S3功能概述
3.5.1 系統和儲存器
ESP32-S3採用哈佛結構Xtensa® LX7 CPU構成雙核系統。所有的內部儲存器、外部儲存器以及外設都分佈在CPU 的匯流排上。
以下是ESP32-S3的主要特性:
1,地址空間:ESP32-S3 擁有豐富的地址空間,包括內部儲存器指令地址空間、內部儲存器資料地址空間、外設地址空間、外部儲存器指令虛地址空間、外部儲存器資料虛地址空間、內部DMA地址空間和外部DMA地址空間。這些地址空間為晶片的各個部分提供了獨立的儲存空間。
2,內部儲存器:ESP32-S3內部儲存器包括384 KB的內部ROM、512 KB的內部SRAM、8 KB的RTC快速儲存器和 8 KB 的 RTC 慢速儲存器。這些儲存器為晶片提供了儲存和讀取資料的能力。
3,外部儲存器:ESP32-S3支援最大1 GB的片外flash和最大1 GB 的片外 RAM。這些外部儲存器可以用來儲存大量的程式程式碼和資料,以滿足複雜應用的需求。
4,外設空間:ESP32-S3總計有45個模組/外設,這些外設為晶片提供了豐富的輸入輸出介面和特殊功能。
5,GDMA(Generic DMA):ESP32-S3具有11個具有GDMA功能的模組/外設,這些 GDMA 外設可以用來進行資料塊的傳輸,從而減輕CPU的負擔,提高整體效能。
下圖是ESP32-S3地址空間對映結構圖,闡述了內部儲存器地址空間對映、外部儲存器地址空間對映和模組/外設地址對映的系統結構圖,以及GDMA與各部分的聯絡示意圖。

圖3.5.1 系統結構與地址對映結構

上圖中,灰色背景的地址空間不可用,紅色五角星表示對應儲存器和外設可以被協調器訪問。由於ESP32-S3系統是由兩個哈佛結構Xtensa® LX7 CPU構成,這兩個CPU能夠訪問的地址空間範圍是完全一致的。上圖中,地址0x40000000以下部分屬於資料匯流排的地址範圍;地址0x40000000~4FFFFFFF部分位指令匯流排的地址範圍,其他是資料匯流排與指令匯流排的地址範圍,即內部儲存器、外部儲存器和外設等對映的記憶體地址。
CPU的資料匯流排與指令匯流排都為小端序(將多位元組資料的低位放在較小的地址處,高位放在較大的地址處)。CPU可以透過資料匯流排進行單位元組、雙位元組、4位元組、16位元組的資料訪問。CPU也可以透過指令匯流排進行資料訪問,但必須是4位元組對齊方式;非對齊資料訪問會導致CPU工作異常。CPU的工作如下:
① 透過資料匯流排與指令匯流排直接訪問內部儲存器。
② 透過Cache直接訪問對映到地址空間的外部儲存器。
③ 透過資料匯流排直接訪問模組/外設。
系統中部分內部儲存器與部分外部儲存器既可以被資料匯流排訪問也可以被指令匯流排訪問,這種情況下,CPU可以透過多個地址訪問到同一目標。

3.5.1.1 內部儲存器
圖3.5.1中的①、②、④和⑥部分組成ESP32-S3內部儲存器。
上圖①:Internal ROM(384KB)是隻讀儲存器、不可程式設計,用來存放系統底層的韌體(程式指令和一些只讀資料)。
上圖②:Internal SRAM(512 KB)是易失性儲存器,可以快速響應CPU的訪問請求,通常只需一個CPU時鐘週期。其中,SRAM的一部分可以被配置成外部儲存器訪問的快取(Cache),但這種情況下無法被CPU訪問;另外,某些部分只可以被CPU的指令匯流排訪問;某些部分只可以被CPU的資料匯流排訪問;還有某些部分既可被CPU的指令匯流排訪問,也可被CPU的資料匯流排訪問。
上圖④和⑥:RTC Memory(16 KB)RTC 儲存器以靜態RAM(SRAM)方式實現,因此也是易失性儲存器。但是,在deep sleep模式下,存放在RTC儲存器中的資料不會丟失。其中, RTC FAST memory(8 KB)只可以被 CPU 訪問,不可以被協處理器訪問,通常用來存放一些在 Deep Sleep 模式下仍需保持的程式指令和資料。而RTC SLOW memory (8KB)既可以被CPU訪問,又可以被協處理器訪問,因此通常用來存放一些CPU和協處理器需要共享的程式指令和資料。
注意:所有的內部儲存器都接受許可權管理。只有獲取到訪問內部儲存器的訪問許可權,才可以執行正常的訪問操作,CPU訪問內部儲存器時才可以被響應。關於許可權管理的更多資訊,請參考《esp32-s3_technical_reference_manual_cn.pdf》章節 15 許可權控制(PMS)。

3.5.1.2 外部儲存器
圖3.5.1中的⑦、⑧和⑨可見。CPU藉助快取記憶體(Cache)來訪問外部儲存器。 Cache 將根據記憶體管理單元(MMU)中的資訊把 CPU指令匯流排或資料匯流排的地址變換為訪問片外flash與片外RAM的實地址。經過變換的實地址所組成的實地址空間最大支援1 GB 的片外flash與1 GB的片外RAM。前面我們討論知道,ESP32-S3採用雙核共享ICache 和DCache 結構,以便當CPU的指令匯流排和資料匯流排同時發起請求時,也可以迅速響應。當雙核同時訪問ICache 時,系統會做以下判斷,如下圖所示。

圖3.5.1.2.1 Cache系統框圖

當兩個核的指令匯流排同時訪問ICache/DCache時,由仲裁器決定誰先獲得訪問ICache/DCache的許可權。當Cache缺失(處理器所要訪問的儲存塊不在快取記憶體中的現象)時,Cache控制器會向外部儲存器發起請求,當ICache和DCache同時發起外部儲存器請求時,由仲裁器決定誰先獲得外部儲存器的使用權。
①:ICache的快取大小可配置為16 KB或32KB,塊大小可以配置為16B或32B,當ICache快取大小配置為32KB時停用16B塊大小模式。
②:DCache的快取大小可配置為32 KB或64 KB,塊大小可以配置為16B、32B 或64B,當DCache快取大小配置為64 KB 時停用16B 塊大小模式。
返回到圖4.5.1,外部儲存器透過快取記憶體(Cache),ESP32-S3一次最多可以同時訪問32MB的指令匯流排地址空間和32MB的資料匯流排地址空間。32 MB的指令匯流排地址空間,透過指令快取(ICache)以64 KB為單位對映到片外flash或片外RAM,支援 4 位元組對齊的讀訪問或取指訪問,而32 MB的資料匯流排地址空間,是透過資料快取(DCache)以64 KB為單位對映到片外RAM,支援單位元組、雙位元組、4位元組、16位元組的讀寫訪問。這部分地址空間也可以用作只讀資料空間,對映到片外 flash 或片外RAM。
下表列出了訪問外部儲存器時CPU的資料匯流排和指令匯流排與Cache的對應關係。

表3.5.1.2.1 外部儲存器地址對映

同樣,想要操作外部儲存器的讀寫,需獲取訪問許可權,CPU訪問外部儲存器時才能被響應。關於許可權管理的更多資訊,請參考《esp32-s3_technical_reference_manual_cn.pdf》15許可權控制(PMS)。

3.5.1.3 模組/外設
圖3.5.1中的⑤就是模組/外設地址空間地址,CPU就是透過該空間地址來訪問模組/外設的。下表是模組/外設地址空間的各段地址與其能訪問到的模組/外設對映關係。

表3.5.1.3.1 模組/外設地址空間對映部分表

從上表可以得知,要操作外設的暫存器,首先需要知道該外設的首地址。然後,我們可以使用一些底層的程式語言,如C語言或組合語言,來編寫程式以設定外設暫存器的值,從而控制外設的行為。例如,透過設定GPIO暫存器的值,我們可以控制某個LED燈的亮滅;同樣地,設定UART暫存器的值可以用來傳送和接收資料。
與內部儲存器和外部儲存器訪問類似,CPU要想訪問某一個模組/外設,需要先獲取該模組/外設的訪問許可權,否則訪問將不會被響應。關於許可權管理的更多資訊,請參考《esp32-s3_technical_reference_manual_cn.pdf》章節15許可權控制(PMS)。

3.5.1.4 通用GDMA控制器
通用直接儲存訪問(General Direct Memory Access, GDMA)用於在外設與儲存器之間以及儲存器與儲存器之間提供高速資料傳輸軟體可以在無需任何CPU操作的情況下透過GDMA快速搬移資料,從而降低了CPU的工作負載,提高了效率。ESP32-S3的GDMA控制器採用AHB匯流排架構,以位元組為單位進行資料傳輸,支援軟體程式設計控制傳輸資料量,支援連結串列傳輸,同時支援訪問內部RAM時的INCR burst傳輸。其能夠訪問的最大內部RAM地址空間為480 KB,最大外部RAM地址空間為32 MB。該控制器包含5個接收通道和5個傳送通道,每個通道都可以訪問內部和外部RAM,並且支援可配置的外設選擇。最後,GDMA控制器採用固定優先順序及輪詢仲裁機制來管理通道間的傳輸。
正如前文所述,GDMA共有10個獨立的通道,其中包括5個接收通道和5個傳送通道。這10個通道被支援GDMA功能的外設所共享,也就是說使用者可以將通道分配給任何支援GDMA功能的外設。這些外設包括SPI2、SPI3、UHCI0、I2S0、I2S1、LCD/CAM、AES、SHA、ADC和RMT等。根據圖3.3.1的③所示的連線關係再一次驗證了,這些外設都可以使用GDMA傳輸資料。此外,每個GDMA通道都具備訪問內部RAM或外部RAM的能力,這使得ESP32-S3在處理複雜的資料傳輸任務時具有顯著優勢。
下圖是GDMA功能模組和GDMA通道示意圖。

圖3.5.1.4.1 具有GDMA功能的模組和GDMA通道示意圖

從上圖可知,每一個外設都可以使用任意一條通道進行資料傳輸。然而,這些通道分為不同的型別。當使用GDMA接收資料時,可以選擇任意的RXn通道(n:0~4);相反,當使用GDMA傳送資料時,則需要選擇任務的TXn通道(n:0~4)。這種通道的分類和選擇方式使得資料傳輸更加高效和靈活。
ESP32-S3中有11個外設/模組可以和GDMA聯合工作,如下圖所示。其中的 11 根豎線依次對應這11個具有GDMA功能的外設/模組,橫線表示GDMA的某一個通道(可以是任意一個通道),豎線與橫線的交點表示對應外設/模組可以訪問GDMA的某一個通道。同一行上有多個交點則表示這幾個外設/模組不可以同時開啟GDMA功能。

圖3.5.1.4.2 具有GDMA功能的外設

具有GDMA功能的模組/外設透過GDMA可以訪問任何GDMA可以訪問到的儲存器。更多關於GDMA的資訊,請參考《esp32-s3_technical_reference_manual_cn.pdf》章節 3 通用 DMA 控制器(GDMA)。
與前面小節一樣,當使用GDMA訪問任何儲存器時,都需要獲取對應的訪問許可權,否則訪問將會失敗。

3.5.2 IO MUX和GPIO交換矩陣
ESP32-S3 晶片有45個物理通用輸入輸出管腳(GPIO Pin)。每個管腳都可用作一個通用輸入輸出,或連線一個內部外設訊號。利用GPIO交換矩陣、IO MUX(IO複用選擇器)和RTC IO MUX(RTC複用選擇器),可配置外設模組的輸入訊號來源於任何的GPIO管腳,並且外設模組的輸出訊號也可連線到任意GPIO管腳。這些模組共同組成了晶片的輸入輸出控制。值得注意的是,這45個物理GPIO管腳的編號為021、2648。這些管腳即可作為輸入有可作為輸出管腳。正如前文所述,正點原子選擇ESP32-S3-WROOM-1-N16R8模組作為主控,但由於該模組只有36個實際引腳的物理GPIO管腳。這是因為該模組的Flash和PSRAM使用了八線SPI即Octal SPI模式,這些模式共佔用了12個GPIO管腳。而且,該模組還將IO35、IO36、IO37引出,所以最終的管腳數量為45-12+3,即36個GPIO管腳。
下圖是從《esp32-s3_datasheet_cn.pdf》資料手冊擷取下來的,主要描述Flash和PSRAM使用八線SPI模式下的管腳。

圖3.5.2.1 晶片與封裝內flash/PSRAM的管腳對應關係

需要注意的是,正點原子ESP32-S3開發板的原理圖並沒有使用IO35-IO37號管腳,所以不存在共用Falsh和PSRAM管腳。
下面我們來看一下這個模組的實物圖和引腳分佈圖,如下圖所示。


圖3.5.2.2 ESP32-S3-WROOM-1實物圖和引腳分佈圖

從上圖可以得知,左邊的圖片是該模組的3D實物圖,而右邊的圖片是該模組的管腳分佈圖。雖然這些管腳是無序的,但它們都可以被複用為其他功能(除個別功能外),例如SPI、串列埠、IIC等協議。這是ESP32相比其他MCU的優勢之一,它具有更多的可複用管腳,可以支援更多的外設和協議。
接下來,我們來看一下模組管腳預設複用管腳和管腳功能釋義,如下表所示。


表3.5.2.1 管腳定義

上表是ESP32-S3-WROOM-1-N16R8模組的管腳定義,下面作者根據這個表格來講解GPIO互動矩陣及IO MUX複用的知識。
下圖為GPIO交換矩陣、IO MUX和RTC IO MUX將訊號引入外設和引出至管腳的具體過程。

圖3.5.2.3 IO MUX、RTC IO MUX和GPIO交換矩陣結構框圖

首先,作者說明一下上圖帶有顏色線條和標籤(Ⅰ、Ⅱ、Ⅲ、Ⅳ)的作用,紅色線條表示輸出方向;紫色線條代表RTC IO管腳的輸出方向;黃色線條代表RTC IO管腳輸入方向;標籤代表輸入/輸出分支的節點。
從上圖可知,ESP32-S3管腳具有預設功能,即每個IO管腳直接連線至一組特定的片上外設。在運動時,可透過IO MUX和IO矩陣配置連線管腳外設。從上表4.5.2.1可知,有些IO管腳預設了RTC和模擬功能,有些IO管腳預設了SPI、IIC等功能。
上圖右邊兩個“Pin X supplied by VDD3P3_CPU/RTC”框圖為晶片焊盤 (PAD) 的內部結構,即晶片邏輯與GPIO管腳之間的電氣介面。ESP32-S3的45個GPIO管腳均採用此結構,如下圖所示。

圖3.5.2.4 焊盤內部結構

上圖中的IE表示輸入使能;OE表示輸出使能;WPU表示內部弱上拉;WPD表示內部弱下拉,它們實現了晶片封裝內晶片與GPIO管腳之間的物理連線。

一、“Pin X supplied by VDD3P3_CPU”晶片焊盤輸入流程(圖4.5.1.5.3中的綠色線條)
從上圖3.5.2.3可知,輸入訊號透過兩條通道(Ⅳ處)到達輸入訊號終端。第一條通道(①)無需經過GPIO SYNC模組的同步處理,而是透過IO_MUX_n_REGIO暫存器(該暫存器的IO_MUX_MCU_SEL位作用為訊號選擇IO MUX功能,為0選擇Function 0,為1選擇Function 1(GPIO),Function功能請看《esp32-s3_technical_reference_manual_cn.pdf》章節6.12 IO MUX管腳功能列表)配置進入GPIO交換矩陣,然後輸入訊號進入旁路GPIO交換矩陣(GPIO_SIMy_IN_SET)。另一方面,另一條通道經過GPIO SYNC模組的同步處理,然後將訊號時鐘同步APB匯流排時鐘,隨後進入GPIO交換矩陣。在這個交換矩陣中,通道的開通是由暫存器GPIO_FUNCy_IN_SEL_CFG_REG進行配置的。這個暫存器的描述如下。

圖3.5.2.5 GPIO_FUNCy_IN_SEL_CFG_REG描述

從上圖可知,GPIO_FUNCy_IN_SEL(其中y為GPIO的管腳號)是外設輸入訊號控制位。如果GPIO_FUNCy_IN_SEL的值為0x38,則輸入訊號被視為高電平;如果GPIO_FUNCy_IN_SEL的值為0x3C,則輸入訊號被視為低電平。GPIO_FUNCy_IN_INV_SEL(其中y為GPIO的管腳號)是反轉輸入值的控制位。如果輸入是高電平,經過反轉操作後變為低電平;否則,保持高電平。GPIO_SIMy_IN_SET(其中y為GPIO的管腳號)是旁路GPIO交換矩陣,它的作用是提高高頻數字訊號的特性。如果GPIO_SIMy_IN_SET的值為1,則選擇GPIO交換矩陣作為輸入;否則,選擇IO MUX作為輸入,最終訊號到達輸入訊號終端。

二、“Pin X supplied by VDD3P3_CPU”晶片焊盤輸出流程(圖4.5.1.5.3中的紅色線條)
從上圖3.5.2.3可知,輸出訊號也是分為兩個通道傳輸(Ⅰ處),如果輸出訊號是普通的GPIO輸出,則該訊號經過GPIO矩陣,再由該矩陣輸出到IO MUX,再到輸出管腳,這個流程由GPIO_FUNCy_OUT_SEL_CFG_REG暫存器配置,如下所示:

圖3.5.2.6 GPIO_FUNCy_OUT_SEL_CFG_REG描述

從上圖可知,GPIO_FUNCx_OUT_SEL(其中x為GPIO的管腳號)是外設輸出訊號控制位。當GPIO0管腳輸出訊號時,該值為0。GPIO_FUNCx_OUT _INV_SEL(其中x為GPIO的管腳號)是反轉輸出值的控制位。如果輸出是高電平,經過反轉操作後變為低電平;否則,保持高電平。然後透過IO_MUX_n_REGIO暫存器(該暫存器的IO_MUX_MCU_SEL位的作用是訊號選擇IO MUX功能,為0選擇Function 0,為1選擇Function 1(GPIO)。有關Function的詳細資訊,請參閱《esp32-s3_technical_reference_manual_cn.pdf》第6.12節中的IO MUX管腳功能列表)配置,訊號最終到達輸出管腳。
另一條通道是複用功能輸出的通道。該通道由輸出訊號的起始端到IO MUX複用電路,然後IO_MUX_n_REGIO暫存器的IO_MUX_MCU_SEL位不為1(GPIO模式),為複用功能,最後經過Ⅱ處輸出到輸出端(GPIO和RTC IO)。

三、“Pin X supplied by VDD3P3_RTC”晶片焊盤輸入流程(圖4.5.1.5.3中的黃色線條)
根據表3.5.2.1和圖3.5.2.3所示,ESP32-S3中有22個GPIO管腳具有低功耗(RTC)效能和模擬功能,由RTC子系統控制。這些功能不使用 IO MUX 和GPIO交換矩陣,而是使用RTC IO MUX將22個RTC輸入輸出訊號引入RTC子系統。當這些管腳被配置為RTC GPIO管腳,作為輸出管腳時仍然能夠在晶片處於Deep-sleep模式下保持輸出電平值或者作為輸入管腳使用時可以將晶片從Deep-sleep中喚醒。
如果它們被用作普通輸入,則輸入流程與“Pin X supplied by VDD3P3_CPU”的輸入流程相同。如果它們作為RTC複用功能,則輸入訊號會進入RTC IO MUX複用電路,並最終到達RTC GPIO矩陣。

3.5.3 復位與時鐘
3.5.3.1 ESP32-S3復位等級
ESP32-S3提供四種級別的復位方式,分別是CPU復位、核心復位、系統復位和晶片復位。除晶片復位外其它復位方式不影響片上記憶體儲存的資料。下圖展示了整個晶片系統的結構以及四種復位等級。

圖3.5.3.1.1 四種復位等級

CPU復位:只復位CPUx核心,這裡的CPUx代表CPU0和CPU1.復位釋放後,程式將從CPUx Reset Vector開始執行。
核心復位:復位除了RTC以外的數字系統,包括CPU0、CPU1、外設、WiFi、Bluetooth® LE及數字GPIO。
系統復位:復位包括RTC在內的整個數字系統。
晶片復位:復位整個晶片。
上述任意復位源產生時,CPU0和CPU1均將立刻復位。復位釋放後,CPU0和CPU1可分別透過讀取暫存器RTC_CNTL_RESET_CAUSE_PROCPU和RTC_CNTL_RESET_CAUSE_APPCPU獲取復位源。這兩個暫存器記錄的復位源除了復位級別為CPU復位的復位源分別對應自身的CPUx以外,其餘的復位源保持一致。下表列出了從上述兩個暫存器中可能讀出的復位源。

表3.5.3.1.1 相關復位的復位源

上表描述了不同的復位對應的復位源,在ESP32-S3上電覆位時,它的復位源為晶片復位,如下資訊所示:
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0xb (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3810,len:0x17c0
load:0x403c9700,len:0xd7c
load:0x403cc700,len:0x300c
entry 0x403c992c
從上述內容可以看到,rst為0x01(復位編碼),根據上表的對應關係,可得晶片上電時的復位源為晶片復位。

3.5.3.2 系統時鐘
ESP32-S3的時鐘主要來源於振盪器(oscillator,OSC)、 RC振盪電路和PLL時鐘生成電路。上述時鐘源產生的時鐘經時鐘分頻器或時鐘選擇器等時鐘模組的處理,使得大部分功能模組可以根據不同功耗和效能需求來獲取及選擇對應頻率的工作時鐘。下圖為ESP32-S3系統時鐘結構。

圖3.5.3.2.1 ESP32-S3時鐘樹
從上圖可知,ESP32-S3時脈頻率,可劃分為:
(1),高效能時鐘,主要為CPU和數字外設提供工作時鐘。
①:PLL_CLK:320MHz或者480MHz內部PLL時鐘
②:XTAL_CLK:40MHz外部晶振時鐘
(2),低功耗時鐘,主要為RTC模組以及部分處於低功耗模式的外設提供工作時鐘。
①:XTAL32K_CLK:32kHz外部晶振時鐘
②:RC_FAST_CLK:內建快速RC振盪器時鐘,頻率可調節(通常為17.5MHz)
③:RC_FAST_DIV_CLK:內建快速RC振盪器分頻時鐘(RC_FAST_CLK/256)
④:RC_SLOW_CLK:內建慢速RC振盪器,頻率可調節(通常為136 kHz)
從上圖紅色線條所示,CPU_CLK代表CPU的主時鐘。在CPU最高效的工作模式下,主頻可以達到240MHz。主頻頻率是由暫存器SYSTEM_SOC_CLK_SEL(SEL_0:選擇SOC時鐘源)、SYSTEM_PLL_FREQ_SEL(SEL_2:選擇 PLL 時脈頻率)和SYSTEM_CPUPERIOD_SEL(SEL_3:選擇 CPU 時脈頻率)共同確定的,具體如下表所示。

表3.5.3.2.1 CPU_CLK時脈頻率配置

從上表可以得知,如果使用者想要將ESP32-S3的主頻設定為240MHz,那麼我們應該選擇PLL_CLK作為輸入源,然後透過二分頻得到240MHz的時脈頻率。
外設、WiFi、BLUE、RTC等時鐘配置及選擇源,請讀者參考《esp32-s3_technical_reference_manual_cn.pdf》技術手冊章節7 復位和時鐘。

3.5.4 晶片Boot控制
在上電覆位、 RTC看門狗復位、欠壓復位、模擬超級看門狗(analog super watchdog)復位、晶振時鐘毛刺檢測復位過程中,硬體將取樣 Strapping 管腳電平儲存到鎖存器中,並一直保持到晶片掉電或關閉。GPIO0、GPIO3、GPIO45和GPIO46鎖存的狀態可以透過軟體從暫存器GPIO_STRAPPING中讀取。GPIO0、GPIO45和GPIO46預設連線內部上拉/下拉。如果這些管腳沒有外部連線或者連線的外部線路處於高阻抗狀態,內部弱上拉/下拉將決定這幾個管腳輸入電平的預設值,如下表所示。

表3.5.4.1 Strapping 管腳預設配置

GPIO0、GPIO45和GPIO46在晶片復位時連線晶片內部的弱上拉/下拉電阻。如果strapping管腳沒有外部連線或者連線的外部線路處於高阻抗狀態,這些電阻將決定strappin管腳的預設值。所有strapping管腳都有鎖存器。系統復位時,鎖存器取樣並儲存相應strapping管腳的值,一直保持到晶片掉電或關閉。鎖存器的狀態無法用其他方式更改。因此,strapping管腳的值在晶片工作時一直可讀取,並可在晶片復位後作為普通IO管腳使用。
① 晶片啟動模式控制
復位釋放後,GPIO0和GPIO46共同決定啟動模式。詳見下表。

表3.5.4.2 晶片啟動模式控制

正常情況下,ESP32啟動模式為“SPI BOOT”,當我們按下開發板的BOOT按鍵時才能進入“Download Boot”模式啟動。
② VDD_SPI 電壓控制
ESP32-S3系列晶片所需的VDD_SPI電壓請參考《esp32-s3_datasheet_cn.pdf》資料手冊的1.2型號對比表格,如下圖所示。

圖3.5.4.1 晶片型號對比

這個表格下定義了每個晶片型號VDD_SPI電壓。由於正點原子ESP32S3開發板的模組選擇的是ESP32-S3-WROOM-1-N16R8,而它的主控晶片為ESP32R8,所以根據上圖的內容,我們會發現ESP32R8晶片的VDD_SPI電壓為3.3V。接著我們來看一下GPIO45號管腳的定義,如下圖所示。

圖3.5.4.2 VDD_SPI電壓控制

從上圖可以看到,電壓有兩種控制方式,具體取決於EFUSE_VDD_SPI_FORCE的值。如果這個值為0,那麼VDD_SPI電壓取決於GPIO45的電平值。如果GPIO45的電平值為0,VDD_SPI電壓為3.3V;否則為1.8V。相反,如果EFUSE_VDD_SPI_FORCE 為 1,VDD_SPI電壓取決於 eFuse(表示 flash 電壓調節器是否短接至VDD_RTC_IO)。如果eFuse為0,VDD_SPI電壓值為1.8V;否則為 3.3V。
③ ROM日記列印控制
系統啟動過程中, ROM程式碼日誌可列印至UART和USB串列埠/JTAG控制器。我們可透過配置暫存器和eFuse可分別關閉UART和USB串列埠/JTAG控制器的ROM程式碼日誌列印功能。詳細資訊請參考《ESP32-S3技術參考手冊》 ->章節晶片Boot控制。
④ JTAG 訊號源控制
在系統啟動早期階段,GPIO3可用於控制JTAG訊號源。該管腳沒有內部上下拉電阻,strapping的值必須由不處於高阻抗狀態的外部電路控制。如圖所示,GPIO3與EFUSE_DIS_PAD_JTAG、EFUSE_DIS_USB_JTAG和EFUSE_STRAP_JTAG_SEL共同控制 JTAG 訊號源。

圖3.5.4.3 JTAG訊號源控制

注意:ESP32-S3系統中有一塊4-Kbit的eFuse,其中儲存著引數內容。相關內容請看《esp32-s3_technical_reference_manual_cn.pdf》技術參考手冊-> 章節 eFuse 控制器。
3.5.5 中斷矩陣
ESP32-S3的中斷矩陣將任意外部中斷源單獨分配到雙核CPU的任意外部中斷上,以便在外部裝置中斷訊號產生後,能夠及時通知CPU0或CPU1進行處理。外部中斷源必須經過中斷矩陣分配至CPU0/CPU1外部中斷,主要是因為ESP32-S3具有99個外部中斷源,但每個CPU只有32箇中斷。透過使用中斷矩陣,可以根據應用需求將一個外部中斷源對映到多個CPU0中斷或CPU1中斷。實際上,CPU0和CPU1的外部中斷只有26個,剩下的6箇中斷均為內部中斷。
下圖是雙核中斷矩陣結構。

圖3.5.5.1 中斷矩陣結構圖

這種設計使得ESP32S3能夠適應不同的應用需求,提供更大的靈活性和控制力。在硬體配置上,使用者需要確保中斷矩陣的正確配置,以便能夠正確地接收和處理外部中斷。同時,使用者也需要透過程式設計方式,根據實際需求對中斷矩陣進行適當的配置和操作。
當某個外部中斷源滿足觸發條件時(例如GPIO引腳訊號狀態發生變化),該中斷訊號將被送入中斷矩陣進行處理。中斷矩陣將根據中斷訊號的特性,將其對映到一個特定的CPU外部中斷上。當CPU接收到這個外部中斷訊號時,會執行與該中斷相關聯的ISR函式。
總的來說,ESP32S3的中斷矩陣是一種高效的中斷處理機制,它能夠將多個外部中斷源對映到兩個CPU的外部中斷上進行處理,並能夠查詢外部中斷源當前的中斷狀態。

3.6 ESP32-S3啟動流程
本文將會介紹ESP32-S3從上電到執行app_main函式中間所經歷的步驟(即啟動流程)。從宏觀上,該啟動流程可分為如下3個步驟。
①:一級載入程式,它被固化在ESP32-S3內部的ROM中,它會從flash的0x00處地址載入二級載入程式至RAM中。
②:二級載入程式從flash中載入分割槽表和主程式映象至記憶體中,主程式中包含了RAM段和透過flash快取記憶體對映的只讀段。
③:應用程式啟動階段執行,這時第二個CPU和freeRTOS的排程器啟動,最後進入app_main函式執行使用者程式碼。
下面作者根據IDF庫相關的程式碼來講解這三個引導流程,如下:
一、一級載入程式
該部分程式是直接儲存在ESP32-S3內部ROM中,所以普通開發者無法直接檢視,它主要是做一些前期的準備工作(復位向量程式碼),然後從flash 0x00偏移地址中讀取二級載入程式檔案頭中的配置資訊,並使用這些資訊來載入剩餘的二級載入程式。
二、二級載入程式
該程式是可以檢視且可被修改,在搭建ESP-IDF環境完成後,可在esp-idf\components\bootloader/subproject/main/路徑下找到bootloader_start.c檔案,此檔案就是二級載入程式啟動處。首先我們克隆ESP-IDF庫,克隆過程如下所示。

圖3.6.1 克隆ESP-IDF庫

克隆完成後,使用VSCode開啟ESP-IDF庫,接著找到bootloader_start.c,如下圖所示。

圖3.6.2 bootloader_start.c檔案路徑

在這個檔案下,找到call_start_cpu0函式,此函式是bootloader程式,如下是bootloader程式的部分程式碼。
/*
ROM引導載入程式完成從快閃記憶體載入第二階段引導載入程式之後到達這裡

 */
void __attribute__((noreturn)) call_start_cpu0(void)
{
    if (bootloader_before_init) {
        bootloader_before_init();
    }

/* 1. 硬體初始化:清楚bss段、開啟cache、復位mmc等操作
bootloader_support/src/esp32s3/bootloader_esp32s3.c */
    if (bootloader_init() != ESP_OK) {
        bootloader_reset();
    }

    if (bootloader_after_init) {
        bootloader_after_init();
    }

    /* 2. 選擇啟動分割槽的數量:載入分割槽表,選擇boot分割槽 */
    bootloader_state_t bs = {0};
    int boot_index = select_partition_number(&bs);
    
    if (boot_index == INVALID_INDEX){
        bootloader_reset();
    }

/* 3. 載入應用程式映像並啟動
bootloader_support/src/esp32s3/bootloader_utility.c */
    bootloader_utility_load_boot_image(&bs, boot_index);
}

ESP-IDF使用二級載入程式可以增加FLASH分割槽的靈活性(使用分割槽表),並且方便實現FLASH加密,安全引導和空中升級(OTA)等功能。主要的作用是從flash的0x8000處載入分割槽表(請看線上ESP32-IDF程式設計指南分割槽表章節)。根據分割槽表執行應用程式。

三、三級載入程式
應用程式的入口是在esp-idf/components/esp_system/port/路徑下的cpu_star.c檔案,在此檔案下找到call_start_cpu0函式(埠層初始化函式)。這個函式由二級引導載入程式執行,並且從不返回。因此你看不到是哪個函式呼叫了它,它是從彙編的最底層直接呼叫的。
這個函式會初始化基本的C執行環境(“CRT”),並對SOC的內部硬體進行了初始配置。執行call_start_cpu0函式完成之後,在components\esp_system\startup.c檔案下呼叫start_cpu0(在110行中,弱關聯start_cpu0_default函式)系統層初始化函式,如下start_cpu0_default函式的部分程式碼。

static void start_cpu0_default(void)
{
    ESP_EARLY_LOGI(TAG, "Pro cpu start user code");
    /* 獲取CPU時鐘 */
    int cpu_freq = esp_clk_cpu_freq();
    ESP_EARLY_LOGI(TAG, "cpu freq: %d Hz", cpu_freq);

    /* 初始化核心元件和服務 */
    do_core_init();

    /* 執行建構函式 */
    do_global_ctors();

    /* 執行其他元件的init函式 */
    do_secondary_init();
    /* 開啟APP程式 */
    esp_startup_start_app();
    while (1);
}

到了這裡,就完成了二級程式引導,並呼叫esp_startup_start_app函式進入三級載入程式,該函式的原始碼如下:

/* components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c */
/* 開啟APP程式 */
void esp_startup_start_app(void)
{   /* 省略部分程式碼 */
    /* 新建main任務函式 */
    esp_startup_start_app_common();

    /* 開啟FreeRTOS任務排程 */
    vTaskStartScheduler();
}

/* components/freertos/FreeRTOS-Kernel/portable/port_common.c */
/* 新建main任務函式 */
void esp_startup_start_app_common(void)
{
    /* 省略部分程式碼 */
    /* 建立main任務 */
    portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
                                                ESP_TASK_MAIN_STACK, NULL,
                                                ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE);
    assert(res == pdTRUE);
    (void)res;
}

/* main任務函式 */
static void main_task(void* args)
{   /* 省略部分程式碼 */
    /* 執行app_main函式 */
    app_main();
    vTaskDelete(NULL);
}

從上述原始碼可知,首先在esp_startup_start_app_common函式呼叫FreeRTOS API建立main任務,然後開啟freeRTOS任務排程器,最後在main任務下呼叫app_main函式(此函式在建立工程時,在main.c下定義的)。