网上说明一大堆,基本是官网文档复制没有额外解释!
对于ESP32-C3的 risc-v 内核,是我选择他的原因之一,
了解芯片上电后的启动流程,有利于我们更加深入理解芯片。
contenido
prefacio
Para el proceso de inicio STM32 del núcleo ARM, lo analicé en detalle en mis publicaciones de blog anteriores, y comprender el proceso de inicio STM32 será un nivel superior para el uso y la comprensión del chip. Ahora somos nuevos en ESP32-C3 con núcleo risc-v Si podemos entender su proceso de inicio, podemos entender ESP32-C3 más profundamente.
Antes de escribir el artículo, también leí muchos artículos en Internet y luego también leí las instrucciones oficiales. La mayoría de los documentos en Internet están copiados del sitio web oficial. Esto no es nada. Después de todo, el sitio web oficial es autorizado La explicación, sin análisis adicional, sino también escribir un original, soy realmente XX. Por supuesto, no descarto los buenos artículos que no he visto, y es precisamente porque no he visto un análisis más detallado. Decidí escribir un registro por mi cuenta. Primero, lo usaré como mi propio registro. En segundo lugar, hay algunos lugares en la parte inferior que realmente hago. No es una comprensión completa, y debe haber algunos lugares que no están en su lugar. Espero que puedas dar más opiniones para que el artículo sea más perfecto. .
Como de costumbre, he leído los artículos y materiales oficiales que puedo encontrar muchas veces, los tres pasos que menciona el funcionario son:
Para los tres pasos principales mencionados anteriormente, el más simple y claro es el tercer paso. El segundo paso también tiene el código fuente, pero puede verificarlo e intentar analizarlo, pero el primer paso es verdadero, solo sepa lo que está sucediendo. El método de implementación específico se debe a que el programa está en la ROM interna de ESP32-C3, y es cierto que no se encuentra el código fuente y los datos que se pueden analizar.
El proceso de inicio del chip es en su mayoría inseparable del archivo de inicio y el archivo de enlace. Lo mismo debería ser cierto para ESP32-C3. Originalmente, según tengo entendido, debería encontrar el archivo de inicio y el archivo de conexión subyacentes y comenzar a analizarlos de acuerdo con los pasos, pero revisé el código subyacente por un tiempo, porque no ¡No sé lo suficiente sobre la arquitectura subyacente, y no la encontré = =! Así que pensando en qué hacer?
¡No puedes venir en el orden del principio al final, y luego venir en el orden del final al principio! ¡Veamos app_main
la función frente a la red capa por capa y veamos qué se ha procesado antes de que el programa ejecute la app_main
función!
Tenga en cuenta que el artículo se explica en flashback ~~
Este artículo se basa en la estructura de ingeniería del complemento VScode (entorno Ubuntu). Consulte la siguiente publicación de blog para conocer la configuración del entorno:
Primero, la fase de inicio de la aplicación.
1.1 aplicación_principal.c
Desde app_main.c
nuestra función principal app_main
, pasamos directamente al nivel anterior yendo a la definición:
1.2 puerto_común.c
El archivo que busca app_main es la port_common.c
siguiente ruta:
Qué tarea se llama app_main
, podemos ver directamente arriba,
main_task
call app_main
,
y main_task
esta tarea se crea en la esp_startup_start_app_common
función:
sepa que la esp_startup_start_app_common
función crea main_task
esta tarea,
entonces, ¿dónde se llama esta función? Seguimos buscando y
encontramos esp_startup_start_app
la llamada en la función. Una vez completada la esp_startup_start_app_common
llamada
, se activa la programación de tareas de FreeRTOS.
En consecuencia, echemos un vistazo al REGISTRO de inicio:
1.3 puerto.c
Ingresamos de nuevo un archivo nuevo port.c
, la ruta es la siguiente:
Luego lo anterior, esp_startup_start_app
mira hacia arriba desde la función,
y encuentra otra start_cpu0_default
función, como se muestra en la figura:
1.4 inicio.c
Se encontró un nuevo archivo startup.c
con la siguiente ruta: start_cpu0_default
startup.c
En la start_cpu0_default
función del archivo, se llevan a cabo muchos pasos clave, y usted mismo puede verificar el código: En
consecuencia, echemos un vistazo al REGISTRO de inicio:
También queremos ver desde dónde se llama a la start_cpu0_default
función , pero es imposible saltar en este momento. En este momento, todavía estamos startup.c
buscando en el archivo, y podemos encontrar la siguiente oración:
El significado de esta oración es hacer la start_cpu0_default
función débilmente conectada a la start_cpu0
función, si no hay adicional declara que una start_cpu0_default
función es equivalente a una start_cpu0
función. (por favor señale los errores)
Continúe mirando el programa relacionado con la start_cpu0
función , g_startup_fn
¿parece ser una matriz? Como se muestra en la figura:
al tratar de g_startup_fn
usar ir a definición para, ingresamos otro archivo nuevo y podemos encontrar una definición de macro SYS_STARTUP_FN()
:
1.5 inicio_interno.h
La forma antigua de ver la ruta del archivo es la siguiente:
Este es un archivo de encabezado, por lo que debe haber declaraciones de funciones y definiciones de macros. El lugar al que debemos prestar atención en este archivo es una definición de macro #define SYS_STARTUP_FN() ((*g_startup_fn[(cpu_hal_get_core_id())])())
:
lo siguiente que debemos encontrar es dónde SYS_STARTUP_FN()
se llama a la definición de macro.
Debido a que es un archivo de encabezado, es un poco más complicado encontrar una llamada de función, pero no es un gran problema
y luego usar el directorio superior. Esta es también la forma básica de ver el código fuente subyacente.
1.6 cpu_start.c
La forma antigua de ver la ruta del archivo es la siguiente:
en el cpu_start.c
archivo, puede ver que, de hecho, hay llamadas a la definición de macro en el archivo de encabezado anterior SYS_STARTUP_FN()
, que son principalmente varias funciones que inician la CPU,
entre las cuales la call_start_cpu0
función llama esta definición de macro:
el contenido de la función es mucho Sí, no los analizaremos uno por uno aquí. Pero aquí, mirémoslo nuevamente en combinación con la documentación oficial:
para entenderlo así, parece que la declaración oficial es tan simple, pero de hecho se llama capa por capa.
Llegados a este punto del análisis, todos hemos entrado en la función de entrada, así como se llama el programa. De acuerdo con el entendimiento anterior, esta función de entrada debe ENTRY
llamarse , comoENTRY(call_start_cpu0);
De hecho, si vas a la búsqueda de carpetas y encuentras que hay muchos archivos ENTRY(call_start_cpu0);
, incluso si optamos por elegir algo relacionado con ESP32-C3, también hay diferentes lugares, entonces ¿cuál es? ¡Hay que seguir la pista!
1.7 esp32c3.proyecto.ld.in
esp32c3
Busque en el directorio del componente call_start_cpu0
y encuentre un ENTRY(call_start_cpu0);
archivo de enlace usado: (indique si hay un error)
Esto es similar al análisis en nuestro STM32, que es ingresar a la ejecución de la función de entrada:
ruta de archivo:
También tenemos que mirar hacia abajo brevemente en el gestor de arranque secundario.
En segundo lugar, el programa de arranque secundario
El cargador de arranque de segundo nivel, según mi comprensión actual, no es suficiente para ser completamente claro. El oficial menciona que el código fuente está en el directorio de componentes/cargador de arranque de ESP-IDF. ” programa:
En este bootloader_start.c
archivo, como las instrucciones oficiales , ESP-IDF usa el programa de arranque de segundo nivel para aumentar la flexibilidad de la partición Flash (usando la tabla de particiones) y otras funciones:
continúe verificando algunos códigos (específicamente, en el bootloader_start.c
archivo Encuentre el lugar relevante), determine bootloader_start.c
que es el código del programa de arranque secundario, juzgado según la salida LOG = =!
También hay un archivo de enlace para ESP32-C3 en el directorio del cargador de arranque: también
hay llamadas en él, este debería ser el archivo de enlace correspondiente al cargador de arranque de segundo nivel (señale claramente el problema).ENTRY(call_start_cpu0);
bootloader_start.c
Epílogo
El artículo es bastante satisfactorio en la parte anterior del inicio del lenguaje C. Después de la capa inferior, el kernel y la arquitectura desconocidos de risc-v todavía están en un estado vago. Espero que mis amigos den más opiniones.
El artículo en su conjunto solo puede considerarse como el análisis del proceso del código, y no hay una función para analizar la función. Esto es con lo que no estoy satisfecho. Tres pies congelados no es un día frío, ¡vamos!
El artículo se actualizará a medida que se profundice la comprensión del blogger. ¡Espero poder tener tiempo para mejorar el artículo desde la memoria y la arquitectura en el futuro!