ESP-IDF LP Core GPIO 唤醒测试指南基于双板联测的深睡眠 GPIO 唤醒验证方案【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf本指南围绕 ESP-IDF 中lp_core_gpio_wakeup_tests测试应用展开讲解如何在支持 LP Core低功耗协处理器的 ESP32-C5 / ESP32-C6 / ESP32-P4 芯片上利用双板wakee waker协作的方式验证“深睡眠下外部 GPIO 下降沿唤醒 LP Core再由 LP Core 唤醒主处理器HP”的完整链路。读完本文你将掌握该测试应用的硬件接线方式、Unity 多阶段用例的组织逻辑、LP Core 侧唤醒程序的写法以及如何用 pytest 的generic_multi_device模式在本地复现整个唤醒时序验证。测试应用概述与适用芯片lp_core_gpio_wakeup_tests是 ESP-IDF 低功耗子系统ULP/LP Core下的一个专项测试应用位于 components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests其唯一目的是验证 LP Core 的 GPIO 唤醒功能在深睡眠场景下的正确性——包括真实的唤醒触发、虚假唤醒spurious wakeup的抑制以及唤醒后主处理器对唤醒原因链的核实。该测试应用通过 README 中的支持矩阵声明了三个受支持的目标芯片Supported TargetsESP32-C5ESP32-C6ESP32-P4从 pytest 脚本中的目标过滤条件可以确认能够运行该测试的目标必须同时满足四个 SoC 能力见 pytest_lp_core_gpio_wakeup.py 中的soc_filtered_targetsSOC_LP_CORE_SUPPORTED 1芯片带 LP Core 协处理器SOC_RTCIO_PIN_COUNT 0存在可用于唤醒的 RTC GPIOSOC_DEEP_SLEEP_SUPPORTED 1支持深睡眠SOC_RTC_GPIO_EDGE_WAKEUP_SUPPORTED 1RTC GPIO 支持边沿唤醒。测试原理一次完整的外部 GPIO 下降沿唤醒链路README 明确指出该测试应用复现了gpio_wakeup示例LP Core GPIO 唤醒示例的完整流程并将其拆解为四个可验证的步骤主处理器HP侧准备HP 配置唤醒 GPIO将编译好的 LP Core 程序加载进 LP 核内存并启动随后进入深睡眠空闲高电平保持waker 板将共享 GPIO 维持在空闲高电平并保持足够长时间用于捕获虚假唤醒——如果 wakee 板在下降沿到来之前就提前重启说明唤醒逻辑存在误触发问题下降沿触发唤醒外部waker 板产生下降沿LP Core 被 GPIO 边沿唤醒。LP Core 程序记录本次 LP 唤醒原因然后唤醒主处理器并清除 GPIO 中断状态唤醒原因验证HP 从深睡眠恢复后验证两件事——系统级 ULP 唤醒原因ESP_SLEEP_WAKEUP_ULP是否置位以及 LP Core 记录的唤醒原因是否为LP_IOLP GPIO 唤醒源。这四个步骤恰好对应了实际产品中“低功耗待机 → 外部事件触发 → 协处理器快速响应 → 唤醒主控处理业务”的典型低功耗工作模式因此该测试不仅验证功能正确性也具备很强的工程参考价值。硬件搭建双板generic_multi_device接线方案该测试是一个generic_multi_device多设备测试需要两块同型号开发板配合完成两块板的唤醒 GPIO 必须短接在一起。WakeeDUT 0被唤醒板运行一个多阶段multi-stageUnity 测试用例。它先进入深睡眠随后在外部下降沿到达后被唤醒并校验 ULP 唤醒原因WakerDUT 1唤醒板运行两个独立的 Unity 测试用例分别把共享 GPIO 驱动为高电平和低电平从而为 wakee 板提供“空闲高电平”和“下降沿”两种外部信号。两块板之间默认使用的唤醒引脚为GPIO2该默认值由 Kconfig.projbuild 中的TEST_LP_GPIO_WAKEUP_PIN配置项提供其注释要求 waker 板上必须是同一个 GPIO 编号并配置为输出menu LP GPIO Wakeup Test Configuration config TEST_LP_GPIO_WAKEUP_PIN int GPIO pin wired between wakee and waker boards default 2 help RTC GPIO pin used for LP core GPIO wakeup on the sleeping board. The same pin number must be wired to the GPIO output on the waker board. endmenu接线时需要注意wakee 一侧使用的必须是RTC GPIO即支持rtc_gpio_*API 的引脚因为深睡眠阶段只有 RTC 域保持供电普通 GPIO 无法在深睡眠中感知外部电平变化。源码剖析wakee 板的唤醒配置与多阶段用例wakee 侧的全部逻辑位于 test_lp_gpio_wakeup.c分为三个阶段配置唤醒 GPIO、加载并启动 LP 程序、进入深睡眠。唤醒 GPIO 的 RTC 配置static void configure_wakee_gpio(void) { rtc_gpio_init(TEST_WAKEUP_PIN); rtc_gpio_set_direction(TEST_WAKEUP_PIN, RTC_GPIO_MODE_INPUT_ONLY); rtc_gpio_pulldown_dis(TEST_WAKEUP_PIN); rtc_gpio_pullup_en(TEST_WAKEUP_PIN); rtc_gpio_wakeup_enable(TEST_WAKEUP_PIN, GPIO_INTR_NEGEDGE); }关键点引脚被初始化为 RTC GPIO 输入模式关闭下拉、使能上拉确保 waker 板断开或未驱动时电平不会悬空并以GPIO_INTR_NEGEDGE下降沿作为唤醒触发条件。上拉配置还保证了空闲电平为高——这与 waker 板“空闲高电平”策略相互印证。加载并启动 LP Core 程序static void load_and_start_lp_core_program(void) { TEST_ESP_OK(ulp_lp_core_load_binary(lp_core_gpio_wakeup_bin_start, lp_core_gpio_wakeup_bin_end - lp_core_gpio_wakeup_bin_start)); ulp_lp_core_cfg_t cfg { .wakeup_source ULP_LP_CORE_WAKEUP_SOURCE_LP_IO, }; TEST_ESP_OK(ulp_lp_core_run(cfg)); }LP 程序二进制通过ulp_embed_binary宏嵌入到应用镜像中见 main/CMakeLists.txt符号lp_core_gpio_wakeup_bin_start/_end即其起止地址。ulp_lp_core_cfg_t.wakeup_source被设置为ULP_LP_CORE_WAKEUP_SOURCE_LP_IO声明 LP Core 在深睡眠中由 LP GPIO 事件唤醒。ulp_lp_core_run的底层实现位于 components/ulp/lp_core/lp_core/lp_core_utils.c它负责配置唤醒源并使 LP Core 进入等待状态。多阶段用例深睡眠重启后的状态延续static void lp_gpio_wakeup_wakee_init(void) { configure_wakee_gpio(); load_and_start_lp_core_program(); unity_wait_for_signal(GPIO_IDLE_HIGH_SIGNAL); TEST_ESP_OK(esp_sleep_enable_ulp_wakeup()); esp_deep_sleep_start(); TEST_FAIL_MESSAGE(Should have entered deep sleep); } static void lp_gpio_wakeup_wakee_after_wake(void) { TEST_ASSERT(esp_sleep_get_wakeup_causes() BIT(ESP_SLEEP_WAKEUP_ULP)); printf(LP wakeup cause: 0x% PRIx32 \n, ulp_lp_wakeup_cause); TEST_ASSERT_EQUAL_HEX32(LP_CORE_LL_WAKEUP_SOURCE_LP_IO, ulp_lp_wakeup_cause); } TEST_CASE_MULTIPLE_STAGES( LP GPIO wakeup wakee from deep sleep, [lp_core][lp_gpio_wakeup][test_envgeneric_multi_device][timeout120][deepsleep], lp_gpio_wakeup_wakee_init, lp_gpio_wakeup_wakee_after_wake);这里使用了 Unity 的TEST_CASE_MULTIPLE_STAGES机制因为深睡眠会把芯片重启回 Unity 菜单单个函数无法同时覆盖“入睡前”和“唤醒后”两个阶段必须拆成wakee_init入睡前和after_wake唤醒后两个 stage。唤醒后 HP 侧做两项断言esp_sleep_get_wakeup_causes()中包含ESP_SLEEP_WAKEUP_ULP位证明本次深睡眠唤醒由 ULP/LP Core 触发LP 核侧全局变量ulp_lp_wakeup_cause的值等于LP_CORE_LL_WAKEUP_SOURCE_LP_IO证明 LP Core 自身记录到的唤醒源确实是 LP GPIO。测试用例的 tag 中还包含test_envgeneric_multi_device这正是 pytest 选择双板测试环境、并把用例路由到对应 DUT 的依据。源码剖析LP Core 侧唤醒程序LP 核侧程序非常精简位于 lp_core/test_main_gpio_wakeup.c#include ulp_lp_core_utils.h #include ulp_lp_core_gpio.h #include hal/lp_core_ll.h uint32_t lp_wakeup_cause; int main(void) { lp_wakeup_cause ulp_lp_core_get_wakeup_cause(); ulp_lp_core_wakeup_main_processor(); ulp_lp_core_gpio_clear_intr_status(); return 0; }它依次完成三件事正好对应 README 第 3 步的描述ulp_lp_core_get_wakeup_cause()读取并保存本次唤醒原因到全局变量lp_wakeup_cause。该变量被声明为普通uint32_t全局符号LP 与 HP 共享内存因此 HP 侧代码test_lp_gpio_wakeup.c可以直接以ulp_lp_wakeup_cause的形式访问它ulp_lp_core_wakeup_main_processor()唤醒处于深睡眠的主处理器ulp_lp_core_gpio_clear_intr_status()清除 GPIO 中断状态位防止下次唤醒因残留中断标志而误触发。相关 API 声明位于 ulp_lp_core_gpio.h唤醒原因读取与唤醒源判断逻辑则在 ulp_lp_core_utils.h 与 lp_core_utils.c 中——lp_core_utils.c中通过lp_core_ll_get_wakeup_source() LP_CORE_LL_WAKEUP_SOURCE_LP_IO来判定是否由 LP IO 唤醒。源码剖析waker 板的电平驱动waker 板运行两个普通 Unity 用例分别把共享 GPIO 拉高、拉低static void configure_waker_gpio_output(void) { gpio_config_t io_conf { .pin_bit_mask (1ULL TEST_WAKEUP_PIN), .mode GPIO_MODE_OUTPUT, .pull_down_en GPIO_PULLDOWN_DISABLE, .pull_up_en GPIO_PULLUP_DISABLE, .intr_type GPIO_INTR_DISABLE, }; TEST_ESP_OK(gpio_config(io_conf)); } static void lp_gpio_wakeup_waker_idle_high(void) { configure_waker_gpio_output(); TEST_ESP_OK(gpio_set_level(TEST_WAKEUP_PIN, 1)); } static void lp_gpio_wakeup_waker_wake_low(void) { configure_waker_gpio_output(); TEST_ESP_OK(gpio_set_level(TEST_WAKEUP_PIN, 0)); }注意 waker 板使用的是通用 GPIO 驱动driver/gpio.h的gpio_config因为它不进入睡眠无需 RTC GPIO 能力而 wakee 板使用的是driver/rtc_io.h的rtc_gpio_*API。两个用例的 tag 同样带有test_envgeneric_multi_devicepytest 会依据用例名中的idle high/wake low片段区分两者。pytest 自动化完整的唤醒时序编排整个双板时序由 pytest_lp_core_gpio_wakeup.py 编排其关键流程与 README 描述严格对应从 Unity 菜单中筛选出 1 个 multi_stage 用例wakee和 2 个 normal 用例waker 的idle high与wake low并校验 wakee 用例确实包含 2 个子阶段对两块板分别执行硬复位hard_reset保证从干净状态开始先在 waker 板上运行idle high用例把共享 GPIO 拉高在 wakee 板上运行 stage 0入睡前阶段并等待它打印Waiting for signal: [gpio idle high]!信号行——该信号由 HP 侧unity_wait_for_signal(GPIO_IDLE_HIGH_SIGNAL)发出表示 wakee 已确认 GPIO 处于空闲高电平虚假唤醒检测用极短的NO_EARLY_WAKE_TIMEOUT 2.0秒探测 wakee 是否提前回到 Unity 菜单。如果探测到了直接pytest.fail(Wakee rebooted before the waker drove the GPIO falling edge)——说明在下降沿到来之前就发生了唤醒判定为虚假唤醒若 2 秒内无响应超时则视为通过说明 wakee 稳定停留在深睡眠中在 waker 板上运行wake low用例把 GPIO 拉低形成下降沿等待 wakee 唤醒并回到 Unity 菜单_get_ready(TEST_TIMEOUT)120 秒超时然后运行 stage 1唤醒后验证阶段并检查 Unity 断言输出。该脚本通过pytest.mark.parametrize(count, [2], indirectTrue)声明需要 2 个 DUT并通过pytest.mark.generic_multi_device标记测试类型本地运行时即可用-m generic_multi_device匹配。本地运行从编译到双板联测按照 README 提供的方式在本地复现该测试需要按顺序执行以下命令cd components/ulp/test_apps/lp_core/lp_core_gpio_wakeup_tests idf.py set-target esp32p4 idf.py build pytest --target esp32p4 -m generic_multi_device几点实操提示目标选择esp32p4可替换为 README 支持矩阵中的esp32c5或esp32c6示例中以 ESP32-P4 演示构建依赖配置测试应用默认通过 sdkconfig.defaults 启用 LP Core 相关配置CONFIG_ULP_COPROC_ENABLEDy、CONFIG_ULP_COPROC_TYPE_LP_COREy并预留 12000 字节的 LP 核内存CONFIG_ULP_COPROC_RESERVE_MEM12000同时关闭了任务看门狗CONFIG_ESP_TASK_WDT_INITn避免深睡眠流程中看门狗干扰。CI 环境下的配置在 sdkconfig.ci.defaults 中补充串口连接generic_multi_device模式要求 pytest 能同时访问两块板的串口通常通过 USB 转串口芯片连接到 PC并在测试框架中正确配置两个 DUT 的串口设备换引脚若 GPIO2 不适用于你的硬件例如已被占用或不可用可通过menuconfig修改TEST_LP_GPIO_WAKEUP_PIN但必须确保该引脚在 wakee 板上是 RTC GPIO且两板接线同步更换。验证价值与延伸参考从工程角度看这个测试应用的价值不仅在于“功能能跑通”更在于它把低功耗唤醒场景中最容易踩坑的两个问题纳入了自动化回归虚假唤醒通过“空闲高电平保持 2 秒提前唤醒探测”的组合确保 GPIO 上拉配置、中断使能时机、LP 程序加载顺序都正确不会因电平抖动或配置时序问题在下降沿到来前就误唤醒唤醒原因链路一致性HP 侧断言ESP_SLEEP_WAKEUP_ULPLP 侧记录LP_CORE_LL_WAKEUP_SOURCE_LP_IO两层唤醒原因必须同时正确保证“谁唤醒了谁”在软件语义上是自洽的。如果你要基于此模式开发自己的低功耗唤醒产品可以直接复用这里的三块资产LP Core 侧唤醒程序的四行骨架记录原因 → 唤醒 HP → 清中断、HP 侧rtc_gpio_*esp_sleep_enable_ulp_wakeup的入睡前配置序列以及 pytest 中“先拉高、防早醒、再拉低”的双板时序编排。更深层的 LP Core 编程接口可继续阅读 ulp_lp_core_utils.h 与 ulp_lp_core_gpio.h而唤醒源判定与寄存器操作的底层实现在 lp_core_utils.c 与 hal 层lp_core_ll头文件中。【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考