持续创作,加快生长!这是我参加「日新方案 10 月更文应战」的第29天,点击检查活动详情

网上阐明一大堆,根本是官网文档仿制没有额定解说!
关于ESP32-C3的 risc-v 内核,是我选择他的原因之一,
了解芯片上电后的发动流程,有利于咱们愈加深化了解芯片。

前言

关于ARM内核的STM32的发动流程,我曾经的博文详细剖析过,搞懂了STM32的发动流程关于芯片的运用和了解来说就会更上一个等级。现在咱们新接触的 risc-v 内核的ESP32-C3,假如可以搞明白他的发动流程,就能更深的了解 ESP32-C3。

在写文章之前也看了许多网上的文章,然后官方的阐明也看过了,网上绝大多数都是官网文档仿制一遍,这倒没什么,究竟官网权威,问题是,仿制一遍过来没有做过多的解说,没有额定的剖析,还写个原创,我真是服了。当然不扫除我没看到的好的文章,也正是由于根本没有看到愈加详细的剖析,我决定要自己写一篇记载,一来作为自己记载,二来底层有些当地目前来说我的确不是了解透彻,必定有不到位的当地,期望咱们多提意见,能让文章愈加完善。

依照惯例,我把能找到的文章和官方的材料都看了好多遍,官方说到的3大过程:

一步步带你分析 ESP32-C3 应用程序的启动流程

关于上述说到的3大过程,最简略的明晰的是第三步,第二步也有源码,却是可以检查试着剖析一下,可是第一步的确,仅仅知道这么回事,详细的完成方法由于程序是在ESP32-C3 的内部 ROM 中,的确找不到可以剖析的源码和材料。

芯片的发动流程,大多离不开发动文件和链接文件。ESP32-C3应该也是这样,原本依照了解,应该找到底层的发动文件和衔接文件开端依照过程剖析,可是检查了一会底层代码,由于对底层架构深化了解得还不行,没有找到= =! 所以想着怎么办?

不能依照从最开端到完毕的次序来,那么就依照从完毕到开端的次序来!咱们从app_main 函数反过来一层一层网前看,看看经过了一些什么处理,程序才执行到app_main 函数的!

留意,文章以倒叙的方法阐明~ ~

本文是根据 VScode 插件的工程结构来阐明(Ubuntu环境)。

一、应用程序发动阶段

1.1 app_main.c

咱们从app_main.c的主函数app_main中,咱们直接通过转到界说看看上一层:

一步步带你分析 ESP32-C3 应用程序的启动流程

1.2 port_common.c

app_main 往上找的文件是 port_common.c,途径如下:

一步步带你分析 ESP32-C3 应用程序的启动流程

是哪一个使命调用了app_main 呢,咱们直接往上就能看到, main_task调用了app_main , 而main_task这个使命就在esp_startup_start_app_common函数中创立:

一步步带你分析 ESP32-C3 应用程序的启动流程

知道了esp_startup_start_app_common 函数创立了main_task这个使命, 那么这个函数在哪边有调用呢?咱们持续往上看, 找到esp_startup_start_app函数中调用了esp_startup_start_app_common, 调用完成今后就开启了 FreeRTOS 使命调度。

一步步带你分析 ESP32-C3 应用程序的启动流程

对应的,咱们看一下发动LOG:

一步步带你分析 ESP32-C3 应用程序的启动流程

1.3 port.c

咱们又进入了一个新的文件 port.c,途径如下:

一步步带你分析 ESP32-C3 应用程序的启动流程

接着上面的,从esp_startup_start_app函数往上找, 又找到一个start_cpu0_default函数,如图:

一步步带你分析 ESP32-C3 应用程序的启动流程

1.4 startup.c

又找到一个新文件startup.c,途径如下:

一步步带你分析 ESP32-C3 应用程序的启动流程

start_cpu0_default

startup.c 文件的 start_cpu0_default函数,其间进行了许多关键过程,详细可以自行检查代码:

一步步带你分析 ESP32-C3 应用程序的启动流程

对应的,咱们看一下发动LOG:

一步步带你分析 ESP32-C3 应用程序的启动流程

咱们还想看 start_cpu0_default函数从哪里调用,可是这时候现已无法跳转了,这时候咱们依然在startup.c文件中查找,可以找到下面一句话:

一步步带你分析 ESP32-C3 应用程序的启动流程

这句话的意思便是使得 start_cpu0_default函数弱衔接到start_cpu0函数,假如没有额定的声明,start_cpu0_default函数等价于start_cpu0函数。(有过错请指出)

持续看看与 start_cpu0函数 有关的程序,g_startup_fn好像是一个数组?如图:

一步步带你分析 ESP32-C3 应用程序的启动流程

尝试着对 g_startup_fn 运用转到界说,咱们进入了别的一个新的文件,可以找到一个宏界说SYS_STARTUP_FN()

一步步带你分析 ESP32-C3 应用程序的启动流程

1.5 startup_internal.h

老姿态先看文件途径如下:

一步步带你分析 ESP32-C3 应用程序的启动流程

这是一个头文件,所以这儿边必定都是函数的声明和宏界说,咱们在这个文件中需要重视的当地便是一个宏界说#define SYS_STARTUP_FN() ((*g_startup_fn[(cpu_hal_get_core_id())])())

一步步带你分析 ESP32-C3 应用程序的启动流程

咱们接下来要找的便是这个宏界说SYS_STARTUP_FN()在哪里调用了。

由于是头文件,找函数调用就杂乱一点,可是问题不大,如下图:

一步步带你分析 ESP32-C3 应用程序的启动流程

点进去的确发现是我所需要查找的文件,假如找不到,可以在目录下面查找,先小目录,还是找不到,再用上层目录。 这也是看底层源码的根本方法。

1.6 cpu_start.c

老姿态先看文件途径如下:

一步步带你分析 ESP32-C3 应用程序的启动流程

cpu_start.c文件中,可以看到的确有上面头文件中宏界说SYS_STARTUP_FN()的调用,里边主要便是几个发动cpu的函数, 其间是call_start_cpu0函数调用了这个宏界说:

一步步带你分析 ESP32-C3 应用程序的启动流程

函数的内容是许多的,这儿咱们就不逐个剖析。可是到了这儿,咱们再结合官方的阐明文档再看一遍:

一步步带你分析 ESP32-C3 应用程序的启动流程

这姿态去了解,感觉官方说得好简略,实际上都是层层调用。

剖析到这儿,咱们都现已进入进口函数了,那么程序是如何调用。依照曾经的了解,这个进口函数应该会在一个衔接脚本里边运用 ENTRY调用,就像ENTRY(call_start_cpu0);

实际上,假如去文件夹查找可以找到许多文件中有ENTRY(call_start_cpu0);,即使咱们值选择与 ESP32-C3 有关的,也有不同的当地,那么到底是哪个呢?咱们还得持续顺藤摸瓜!

1.7 esp32c3.project.ld.in

在组件的esp32c3目录下面查找call_start_cpu0,找到一个运用了ENTRY(call_start_cpu0);的链接文件:(有过错请指出)

一步步带你分析 ESP32-C3 应用程序的启动流程

这个和咱们的STM32中剖析中的类似,便是进入到进口函数执行:

一步步带你分析 ESP32-C3 应用程序的启动流程

文件途径:

一步步带你分析 ESP32-C3 应用程序的启动流程

咱们还得往下简略看看二级引导程序。

二、二级引导程序

二级引导程序,根据现在我的了解,还不足以可以彻底的讲清楚,官方说到源码在 ESP-IDF 的 components/bootloader 目录下,我也简略的看了一下,在目录中找到比较“或许”的程序:

一步步带你分析 ESP32-C3 应用程序的启动流程

在这个bootloader_start.c文件中,正如官方的阐明相同,ESP-IDF 运用二级引导程序可以添加 Flash 分区的灵活性(运用分区表)等一些功能:

一步步带你分析 ESP32-C3 应用程序的启动流程

持续检查了一些代码(详细的便是在bootloader_start.c文件相关联的当地查找),确定bootloader_start.c便是二级引导程序的代码,根据LOG输出判别的 = =!

一步步带你分析 ESP32-C3 应用程序的启动流程

在bootloader 目录下也有 ESP32-C3 的链接文件:

一步步带你分析 ESP32-C3 应用程序的启动流程

在其间也有ENTRY(call_start_cpu0);的调用,这个应该是和二级引导程序中bootloader_start.c中对应的链接文件(有问题清指出)。

一步步带你分析 ESP32-C3 应用程序的启动流程

结语

文章在前面C言语发动的部分却是还算满意,到底层今后,对生疏的 risc-v 内核和架构还是处于含糊的状态,期望小伙伴多多给些意见。

文章整体只能算是代码的流程解析,并没有剖析函数的功能,这是我不满意的当地,冰冻三尺非一日之寒,加油! 文章会随着博主的了解深化坚持更新,期望今后能有时刻从内存,从架构好好的完善一下文章!