当前位置: 首页 > ds >正文

ESP32-S3学习笔记

第一章 ESP32-S3 基础知识

        前段时间买了一块正点原子 DNESP32S3 开发板,为什么选择他的呢?主要因为DNESP32S3 开发板资源比较多,正点原子提供的资料多,又全面,如下图所示:

        又为什么选择ESP32-S3这款芯片呢?主要是这款芯片资源丰富,内存也大,同时支出WIFI和蓝牙,还有支持神经网络加速功能,如果想做AI、图像识别方面,也款芯片也能满足,下面就用一张图来简单介绍一下ESP32-S3

         下面就让我们一起了解认识这款芯片吧。

1. ESP32系列对比

        在上述表格中,我们可以看到乐鑫推出的各系列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 系列可能更合适。

2. ESP32-S3 介绍

        ESP32-S3 是一款低功耗的 MCU 系统级芯片(SoC),支持 2.4 GHz Wi-Fi 和低功耗蓝牙(Bluetooth® LE)无线通 信。芯片集成了高性能的 Xtensa® 32 位 LX7 双核处理器、超低功耗协处理器、W-Fi基带、蓝牙基带、RF 模块 以及外设。 可以说是专为物联网而生的一款Soc,应用领域贯穿移动设备、可穿戴电子设备、智能家居等;下图为芯片的功能框图。官方网站提供了最详细的参考:芯片概览 | 乐鑫科技

        2.1 特性

        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方面的计算速度和效率。

        2.2 资源介绍 

内核Xtensa® LX7 CPU系统定时器1UART3
主频240MHz定时器组2RNG1
ROM384KBLEDC1I2C2
SRAM512KBRMT1I2S2
编程 IO45GPIOPCNT1SPI4(0、 1 禁用)
工作电压3.3TWAI1RGB1
Wi-Fi/BLE1/1USB OTG1SD/MMC1

        2.3 S3 系列型号命名规则

        乐鑫S3系列型号包括ESP32-S3、ESP32-S3R2、ESP32-S3R8和ESP32-S3FN8等。这些型号在硬件配置、功能和应用场景方面略有不同。不同型号的MCU都有不同的应用场景,下面我们来看一下这些型号的命名规则,如下图所示。

        从上图可以看到,F表示内置FLASH;H/N表示FLASH温度(H:高温,N:常温);x表示内置FLASH大小(MB);R表示内置PSRAM;x表示内置PSRAM大小(MB);V表示仅支持外部1.8v spi flash。为了让读者更清晰了解ESP32-S3命名规则,这里作者以ESP32-S3FH4R2这一款芯片为例,绘画一副清晰的命名示意图,如下图所示。

         根据上述两张图的分析,我们可以了解到乐鑫S3系列的命名规则和特点。除了S3系列的芯片之外,乐鑫还推出了S3系列的模组,它是S3系列芯片的简易系统。

2.4 模组型号 

模组型号内置芯片外置 FLASH内置 PSRAM
ESP32-S3-WROOM-1-N4ESP32-S340
ESP32-S3-WROOM-1-N8ESP32-S380
ESP32-S3-WROOM-1-N16ESP32-S3160
ESP32-S3-WROOM-1-H4ESP32-S340
ESP32-S3-WROOM-1-N4R2ESP32-S3R242(Quad SPI)
ESP32-S3-WROOM-1-N8R2ESP32-S3R282(Quad SPI)
ESP32-S3-WROOM-1-N16R2ESP32-S3R2162(Quad SPI)
ESP32-S3-WROOM-1-N4R8ESP32-S3R848(Octal SPI)
ESP32-S3-WROOM-1-N8R8ESP32-S3R888(Octal SPI)
ESP32-S3-WROOM-1-N16R8ESP32-S3R8168(Octal SPI)
ESP32-S3-WROOM-1U-N4ESP32-S340
ESP32-S3-WROOM-1U -N8ESP32-S380
ESP32-S3-WROOM-1U -N16ESP32-S3160
ESP32-S3-WROOM-1U -H4ESP32-S340
ESP32-S3-WROOM-1U -N4R2ESP32-S3R242(Quad SPI)
ESP32-S3-WROOM-1U -N8R2ESP32-S3R282(Quad SPI)
ESP32-S3-WROOM-1U -N16R2ESP32-S3R2162(Quad SPI)
ESP32-S3-WROOM-1U -N4R8ESP32-S3R848(Octal SPI)
ESP32-S3-WROOM-1U -N8R8ESP32-S3R888(Octal SPI)
ESP32-S3-WROOM-1U -N16R8ESP32-S3R8168(Octal SPI)

        根据上表,可以看出这两款模组的主控芯片是 ESP32-S3 和 ESP32-S3Rx,它们都属于乐鑫的 ESP32-S3 系列芯片。之前作者已经详细讲解了 ESP32-S3 系列芯片的命令规则,可以得出这两款通用模组都是外接 Flash 存储器,并且内置有 PSRAM(主控芯片 ESP32-S3 没有内置PSRAM)。正点原子ESP32-S3开发板是以ESP32-S3-WROOM-1-N16R8模组作为主控,下面我们以此模组为例,来讲解模组的命名规则,如下图所示。

3. ESP32-S3功能概述 

3.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与各部分的联系示意图。

        上图中,灰色背景的地址空间不可用,红色五角星表示对应存储器和外设可以被协调器访问。由于 ESP32-S3 系统是由两个哈佛结构 Xtensa® LX7 CPU 构成,这两个 CPU 能够访问的地址空间范围是完全一致的。上图中,地址 0x40000000 以下部分属于数据总线的地址范围;地址0x40000000~4FFFFFFF 部分位指令总线的地址范围,其他是数据总线与指令总线的地址范围,即内部存储器、外部存储器和外设等映射的内存地址。
        CPU 的数据总线与指令总线都为小端序(将多字节数据的低位放在较小的地址处,高位放在较大的地址处)。 CPU 可以通过数据总线进行单字节、双字节、 4 字节、 16 字节的数据访问。
        CPU 也可以通过指令总线进行数据访问,但必须是 4 字节对齐方式;非对齐数据访问会导致CPU 工作异常。 CPU 的工作如下:
        ① 通过数据总线与指令总线直接访问内部存储器。
        ② 通过 Cache 直接访问映射到地址空间的外部存储器。
        ③ 通过数据总线直接访问模块/外设。
        系统中部分内部存储器与部分外部存储器既可以被数据总线访问也可以被指令总线访问,这种情况下, CPU 可以通过多个地址访问到同一目标。

3.2 内部存储器 

        上图 中的①、②、④和⑥部分组成 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.3 外部存储器 

        上图中的⑦、⑧和⑨可见。 CPU 借助高速缓存(Cache)来访问外部存储器。 Cache 将根据内存管理单元(MMU)中的信息把 CPU 指令总线或数据总线的地址变换为访问片外 flash与片外 RAM 的实地址。经过变换的实地址所组成的实地址空间最大支持 1 GB 的片外 flash 与 1GB 的片外 RAM。前面我们讨论知道, ESP32-S3 采用双核共享 ICache 和 DCache 结构,以便当CPU 的指令总线和数据总线同时发起请求时,也可以迅速响应。当双核同时访问 ICache 时,系统会做以下判断,如下图所示。

        当 两 个 核 的 指 令 总 线 同 时 访 问 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 块大小模式。
        外部存储器通过高速缓存(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 的对应关系。

        同样,想要操作外部存储器的读写,需获取访问权限,CPU访问外部存储器时才能被响应。关于权限管理的更多信息,请参考《esp32-s3_technical_reference_manual_cn.pdf》15权限控制(PMS)。

3.4 模块/外设 

        上图中的⑤就是模块/外设地址空间地址,CPU就是通过该空间地址来访问模块/外设的。下表是模块/外设地址空间的各段地址与其能访问到的模块/外设映射关系。 

        从上表可以得知,要操作外设的寄存器,首先需要知道该外设的首地址。然后,我们可以使用一些底层的编程语言,如C语言或汇编语言,来编写程序以设置外设寄存器的值,从而控制外设的行为。例如,通过设置GPIO寄存器的值,我们可以控制某个LED灯的亮灭;同样地,设置UART寄存器的值可以用来发送和接收数据。

        与内部存储器和外部存储器访问类似,CPU要想访问某一个模块/外设,需要先获取该模块/外设的访问权限,否则访问将不会被响应。关于权限管理的更多信息,请参考《esp32-s3_technical_reference_manual_cn.pdf》章节15权限控制(PMS)。

3.5 通用GDMA控制器 

        通用直接存储访问(GeneralDirect 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通道示意图。

        从上图可知,每一个外设都可以使用任意一条通道进行数据传输。然而,这些通道分为不同的类型。当使用GDMA接收数据时,可以选择任意的RXn通道(n:0~4);相反,当使用GDMA发送数据时,则需要选择任务的TXn通道(n:0~4)。这种通道的分类和选择方式使得数据传输更加高效和灵活。

        ESP32-S3中有11个外设/模块可以和GDMA联合工作,如下图所示。其中的 11 根竖线依次对应这11个具有GDMA功能的外设/模块,横线表示GDMA的某一个通道(可以是任意一个通道),竖线与横线的交点表示对应外设/模块可以访问GDMA的某一个通道。同一行上有多个交点则表示这几个外设/模块不可以同时开启GDMA功能。

        具有GDMA功能的模块/外设通过GDMA可以访问任何GDMA可以访问到的存储器。更多关于GDMA的信息,请参考《esp32-s3_technical_reference_manual_cn.pdf》章节 3 通用 DMA 控制器(GDMA)。

        与前面小节一样,当使用GDMA访问任何存储器时,都需要获取对应的访问权限,否则访问将会失败。

4. IO MUX和GPIO交换矩阵 

        ESP32-S3 芯片有45个物理通用输入输出管脚(GPIOPin)。每个管脚都可用作一个通用输入输出,或连接一个内部外设信号。利用GPIO交换矩阵、IO MUX(IO复用选择器)和RTC IO MUX(RTC复用选择器),可配置外设模块的输入信号来源于任何的GPIO管脚,并且外设模块的输出信号也可连接到任意GPIO管脚。这些模块共同组成了芯片的输入输出控制。值得注意的是,这45个物理GPIO管脚的编号为0~21、26~48。这些管脚即可作为输入有可作为输出管脚。正如前文所述,正点原子选择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模式下的管脚。

        下面我们来看一下这个模组的实物图和引脚分布图,如下图所示。 

        从上图可以得知,该图片是该模组的管脚分布图。虽然这些管脚是无序的,但它们都可以被复用为其他功能(除个别功能外),例如SPI、串口、IIC等协议。这是ESP32相比其他MCU的优势之一,它具有更多的可复用管脚,可以支持更多的外设和协议。

        接下来,我们来看一下模组管脚默认复用管脚和管脚功能释义,如下表所示。

管脚
名称
序号类型描述
GND1P接地
3V32P供电
EN3I高电平:使能芯片
低电平:关闭芯片
注:不能悬空
IO44I/O/TRTC_GPIO4\GPIO4\TOUCH4\ADC1_CH3
IO55I/O/TRTC_GPIO5\GPIO5\TOUCH5\ADC1_CH4
IO66I/O/TRTC_GPIO6\GPIO6\TOUCH6\ADC1_CH5
IO77I/O/TRTC_GPIO7\GPIO7\TOUCH7\ADC1_CH6
IO158I/O/TRTC_GPIO15\GPIO15\U0RTS\ADC2_CH4\XTAL_32K_P
IO169I/O/TRTC_GPIO16\GPIO16\U0CTS\ADC2_CH5\XTAL_32K_N
IO1710I/O/TRTC_GPIO17\GPIO17\U1TXD\ADC2_CH6
IO1811I/O/TRTC_GPIO18\GPIO18\U1RXD\ADC2_CH7\CLK_OUT3
IO812I/O/TRTC_GPIO8\GPIO8\TOUCH8\ADC1_CH7\SUBSPICS1
IO1913I/O/TRTC_GPIO19\GPIO19\U1RTS\ADC2_CH8\CLK_OUT2\USB_D
IO2014I/O/TRTC_GPIO20\GPIO20\U1CTS\ADC2_CH9\CLK_OUT1\USB_D+
IO315I/O/TRTC_GPIO3\GPIO3\TOUCH3\ADC1_CH2
IO4616I/O/TGPIO46
IO917I/O/TRTC_GPIO9,GPIO9,TOUCH9,ADC1_CH8,FSPIHD,SUBSPIHD
IO1018I/O/TRTC_GPIO10,GPIO10,TOUCH10,ADC1_CH9,FSPICS0,FSPIIO4
IO1119I/O/TRTC_GPIO11,GPIO11,TOUCH11,ADC2_CH0,FSPID,FSPIIO5
IO1220I/O/TRTC_GPIO12,GPIO12,TOUCH12,ADC2_CH1,FSPICLK,FSPIIO6
IO1321I/O/TRTC_GPIO13,GPIO13,TOUCH13,ADC2_CH2,FSPIQ,FSPIIO7
IO1422I/O/TRTC_GPIO14,GPIO14,TOUCH14,ADC2_CH3,FSPIWP,FSPIDQS
IO2123I/O/TRTC_GPIO21,GPIO21
IO4724I/O/TSPICLK_P_DIFF,GPIO47,SUBSPICLK_P_DIFF
IO4825I/O/TSPICLK_N_DIFF\GPIO48\SUBSPICLK_N_DIFF
IO4526I/O/TGPIO45
IO027I/O/TRTC_GPIO0\GPIO0
IO3528I/O/TSPIIO6\GPIO35\FSPID\SUBSPID
IO3629I/O/TSPIIO7\GPIO36\FSPICLK\SUBSPICLK
IO3730I/O/TSPIDQS\GPIO37\FSPIQ\SUBSPIQ
IO3831I/O/TGPIO38\FSPIWP\SUBSPIWP
IO3932I/O/TMTCK\GPIO39\CLK_OUT3\SUBSPICS1
IO4033I/O/TMTDO\GPIO40\CLK_OUT2
IO4134I/O/TMTDI\GPIO41\CLK_OUT1
IO4235I/O/TMTMS\GPIO42
RXD036I/O/TU0RXD\GPIO44\CLK_OUT2
TXD037I/O/TU0TXD\GPIO43\CLK_OUT1
IO238I/O/TRTC_GPIO2\GPIO2\TOUCH2\ADC1_CH1
IO139I/O/TRTC_GPIO1\GPIO1\TOUCH1\ADC1_CH0
GND40P接地
EPAD41P接地

        上表是ESP32-S3-WROOM-1-N16R8模组的管脚定义,下面作者根据这个表格来讲解GPIO交互矩阵及IO MUX复用的知识。

        下图为GPIO交换矩阵、IO MUX和RTC IO MUX将信号引入外设和引出至管脚的具体过程。

        首先,作者说明一下上图带有颜色线条和标签(Ⅰ、Ⅱ、Ⅲ、Ⅳ)的作用,红色线条表示输出方向;紫色线条代表RTC IO管脚的输出方向;黄色线条代表RTCIO管脚输入方向;标签代表输入/输出分支的节点。

        从上图可知,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管脚均采用此结构,如下图所示。

        上图中的IE表示输入使能;OE表示输出使能;WPU表示内部弱上拉;WPD表示内部弱下拉,它们实现了芯片封装内晶片与GPIO管脚之间的物理连接。 

一、“Pin X supplied by VDD3P3_CPU”芯片焊盘输入流程(图4.5.1.5.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进行配置的。这个寄存器的描述如下。

        从上图可知,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交换矩阵作为输入;否则,选择IOMUX作为输入,最终信号到达输入信号终端。

二、“Pin X supplied by VDD3P3_CPU”芯片焊盘输出流程(图4.5.1.5.3中的红色线条)

        从上图可知,输出信号也是分为两个通道传输(Ⅰ处),如果输出信号是普通的GPIO输出,则该信号经过GPIO矩阵,再由该矩阵输出到IO MUX,再到输出管脚,这个流程由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复用功能,则输入信号会进入RTCIO MUX复用电路,并最终到达RTCGPIO矩阵。

5.  复位与时钟 

5.1 ESP32-S3复位等级 

        ESP32-S3提供四种级别的复位方式,分别是CPU复位、内核复位、系统复位和芯片复位。除芯片复位外其它复位方式不影响片上内存存储的数据。下图展示了整个芯片系统的结构以及四种复位等级。 

        CPU复位:只复位CPUx内核,这里的CPUx代表CPU0和CPU1.复位释放后,程序将从CPUxReset 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以外,其余的复位源保持一致。下表列出了从上述两个寄存器中可能读出的复位源。

        上表描述了不同的复位对应的复位源,在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(复位编码),根据上表的对应关系,可得芯片上电时的
复位源为芯片复位。

5.2 系统时钟

        ESP32-S3的时钟主要来源于振荡器(oscillator,OSC)、 RC振荡电路和PLL时钟生成电路。上述时钟源产生的时钟经时钟分频器或时钟选择器等时钟模块的处理,使得大部分功能模块可以根据不同功耗和性能需求来获取及选择对应频率的工作时钟。下图为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 时钟频率) 共同确定的,具体如下表所示。

        从上表可以得知,如果用户想要将 ESP32-S3 的主频设置为 240MHz,那么我们应该选择PLL_CLK 作为输入源,然后通过二分频得到 240MHz 的时钟频率。
        外设、 WiFi、 BLUE、 RTC 等时钟配置及选择源,请读者参考《esp32s3_technical_reference_manual_cn.pdf》技术手册章节 7 复位和时钟。

5.3 芯片Boot控制 

        在上电复位、 RTC 看门狗复位、欠压复位、模拟超级看门狗(analog super watchdog) 复位、晶振时钟毛刺检测复位过程中,硬件将采样 Strapping 管脚电平存储到锁存器中,并一直保持到芯片掉电或关闭。 GPIO0、 GPIO3、 GPIO45 和 GPIO46 锁存的状态可以通过软件从寄存器GPIO_STRAPPING 中读取。 GPIO0、 GPIO45 和 GPIO46 默认连接内部上拉/下拉。如果这些管脚没有外部连接或者连接的外部线路处于高阻抗状态,内部弱上拉/下拉将决定这几个管脚输入电平的默认值,如下表所示。

        GPIO0、 GPIO45 和 GPIO46 在芯片复位时连接芯片内部的弱上拉/下拉电阻。如果 strapping管脚没有外部连接或者连接的外部线路处于高阻抗状态,这些电阻将决定 strappin管脚的默认值。所有 strapping 管脚都有锁存器。系统复位时,锁存器采样并存储相应 strapping 管脚的值,一直保持到芯片掉电或关闭。锁存器的状态无法用其他方式更改。因此, strapping 管脚的值在芯片工作时一直可读取,并可在芯片复位后作为普通 IO 管脚使用。
        ① 芯片启动模式控制
        复位释放后, GPIO0 和 GPIO46 共同决定启动模式。详见下表。

        正常情况下, ESP32 启动模式为“SPI BOOT”,当我们按下开发板的 BOOT 按键时才能进入“Download Boot”模式启动。

        ② VDD_SPI 电压控制
        ESP32-S3 系列芯片所需的 VDD_SPI 电压请参考《esp32-s3_datasheet_cn.pdf》数据手册的1.2 型号对比表格,如下图所示。

        这个表格下定义了每个芯片型号 VDD_SPI电压。由于正点原子 ESP32S3开发板的模组选择的是 ESP32-S3-WROOM-1-N16R8,而它的主控芯片为 ESP32R8,所以根据上图的内容,我们会发现 ESP32R8 芯片的 VDD_SPI 电压为 3.3V。接着我们来看一下 GPIO45 号管脚的定义,如下图所示。

        从上图可以看到,电压有两种控制方式,具体取决于 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 信号源。

        注意: ESP32-S3 系统中有一块 4-Kbit 的 eFuse,其中存储着参数内容。相关内容请看《esp32-s3_technical_reference_manual_cn.pdf》 技术参考手册-> 章节 eFuse 控制器。

5.4 中断矩阵 

        SP32-S3的中断矩阵将任意外部中断源单独分配到双核CPU的任意外部中断上,以便在外部设备中断信号产生后,能够及时通知CPU0或CPU1进行处理。外部中断源必须经过中断矩阵分配至CPU0/CPU1外部中断,主要是因为ESP32-S3具有99个外部中断源,但每个CPU只有32个中断。通过使用中断矩阵,可以根据应用需求将一个外部中断源映射到多个CPU0中断或CPU1中断。实际上,CPU0和CPU1的外部中断只有26个,剩下的6个中断均为内部中断。

        下图是双核中断矩阵结构。

         这种设计使得ESP32S3能够适应不同的应用需求,提供更大的灵活性和控制力。在硬件配置上,用户需要确保中断矩阵的正确配置,以便能够正确地接收和处理外部中断。同时,用户也需要通过编程方式,根据实际需求对中断矩阵进行适当的配置和操作。

        当某个外部中断源满足触发条件时(例如GPIO引脚信号状态发生变化),该中断信号将被送入中断矩阵进行处理。中断矩阵将根据中断信号的特性,将其映射到一个特定的CPU外部中断上。当CPU接收到这个外部中断信号时,会执行与该中断相关联的ISR函数。

        总的来说,ESP32S3的中断矩阵是一种高效的中断处理机制,它能够将多个外部中断源映射到两个CPU的外部中断上进行处理,并能够查询外部中断源当前的中断状态。

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 库,克隆过程如下所示。

        克隆完成后,使用 VSCode 打开 ESP-IDF 库,接着找到 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 下定义的)。

本文参考文章,书籍

参考文章

《ESP32-S3使用指南—IDF版 V1.6》第三章 ESP32-S3基础知识 - 简书

注:如发现内容存在侵权问题,欢迎随时告知,我会立即删除相关内容并妥善处理。

http://www.xdnf.cn/news/6739.html

相关文章:

  • el-table表格列宽度自适应
  • 微服务中服务降级和异常的区别
  • 课设:基于swin_transformer的植物中草药分类识别系统(包含数据集+UI界面+系统代码)
  • 基于支持向量机(SVM)的P300检测分类
  • Android SwitchButton 使用详解:一个实际项目的完美实践
  • redis数据结构-12(配置 RDB 快照:保存间隔和压缩)
  • okcc呼叫中心系统搭建的方案方式
  • 反向传播算法:神经网络的核心优化方法,一文打通任督二脉
  • [逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五)
  • 基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
  • 内容中台重构企业知识管理路径
  • 英飞凌tle9954 GPIO
  • FPGA:Lattice的FPGA产品线以及器件选型建议
  • SQL里where条件的顺序影响索引使用吗?
  • 电子界桩在古建筑文物保护应用解决方案
  • 综合项目:博客
  • 保安员考试报名时,体检项目包含哪些?
  • Java回溯算法解决非递减子序列问题(LeetCode 491)的深度解析
  • 安全版4.5.8开启审计后,hac+读写分离主备切换异常
  • 算法刷题(Java与Python)1.二分查找
  • Linux补充之vscode连接远端主机
  • 2025 Adobe Acrobat DC安装教程
  • Vue3中实现轮播图
  • 敏捷-第二章 敏捷宣言与原则
  • Reactive与Ref的故事
  • linux用户切换
  • 单序列双指针---初阶篇
  • NHANES指标推荐:MDS
  • 【常见的面试题总结】
  • Spring Cloud:Gateway(统一服务入口)