根据鱼油提供的日志和描述,
ESP32S3 模组在完成某些操作后发生了重启。
在运行日志中可以看到,当 app_main() 函数返回后,系统重新启动:
I (909) main_task: Returned from app_main()
在 ESPIDF 中,app_main() 函数是应用程序的入口点。
通常情况下,我们会在 app_main() 中创建各种任务 (tasks) 来执行程序逻辑,而不是直接从 app_main() 返回。
一旦 app_main() 函数执行完毕并返回,系统默认行为是重启。
1. 人脸识别完成后连接蓝牙成功导致重启:当人脸识别完成后再连接蓝牙,一旦蓝牙连接成功,ESP32S3 模组就重启。这可能是因为 app_main() 函数执行完了所有逻辑并返回,导致系统自动重启。
2. 连接蓝牙后进行人脸识别导致重启:类似地,当先连接蓝牙,再进行人脸识别后,识别通过后 ESP32S3 模组重启,这也可能是 app_main() 函数执行完所有逻辑后返回所致。
导致重启的可能原因:
- app_main()函数返回:在 ESP-IDF 中,如果 app_main() 函数正常返回,ESP32 会进行重新启动。此行为是预期的,因为 app_main() 是用户应用的主要执行函数。通常,应确保 app_main() 在应用程序的生命周期内不会返回。
- 电源问题或Brownout: 如果电源不稳定,可能会导致 ESP32S3 重启。但从日志中没有看到任何与电源问题相关的信息。
- 内存或WDT(看门狗定时器)问题: 如果应用程序内存溢出或看门狗超时,也可能导致重启。但日志中没有显示任何 panic 信息或WDT触发信息。
- 程序调用 esp_restart(): 应用程序可能在某些情况下主动调用 esp_restart() 重新启动设备。
从提供的日志我们可以看到以下关键点:
- app_main() 函数开始执行(I (429) main_task: Calling app_main())。
- 在 app_main() 中执行一系列操作,包括 GPIO 配置、蓝牙初始化、读取/写入操作等。
- 最后,日志显示 I (909) main_task: Returned from app_main(),表示 app_main() 执行完成并返回。
- 随后系统自动重启,重新加载运行(rst:0x1 (POWERON),boot:0xb (SPI_FAST_FLASH_BOOT))。
1. 确保 app_main() 不返回: app_main() 是应用程序的主函数,不应该正常返回。如果 app_main() 返回,系统将默认重启。
为了防止 app_main() 返回,可以使用无线循环或任务调度来保持应用程序运行:
void app_main(void)
{
// 执行初始化和配置任务
...
// 创建任务、定时器或其他应用逻辑
// 保持 app_main 运行
for (;;) {
vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟1秒以释放CPU
}
// 或者使用 vTaskDelete(NULL); 来删除main task
// vTaskDelete(NULL);
}
确保任务正确运行:当需要执行特定逻辑(如人脸识别和蓝牙连接)时,通常会创建新的 FreeRTOS 任务而不是在 app_main() 中完成所有逻辑。app_main() 函数只负责初始化和创建任务,然后保持应用程序运行。
检查程序逻辑:确保在进行人脸识别和蓝牙连接的流程中,没有代码调用 esp_restart() 或其他重启函数。确保内存和电源稳定。使用 esp_get_free_heap_size() 等函数监视内存情况。
使用深度调试信息:若问题持续,启用更多日志级别(如 debug 或 verbose)可能有助于定位问题根源。
app_main() 函数执行完毕后返回是造成系统重启的主要原因之一。
必须确保 app_main() 不返回,从而维持应用程序的正常运行。
可以通过无限循环 (while(1)) 或使用 FreeRTOS 的任务功能 (vTaskDelete(NULL)) 来防止 app_main() 返回。
void app_main(void)
{
// 初始化和配置
...
// 创建任务,用于处理人脸识别、蓝牙连接等逻辑
xTaskCreatePinnedToCore(&face_recognition_task, "face_recog_task", 4096, NULL, 5, NULL, APP_CPU_NUM);
xTaskCreatePinnedToCore(&ble_connection_task, "ble_conn_task", 4096, NULL, 5, NULL, APP_CPU_NUM);
// 通过一个无限循环保持 app_main 运行
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}