持续创作,加快生长!这是我参加「日新方案 10 月更文应战」的第29天,点击检查活动详情
网上阐明一大堆,根本是官网文档仿制没有额定解说!
关于ESP32-C3的 risc-v 内核,是我选择他的原因之一,
了解芯片上电后的发动流程,有利于咱们愈加深化了解芯片。
前言
关于ARM内核的STM32的发动流程,我曾经的博文详细剖析过,搞懂了STM32的发动流程关于芯片的运用和了解来说就会更上一个等级。现在咱们新接触的 risc-v 内核的ESP32-C3,假如可以搞明白他的发动流程,就能更深的了解 ESP32-C3。
在写文章之前也看了许多网上的文章,然后官方的阐明也看过了,网上绝大多数都是官网文档仿制一遍,这倒没什么,究竟官网权威,问题是,仿制一遍过来没有做过多的解说,没有额定的剖析,还写个原创,我真是服了。当然不扫除我没看到的好的文章,也正是由于根本没有看到愈加详细的剖析,我决定要自己写一篇记载,一来作为自己记载,二来底层有些当地目前来说我的确不是了解透彻,必定有不到位的当地,期望咱们多提意见,能让文章愈加完善。
依照惯例,我把能找到的文章和官方的材料都看了好多遍,官方说到的3大过程:
关于上述说到的3大过程,最简略的明晰的是第三步,第二步也有源码,却是可以检查试着剖析一下,可是第一步的确,仅仅知道这么回事,详细的完成方法由于程序是在ESP32-C3 的内部 ROM 中,的确找不到可以剖析的源码和材料。
芯片的发动流程,大多离不开发动文件和链接文件。ESP32-C3应该也是这样,原本依照了解,应该找到底层的发动文件和衔接文件开端依照过程剖析,可是检查了一会底层代码,由于对底层架构深化了解得还不行,没有找到= =! 所以想着怎么办?
不能依照从最开端到完毕的次序来,那么就依照从完毕到开端的次序来!咱们从app_main
函数反过来一层一层网前看,看看经过了一些什么处理,程序才执行到app_main
函数的!
留意,文章以倒叙的方法阐明~ ~
本文是根据 VScode 插件的工程结构来阐明(Ubuntu环境)。
一、应用程序发动阶段
1.1 app_main.c
咱们从app_main.c
的主函数app_main
中,咱们直接通过转到界说看看上一层:
1.2 port_common.c
app_main 往上找的文件是 port_common.c
,途径如下:
是哪一个使命调用了app_main
呢,咱们直接往上就能看到,
main_task
调用了app_main
,
而main_task
这个使命就在esp_startup_start_app_common
函数中创立:
知道了esp_startup_start_app_common
函数创立了main_task
这个使命,
那么这个函数在哪边有调用呢?咱们持续往上看,
找到esp_startup_start_app
函数中调用了esp_startup_start_app_common
,
调用完成今后就开启了 FreeRTOS 使命调度。
对应的,咱们看一下发动LOG:
1.3 port.c
咱们又进入了一个新的文件 port.c
,途径如下:
接着上面的,从esp_startup_start_app
函数往上找,
又找到一个start_cpu0_default
函数,如图:
1.4 startup.c
又找到一个新文件startup.c
,途径如下:
start_cpu0_default
在 startup.c
文件的 start_cpu0_default
函数,其间进行了许多关键过程,详细可以自行检查代码:
对应的,咱们看一下发动LOG:
咱们还想看 start_cpu0_default
函数从哪里调用,可是这时候现已无法跳转了,这时候咱们依然在startup.c
文件中查找,可以找到下面一句话:
这句话的意思便是使得 start_cpu0_default
函数弱衔接到start_cpu0
函数,假如没有额定的声明,start_cpu0_default
函数等价于start_cpu0
函数。(有过错请指出)
持续看看与 start_cpu0
函数 有关的程序,g_startup_fn
好像是一个数组?如图:
尝试着对 g_startup_fn
运用转到界说,咱们进入了别的一个新的文件,可以找到一个宏界说SYS_STARTUP_FN()
:
1.5 startup_internal.h
老姿态先看文件途径如下:
这是一个头文件,所以这儿边必定都是函数的声明和宏界说,咱们在这个文件中需要重视的当地便是一个宏界说#define SYS_STARTUP_FN() ((*g_startup_fn[(cpu_hal_get_core_id())])())
:
咱们接下来要找的便是这个宏界说SYS_STARTUP_FN()
在哪里调用了。
由于是头文件,找函数调用就杂乱一点,可是问题不大,如下图:
点进去的确发现是我所需要查找的文件,假如找不到,可以在目录下面查找,先小目录,还是找不到,再用上层目录。 这也是看底层源码的根本方法。
1.6 cpu_start.c
老姿态先看文件途径如下:
在cpu_start.c
文件中,可以看到的确有上面头文件中宏界说SYS_STARTUP_FN()
的调用,里边主要便是几个发动cpu的函数,
其间是call_start_cpu0
函数调用了这个宏界说:
函数的内容是许多的,这儿咱们就不逐个剖析。可是到了这儿,咱们再结合官方的阐明文档再看一遍:
这姿态去了解,感觉官方说得好简略,实际上都是层层调用。
剖析到这儿,咱们都现已进入进口函数了,那么程序是如何调用。依照曾经的了解,这个进口函数应该会在一个衔接脚本里边运用 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);
的链接文件:(有过错请指出)
这个和咱们的STM32中剖析中的类似,便是进入到进口函数执行:
文件途径:
咱们还得往下简略看看二级引导程序。
二、二级引导程序
二级引导程序,根据现在我的了解,还不足以可以彻底的讲清楚,官方说到源码在 ESP-IDF 的 components/bootloader 目录下,我也简略的看了一下,在目录中找到比较“或许”的程序:
在这个bootloader_start.c
文件中,正如官方的阐明相同,ESP-IDF 运用二级引导程序可以添加 Flash 分区的灵活性(运用分区表)等一些功能:
持续检查了一些代码(详细的便是在bootloader_start.c
文件相关联的当地查找),确定bootloader_start.c
便是二级引导程序的代码,根据LOG输出判别的 = =!
在bootloader 目录下也有 ESP32-C3 的链接文件:
在其间也有ENTRY(call_start_cpu0);
的调用,这个应该是和二级引导程序中bootloader_start.c
中对应的链接文件(有问题清指出)。
结语
文章在前面C言语发动的部分却是还算满意,到底层今后,对生疏的 risc-v 内核和架构还是处于含糊的状态,期望小伙伴多多给些意见。
文章整体只能算是代码的流程解析,并没有剖析函数的功能,这是我不满意的当地,冰冻三尺非一日之寒,加油! 文章会随着博主的了解深化坚持更新,期望今后能有时刻从内存,从架构好好的完善一下文章!