分析app_main之前运行了什么代码

本文详细分析了ESP-IDF应用程序在调用app_main之前执行的代码,包括硬件端口初始化、基本C运行环境配置、FreeRTOS系统初始化以及各种服务如WiFi和蓝牙的初始化过程。
摘要由CSDN通过智能技术生成

第二章 分析app_main之前运行了什么代码



前言

编译esp-box sdk下的examples下所有官方demo得到bin文件(此点能独立完成后买个官方样机,等样机到手后自行烧录全部demo都试一遍全部功能)。

一、任务是什么?

分析app_main之前运行了什么代码(可以阅读官方文档,阅读后写下来)。

二、代码分析

1.硬件和基本 C 语言运行环境的端口初始化

ESP-IDF 应用程序的入口是 components/esp_system/port/cpu_start.c 文件中的 call_start_cpu0 函数。
w
该端口层的初始化功能会初始化基本的 C 运行环境 (“CRT”),并对 SoC 的内部硬件进行了初始配置。

  • 为应用程序重新配置 CPU 异常(允许应用程序中断处理程序运行,并使用为应用程序配置的选项来处理 严重错误,而不是使用 ROM 提供的简易版错误处理程序处理。
  • 如果没有设置选项 CONFIG_BOOTLOADER_WDT_ENABLE,则不使能 RTC 看门狗定时器。
  • 初始化内部存储器(数据和 bss)。
  • 完成 MMU 高速缓存配置。
  • 如果配置了 PSRAM,则使能 PSRAM。
  • 将 CPU 时钟设置为项目配置的频率。
  • 根据应用程序头部设置重新配置主 SPI flash,这是为了与 ESP-IDF V4.0 之前的引导程序版本兼容,请参考 引导加载程序兼容性。
  • 如果应用程序被配置为在多个内核上运行,则启动另一个内核并等待其初始化(在类似的“端口层”初始化函数 call_start_cpu1 内)。

call_start_cpu0 完成运行后,将调用components/esp_system/startup.c 中找到的“系统层”初始化函数 start_cpu0。
e
其他内核也将完成端口层的初始化,并调用同一文件中的 start_other_cores。
w

2.软件服务和 FreeRTOS 的系统初始化

主要的系统初始化函数是 start_cpu0。默认情况下,这个函数与 start_cpu0_default 函数弱链接。
w
这意味着可以覆盖这个函数,增加一些额外的初始化步骤。
主要的系统初始化阶段包括:

  • 如果默认的日志级别允许,则记录该应用程序的相关信息(项目名称、应用程序版本 等)。
  • 初始化堆分配器(在这之前,所有分配必须是静态的或在堆栈上)。
  • 初始化 newlib 组件的系统调用和时间函数。
  • 配置断电检测器。
  • 根据 串行控制台配置 设置 libc stdin、stdout、和 stderr。
  • 执行与安全有关的检查,包括为该配置烧录 efuse(包括 禁用 ESP32 V3 的 ROM 下载模式、CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE)。
  • 初始化 SPI flash API 支持。
  • 调用全局 C++ 构造函数和任何标有 attribute((constructor)) 的 C 函数。

二级系统初始化允许单个组件被初始化。如果一个组件有一个用 ESP_SYSTEM_INIT_FN 宏注释的初始化函数,它将作为二级初始化的一部分被调用。

3.运行主任务并调用 app_main

在所有其他组件都初始化后,主任务会被创建,FreeRTOS 调度器开始运行。
做完一些初始化任务后(需要启动调度器),主任务在固件中运行应用程序提供的函数 app_main。
q
运行 app_main 的主任务有一个固定的 RTOS 优先级(比最小值高)和一个 可配置的堆栈大小。
e
与普通的 FreeRTOS 任务(或嵌入式 C 的 main 函数)不同,app_main 任务可以返回。如果app_main 函数返回,那么主任务将会被删除。系统将继续运行其他的 RTOS 任务。因此可以将 app_main 实现为一个创建其他应用任务然后返回的函数,或主应用任务本身。

总结

总之,在 app_main 函数之前会运行一些代码来完成一些初始化和配置操作。以下是 factory_demo 的主要初始化代码:

  1. 运行 esp_err_t ret = nvs_flash_init() 来初始化非易失性存储(NVS)。2
  2. 运行 esp_log_set_vprintf() 来设置日志输出函数。
  3. 运行 esp_err_t ret = esp_periph_set_register_callback() 来注册外设回调函数。
  4. 运行 periph_service_start() 来启动外设服务。
  5. 运行 esp_err_t ret = esp_periph_set_periph_overcur_callback() 来注册外设过电流回调函数。
  6. 运行 esp_err_t ret = esp_periph_set_play_finished_callback() 来注册外设播放完成回调函数。
  7. 运行 wifi_service_init() 来初始化 Wi-Fi 服务。
  8. 运行 esp_bluedroid_init() 来初始化蓝牙协议栈。
  9. 运行 esp_bluedroid_enable() 来启用蓝牙协议栈。
  10. 运行 esp_bt_gap_register_callback() 来注册蓝牙 GAP 回调函数。
  11. 运行 esp_bt_gap_set_scan_mode() 来设置蓝牙扫描模式。
  12. 运行 esp_bt_gap_start_discovery() 来开始进行蓝牙设备的扫描。
    在这里插入图片描述
    以上是 factory_demo 在 app_main 函数之前运行的一些代码,用于初始化和配置外设、Wi-Fi 和蓝牙相关的功能。这些代码将设备从启动状态转换为可执行其他操作的状态,为后续的应用程序逻辑做好准备。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

分~耳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值