前言我最终任务是使用开发板上的MIPI-CSI接口获取偶ov5647摄像头的图像并通过wife传输实际上开发板应该会有配套显示屏这样直接用示例代码就行了示例代码里有一个在显示屏上显示图像的代码由于没有显示屏我不知道这个开发板有没有获取视频成功于是我先开发wife。1.原理这个开发板不能像其他ESP32系列开发板一样直接AP或者STA模式被连接或者连接也就是说开源的示例代码和按平常那样使用wifi是用不了的这是官方文档的相关说明。这块开发板有两块芯片分别是ESP32P4和ESP32C5我们平常烧录的代码和运行都是在ESP32P4中但是P4并不支持wife只能使用C5的wifeESP32-C5与ESP32-P4芯片通过SIDO连接。为开发板提供Wi-Fi 6能力所以只能在C5中烧录相关代码后在P4中操作两个芯片在板子上已经接好了SDIO的接口使用SDIO进行通信所以要实现开发板连接WIFE步骤如下1.在C5中烧录官方提供的slave代码2.通过编写P4代码实现wife连接。看上去就这两个步骤但是坑依旧非常多。2.在C5中烧录官方代码这是官方文档中提到的烧录C5代码的步骤需要先下载仓库代码随后使用命令行编译下载代码与我们在vscode中使用底下的按键编译烧录监视是一个效果。官方文档没提的是下载这个代码需要换一个接口两个芯片无法共用一个接口设置目标芯片的意思不是表示把代码从烧录给P4变成C5所以我们烧录不能使用之前的接口在开发板上找到一个J5的端口这里就是C5的下载端口我们烧录使用USB转TTL连接的GNDTXDRXD就行了具体连线如下TX和RX交叉然后共地三根线同时还需要将BOOT和EN都接地GND这两根线是烧录成功的关键需要进入下载模式否则烧录会报错开发板无应答同样烧录不进去。具体的操作五根线连接好后编译烧录当出现烧录后把EN接地的线拔了就开始下载了。总之在下载前先拉低BOOT然后拉低一次EN就能进入下载模式了。C5这边就操作完了接下来是P4。2.P4操作打开ESP-IDF终端输入idf.py menuconfig进入SDK配置界面这个配置跟底下工具栏的齿轮作用是一样的不过不过一个是图形化一个是文字首先要配置SDIO的通信引脚这是第一个坑这是通过底部齿轮进入的配置由于更改的地方很多图形化不太方便所以直接在这改这是默认的引脚没有设置正确会出现107已经建立SDIO连接无响应大概率是没连接上引脚不对我这里除了108还有Link not yet up的报错这个是我P4代码有问题缺少 esp_hosted_init() 和 esp_hosted_connect_to_slave() 调用 没有等待SDIO transport建立完成就直接调用WiFi导致 ESP-Hosted link not yet up 错误。同时官方示例显示 1.必须先注册 ESP_HOSTED_EVENT 事件处理器 2.调用 esp_hosted_init() esp_hosted_connect_to_slave() 3.用信号量等待 ESP_HOSTED_EVENT_TRANSPORT_UP 事件 4.等到transport UP之后才能调用WiFi 你当前代码缺少步骤1、2中的 esp_hosted_connect_to_slave()以及步骤3的等待机制官方文档有正确的输出日志通过对比可以发现自己的问题。查看官方日志和原理图可以发现引脚配置不对在配置界面出现的两个选项配置都不对要使用默认然后自己修改如果使用自带的选项引脚就不能修改了正确设置把上述代码修改完发现没有日志报错还有C5的Reset GPIO配置CONFIG_ESP_SDIO_GPIO_RESET-1未配置reset引脚但P4端用GPIO54来reset C5。最后将54改为1最后一个警告也没了。但是我还是无法连接wife我又加了一个reason码打印和又一个AP扫描看能不能扫到我的wife201是WIFI_REASON_NO_AP_FOUND找不到APesp_wifi_scan_start(NULL, true); uint16_t ap_count 0; esp_wifi_scan_get_ap_num(ap_count); printf(扫描到 %d 个AP:\n, ap_count); if (ap_count 0) { wifi_ap_record_t *ap_list malloc(ap_count * sizeof(wifi_ap_record_t)); if (ap_list) { esp_wifi_scan_get_ap_records(ap_count, ap_list); for (int i 0; i ap_count; i) { printf( [%d] SSID: %s, RSSI: %d, 频道: %d\n, i, ap_list[i].ssid, ap_list[i].rssi, ap_list[i].primary); } free(ap_list); } }结果连wife都扫不到后面发现是我的wife只开了2.4G频段之前使用ESP8266时是只能连接2.4G我没想到C5可以连接5G开启5G频段后连接成功最后是P4完整代码#include string.h #include freertos/FreeRTOS.h #include freertos/task.h #include freertos/semphr.h #include nvs_flash.h #include esp_wifi.h #include esp_event.h #include esp_netif.h #include esp_hosted.h #define WIFI_SSID WT99P4C5 #define WIFI_PASS 12345678 static SemaphoreHandle_t s_hosted_up_sem; static void hosted_event_handler(void* arg, esp_event_base_t base, int32_t id, void* data) { if (base ESP_HOSTED_EVENT id ESP_HOSTED_EVENT_TRANSPORT_UP) { printf(SDIO transport UP\n); xSemaphoreGive(s_hosted_up_sem); } } static void wifi_event_handler(void* arg, esp_event_base_t base, int32_t id, void* data) { if (base WIFI_EVENT id WIFI_EVENT_STA_START) { printf(WiFi 启动 → 正在连接...\n); esp_wifi_connect(); } else if (base WIFI_EVENT id WIFI_EVENT_STA_CONNECTED) { printf(WiFi 连接成功等待获取IP...\n); } else if (base IP_EVENT id IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t* event (ip_event_got_ip_t*)data; printf(获取IP地址: IPSTR \n, IP2STR(event-ip_info.ip)); } else if (base WIFI_EVENT id WIFI_EVENT_STA_DISCONNECTED) { wifi_event_sta_disconnected_t* disconn (wifi_event_sta_disconnected_t*)data; printf(WiFi 断开reason: %d重试连接...\n, disconn-reason); vTaskDelay(pdMS_TO_TICKS(1000)); esp_wifi_connect(); } } void app_main(void) { // 初始化 NVS esp_err_t err nvs_flash_init(); if (err ESP_ERR_NVS_NO_FREE_PAGES || err ESP_ERR_NVS_NEW_VERSION_FOUND) { nvs_flash_erase(); nvs_flash_init(); } // 系统初始化 esp_netif_init(); esp_event_loop_create_default(); // 创建信号量用于等待SDIO transport就绪 s_hosted_up_sem xSemaphoreCreateBinary(); // 注册esp_hosted事件必须在esp_hosted_init()之前注册 esp_event_handler_register(ESP_HOSTED_EVENT, ESP_EVENT_ANY_ID, hosted_event_handler, NULL); // 初始化esp_hosted并连接到C5 esp_hosted_init(); esp_hosted_connect_to_slave(); // 等待SDIO transport建立完成 printf(等待与C5建立SDIO连接...\n); xSemaphoreTake(s_hosted_up_sem, portMAX_DELAY); printf(SDIO连接已建立开始WiFi初始化\n); // WiFi netif和事件 esp_netif_create_default_wifi_sta(); esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL); esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL); // WiFi 初始化 wifi_init_config_t cfg WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(cfg); // WiFi 配置 wifi_config_t wifi_config { .sta { .ssid WIFI_SSID, .password WIFI_PASS, }, }; esp_wifi_set_mode(WIFI_MODE_STA); esp_wifi_set_config(WIFI_IF_STA, wifi_config); esp_wifi_start(); // 扫描附近AP确认目标SSID可见 esp_wifi_scan_start(NULL, true); uint16_t ap_count 0; esp_wifi_scan_get_ap_num(ap_count); printf(扫描到 %d 个AP:\n, ap_count); if (ap_count 0) { wifi_ap_record_t *ap_list malloc(ap_count * sizeof(wifi_ap_record_t)); if (ap_list) { esp_wifi_scan_get_ap_records(ap_count, ap_list); for (int i 0; i ap_count; i) { printf( [%d] SSID: %s, RSSI: %d, 频道: %d\n, i, ap_list[i].ssid, ap_list[i].rssi, ap_list[i].primary); } free(ap_list); } } printf(\n); printf( P4 正在通过 C5 连接 WiFi: %s \n, WIFI_SSID); printf(\n); }需要注意的是如果直接复制粘贴就用会找不到头文件需要在main目录下的CMakeLists.txt文件下添加依赖库idf_component_register(SRCS hello_world_main.c # 私有依赖库 PRIV_REQUIRES spi_flash # 闪存驱动基础必备 esp_wifi # WiFi 协议栈核心 esp_netif # 网络接口必备 esp_event # 事件循环系统 nvs_flash # 持久化存储WiFi必备 esp_wifi_remote # Wi-Fi Remote 控制C5核心 esp_hosted # P4与C5 SDIO通信必须 # 头文件目录 INCLUDE_DIRS )然后没有的依赖库需要导入在main文件夹下的idf_componet.yml中其实我在开发过程中原不止踩了这么多坑但是由于是事后写的很多地方没截图就没写如果有问题欢迎讨论。