【ESP 乐鑫相关】ESP32-S3启动流程

news/2025/1/18 9:37:06/文章来源:https://www.cnblogs.com/FBsharl/p/18678053

转载自:https://blog.itpub.net/70040860/viewspace-3053923/

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

 

图4.6.1 克隆ESP-IDF库

 

       克隆完成后,使用VSCode打开ESP-IDF库,接着找到bootloader_start.c,如下图所示。

 

图4.6.2 bootloader_start.c文件路径

 

       在这个文件下,找到call_start_cpu0函数,此函数是bootloader程序,如下是bootloader程序的部分代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 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函数的部分代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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函数进入三级引导程序,该函数的源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* 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下定义的)。

       同理,ESP32S3的MicroPython固件也是以这种方式启动的。此外,MicroPython的app_main函数是在ports/esp32/main.c文件中定义的。在该文件中,会进行UART、USB和特定库的初始化操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/871144.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

80端口对外网访问受限,如何解除限制?

您好!当您发现配置了80端口的Nginx服务虽然可以在本地正常访问,但从外部网络却无法访问时,这通常是由于防火墙规则、安全组策略或其他网络配置不当所造成的。以下是详细的排查步骤和解决方案,帮助您解除80端口的访问限制:检查服务器防火墙设置: 首先,确认服务器上的防火…

服务器升级后,CPU性能下降,网站响应缓慢,如何优化?

在服务器硬件升级后,如果出现CPU性能下降、网站响应速度变慢的情况,这可能是由多种因素共同作用的结果。以下是一些详细的排查步骤和优化建议,帮助您提升服务器的整体性能:确认硬件配置变更: 首先,确保服务器硬件确实按照预期进行了升级。有时候,尽管表面上看起来硬件规…

网站域名解析异常导致跳转到其他页面怎么办?

问题描述: 网站域名解析后出现异常,访问时跳转到其他无关页面。这是什么原因造成的?如何解决? 解决方案: 当您发现网站域名解析后出现异常,访问时跳转到其他无关页面时,这可能是由多种原因引起的。以下是详细的排查步骤和解决方案:检查程序挂马:首先,需要确认网站是否…

SSL证书配置导致二级域名覆盖主域名访问问题

问题描述: 在为二级域名申请SSL证书后,发现二级域名的访问覆盖了主域名,导致主域名无法正常访问。如何解决这个问题? 解决方案: 当您为二级域名申请SSL证书后,发现二级域名的访问覆盖了主域名,导致主域名无法正常访问时,这通常是因为Web服务器配置不当所致。以下是详细…

threejs 实现镜面反射,只反射指定物体,背景透明

一、背景 最近在做数字孪生项目,使用threejs渲染模型,UI要求地面反射建筑物,也就是模型要有倒影。 二、调研 在官网找到一个镜面反射的例子(https://threejs.org/examples/?q=refle#webgl_mirror) 如图:和UI要的功能类似,但有缺陷 1、反射出了地面上所有的元素,连天空…

3D-NAND 计算(下)

过去几年, 具有存算一体特性的 AI 芯片不断 涌现, 工艺节点涵盖了 14—180 nm, 计算架构包括 了近存计算、存内计算和神经形态计算, 应用场景 覆盖了边缘端到云端设备. 在各种硬件方案中, 基 于 3D-NAND 的神经形态芯片在芯片容量, CMOS 工艺兼容性和成本方面极具优势. 本文首先…

海康工业相机的应用部署不是简简单单!?

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 笔者使用的设备及环境:WSL2-Ubuntu22.04+MV-CS016-10UC 不会吧?不会吧?不会还有人拿到海康工业相机还是一脸懵叭?不会还有人觉得海康相机的API使用很难叭?不用慌!这篇文章从官方文档涵盖了海康相机官方…

3D-NAND 计算(上)

3D-NAND 闪存工艺成熟并且存储密度极高, 基于 3D-NAND 的神经形态芯片受到许多研究者的关注. 然而由于该技术的专利性质, 少有基 于 3D-NAND 神经形态计算的硬件实现. 本文综述了用 3D-NAND 实现神经形态计算的工作, 介绍了其中前 向传播和反向传播的机制, 并提出了目前 3D NAN…

blender4.3.2-修改器

关于修改器的其他问题 1.在修改器执行应用前,无法与其他物体进行合并 阵列修改器 生成->阵列指定数量和间隔,生成克隆体,所有克隆体同步发生选中和修改 倒角修改器 生成->倒角使用倒角修改器而不直接使用编辑模式中的倒角,好处在于像立方体这种使用了倒角修改器而未应…

推荐书籍《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》4本,谢谢

4本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该…

2025 最佳免费商用文本转语音模型: Kokoro TTS

在文本转语音(TTS)技术领域,一项突破性的进展引起了广泛关注——Kokoro TTS 模型凭借其卓越性能和完全免费的商用许可,成为目前最出色的 TTS 解决方案之一。基于广受欢迎的开源框架 StyleTTS,Kokoro TTS 在灵活性和功能性上都表现出色,可广泛应用于多种场景。接下来,我们…

2025春秋杯部分wpDAY1

2025春秋杯 DAY1 WEB easy_flask 直接fenjing一把梭file_copy 下载github上的脚本MISC 简单算术 题目提示了异或简单镜像提取formost提取到镜像文件然后用autopsy打开flag{E7A10C15E26AA5750070EF756AAA1F7C} CRYPTO 通往哈希的旅程 import hashlib# 目标哈希值 target_hash = …