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

第二章 分析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
    评论
if __name__ == "__main__"是一个常见的Python代码块,用于判断当前模块是否作为主程序执行。当一个Python文件被直接运行时,__name__的值会被设置为"__main__",而当它被作为模块导入时,__name__的值会是模块的名称。 在你提供的代码中,if __name__ == "__main__"语句用于判断当前模块是否作为主程序执行。如果是主程序执行,就会调用main()函数并打印出"pencil..."。如果是作为模块导入,main()函数不会被调用。 所以,根据你提供的代码,当你运行这个pencil.py文件时,会输出"pencil..."。但如果你将这个文件作为模块导入到其他文件中使用,main()函数不会被执行。 希望这个解答对你有帮助! #### 引用[.reference_title] - *1* [python中的if __name__ == "__main__"和sys.argv[]](https://blog.csdn.net/gehulushang/article/details/103972219)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [python——__name__ == __main__用法理解](https://blog.csdn.net/qq_45325885/article/details/122802535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

分~耳

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

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

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

打赏作者

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

抵扣说明:

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

余额充值