From 026d6d5da73596a17651d56f1e19d7818a0acb39 Mon Sep 17 00:00:00 2001 From: Wuchuyuan <1917507415@qq.com> Date: Thu, 27 Aug 2026 20:19:57 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=BC=80=E6=9C=BA=E6=8C=89=E6=BB=A1?= =?UTF-8?q?=205s=20=E7=BB=BF=E7=81=AF=E5=85=88=E5=88=87=E9=85=8D=E5=AF=B9?= =?UTF-8?q?=E5=BF=AB=E9=97=AA=E6=8F=90=E7=A4=BA=EF=BC=8C=E6=9D=BE=E6=89=8B?= =?UTF-8?q?=E6=89=8D=E6=B8=85=E7=BB=91=E5=AE=9A=E5=B9=B6=E8=BF=9B=E9=85=8D?= =?UTF-8?q?=E7=BD=91=EF=BC=8C=E7=BB=A7=E7=BB=AD=E6=8C=89=E5=88=B0=2012s=20?= =?UTF-8?q?=E4=BB=8D=E5=8F=AF=E6=94=B9=E9=81=93=20OTA=202=E3=80=81app=5Fle?= =?UTF-8?q?d=5Finit=20=E6=8F=90=E5=89=8D=E5=88=B0=E6=8C=89=E9=94=AE?= =?UTF-8?q?=E5=88=A4=E5=AE=9A=E5=89=8D=EF=BC=8C3s=20=E5=B8=B8=E4=BA=AE=20/?= =?UTF-8?q?=205s=20=E5=BF=AB=E9=97=AA=20/=20=E6=8B=92=E7=BB=9D=E5=BC=80?= =?UTF-8?q?=E6=9C=BA=E4=BD=8E=E7=94=B5=E9=97=AA=E7=BB=9F=E4=B8=80=E8=B5=B0?= =?UTF-8?q?=E7=81=AF=E6=95=88=E4=BA=8B=E4=BB=B6=E8=A1=A8=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E5=BC=80=E6=9C=BA=E9=98=B6=E6=AE=B5=E6=89=8B=E6=90=93?= =?UTF-8?q?=20GPIO=20=E9=97=AA=E7=83=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/usr_app/app_boot.c | 55 ++++++++++++++++++++------------- apps/usr_app/app_boot.h | 13 ++++---- apps/usr_app/led.h | 5 ++- apps/usr_app/led_manager.c | 33 ++++++++++++++++++-- apps/usr_jb_proto/usr_jb_main.c | 20 +++++++----- 5 files changed, 89 insertions(+), 37 deletions(-) diff --git a/apps/usr_app/app_boot.c b/apps/usr_app/app_boot.c index bb78a49..b6d8cf4 100644 --- a/apps/usr_app/app_boot.c +++ b/apps/usr_app/app_boot.c @@ -2,11 +2,19 @@ * @file app_boot.c * @brief 深睡唤醒 / 上电按键判定实现 * @author cyWu <1917507415@qq.com> - * @date 2026.08.26 - * @version V1.1.0 + * @date 2026.08.27 + * @version V1.4.0 * @history * - V1.0.0, 2026.08.25, cyWu, 首次发布,实现深睡唤醒按键判定(3s 开机 / 5s 配对) * - V1.1.0, 2026.08.26, cyWu, 新增 12s 长按进 OTA、开机前低电量拦截 + * - V1.2.0, 2026.08.27, cyWu, 按满 5s 绿灯即按配对节奏快闪,松手才真正提交配网 + * - V1.3.0, 2026.08.27, cyWu, 3s/5s 提示灯改直接复用 LED 事件库 + * (LED_EVENT_STANDBY/LED_EVENT_PAIRING), + * 不再手写一份闪烁定时逻辑 + * - V1.4.0, 2026.08.27, cyWu, LED 事件库初始化提前到 usr_jb_init(调用本文件 + * 前完成),本文件不再自己调 user_led_init; + * 拒绝开机低电闪也改用新增的 LED_EVENT_BOOT_REJECT + * 事件,去掉手写的闪烁计次循环 ******************************************************************************/ #include "app_boot.h" @@ -15,6 +23,7 @@ #include "board_pin.h" #include "app_main.h" #include "usr_le_api.h" +#include "led_manager.h" #include "asm/power/power_api.h" #include "asm/power/power_reset.h" @@ -62,18 +71,17 @@ static void boot_sleep(void) } /** - * @brief 拒绝开机前的低电提示:红灯闪烁 BOARD_BOOT_LOWBAT_BLINK_N 下 + * @brief 拒绝开机前的低电提示:红灯闪 BOARD_BOOT_LOWBAT_BLINK_N 下 + * @note 直接挂 LED_EVENT_BOOT_REJECT,闪烁节奏/次数由 led_manager 的事件表 + * 统一管理,这里只管等它闪完(事件闪完会自己删掉) * @return 无 */ static void boot_blink_low_battery(void) { - uint8_t i; - - for (i = 0; i < BOARD_BOOT_LOWBAT_BLINK_N; i++) { - bsp_led_red_set(1); - boot_delay_ms(BOARD_BOOT_LOWBAT_ON_MS); - bsp_led_red_set(0); - boot_delay_ms(BOARD_BOOT_LOWBAT_OFF_MS); + LED_EventAdd(LED_EVENT_BOOT_REJECT); + while (LED_IsEventExist(LED_EVENT_BOOT_REJECT)) { + clr_wdt(); + user_led_handle(); } } @@ -134,15 +142,19 @@ static uint8_t boot_skip_key_wait(void) /** * @brief 等待并判定开机按键 * @note 配对(5s)不再一到点就立即提交:需要继续按住观察是否会按到 12s - * 触发 OTA,真正的配对提交放在松手那一刻做,行为上仍是“按满 5s - * 再松手即进配对”,只是多给了继续按到 12s 改道 OTA 的机会。 + * 触发 OTA,真正的配对提交放在松手那一刻做。按满 5s 绿灯先切到配对 + * 快闪提示,行为上仍是“按满 5s 再松手即进配对”,只是多给了继续按到 + * 12s 改道 OTA 的机会。 + * 3s 常亮 / 5s 快闪直接复用 led_manager 的 LED_EVENT_STANDBY / + * LED_EVENT_PAIRING 事件(和正常运行时配对灯效完全一致的节奏), + * 不再手写一份闪烁定时。LED 事件库由调用方(usr_jb_init)在本函数 + * 之前完成初始化,这里直接假定可用,跟 bsp_hw_init() 一个道理。 * @return 无(深睡分支不返回) */ void app_boot_wait_key(void) { uint32_t t0; uint32_t elapsed; - uint8_t green_on = 0; uint8_t pair_armed = 0; usr_var.usr_goto_pair = 0; @@ -165,7 +177,6 @@ void app_boot_wait_key(void) } t0 = timer_get_ms(); - bsp_led_all_off(); log_info("boot key hold, wait 3s on / 5s pair / 12s ota\n"); while (bsp_key_is_pressed()) { @@ -179,19 +190,21 @@ void app_boot_wait_key(void) return; } - /* 5s 只武装配对,真正提交放到松手那一刻,给继续按到 12s 改道 OTA 的机会 */ + /* 5s 只武装配对并切到快闪,真正提交放到松手那一刻,给继续按到 12s 改道 OTA 的机会 */ if (!pair_armed && (elapsed >= BOARD_KEY_PAIR_MS)) { pair_armed = 1; - log_info("boot hold %ums, pair armed (release now for pair, " + LED_EventDelete(LED_EVENT_STANDBY); + LED_EventAdd(LED_EVENT_PAIRING); + log_info("boot hold %ums, pair hint blink (release now for pair, " "keep holding to %ums for ota)\n", (unsigned)elapsed, (unsigned)BOARD_KEY_OTA_MS); - } - - if (!green_on && (elapsed >= BOARD_KEY_POWER_MS)) { - green_on = 1; - bsp_led_green_set(1); + } else if (!pair_armed && !LED_IsEventExist(LED_EVENT_STANDBY) + && (elapsed >= BOARD_KEY_POWER_MS)) { + LED_EventAdd(LED_EVENT_STANDBY); log_info("boot hold 3s, will power on\n"); } + + user_led_handle(); /* 按事件表当前状态刷新一次灯,闪烁节奏由事件配置自己算 */ } elapsed = timer_get_ms() - t0; diff --git a/apps/usr_app/app_boot.h b/apps/usr_app/app_boot.h index 099bb21..2f07164 100644 --- a/apps/usr_app/app_boot.h +++ b/apps/usr_app/app_boot.h @@ -3,13 +3,14 @@ * @brief 深睡唤醒 / 上电按键判定:3s 开机,5s 配对,12s OTA,不足 3s 松手再睡; * 开机前电量低于约 5% 且未充电时拒绝开机 * @author cyWu <1917507415@qq.com> - * @date 2026.08.26 - * @version V1.1.0 + * @date 2026.08.27 + * @version V1.2.0 * @history * - V1.0.0, 2026.08.25, cyWu, 首次发布,实现深睡唤醒按键判定(3s 开机 / 5s 配对) * - V1.1.0, 2026.08.26, cyWu, 新增 12s 长按进 OTA;新增开机前低电量 * (BOARD_VBAT_SHUTDOWN_MV)拦截,仅闪 5 下红灯 * 提示后继续深睡,不接受非充电状态下的开机 + * - V1.2.0, 2026.08.27, cyWu, 按满 5s 绿灯即快闪提示,松手才真正提交配网 * * @note 必须在 BLE 协议栈起来、1ms 定时器启动之前调用。杰理 jiffies 此时 * 往往 10ms 才跳一次,所以内部一律用 timer_get_ms 直接量时间, @@ -21,10 +22,10 @@ /** * @brief 等待并判定开机按键:不足 3s 松手、或全程未按键,直接原地深睡(不返回); - * 满 3s 视为正常开机;松手时已过 5s 视为开机并进入配对(内部会调用 - * app_pair_start);持续按满 12s 直接开机并进入 OTA(调用 - * usr_app_ota_init)。若未充电且电量低于约 5%,则闪 5 下红灯后 - * 继续深睡,拒绝开机。 + * 满 3s 视为正常开机(绿灯常亮);按满 5s 绿灯改快闪提示“松手即配网”, + * 真正清绑定 / 开绑定广播仍等松手(内部调用 app_pair_start);持续按满 + * 12s 直接开机并进入 OTA(调用 usr_app_ota_init)。若未充电且电量低于 + * 约 5%,则闪 5 下红灯后继续深睡,拒绝开机。 * @return 无(深睡分支通过 while(1) 喂狗不返回;其余情况正常返回) */ void app_boot_wait_key(void); diff --git a/apps/usr_app/led.h b/apps/usr_app/led.h index 86c1d09..6c914bf 100644 --- a/apps/usr_app/led.h +++ b/apps/usr_app/led.h @@ -3,9 +3,11 @@ * @brief LED 事件框架:按通道掩码独立开关,红绿可同时亮 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 - * @version V1.0.0 + * @version V1.1.0 * @history * - V1.0.0, 2026.08.25, cyWu, 首次发布,实现按通道掩码独立开关的 LED 事件框架 + * - V1.1.0, 2026.08.27, cyWu, 新增 LED_EVENT_BOOT_REJECT(拒绝开机低电闪), + * 与运行时 LED_EVENT_EMPTY 参数解耦,各自独立可调 ******************************************************************************/ #ifndef __LED_H__ @@ -53,6 +55,7 @@ typedef enum { LED_EVENT_PAIR_FAIL, /**< 配对失败红绿交替 */ LED_EVENT_OTA, /**< OTA:红绿交替闪,直到升级结束/复位 */ LED_EVENT_EMPTY, /**< 电量 5% 关机:关绿灯,红灯闪 5 下 */ + LED_EVENT_BOOT_REJECT, /**< 拒绝开机:电量过低,红灯闪 N 下后继续深睡 */ LED_EVENT_MAX } LED_Event_t; diff --git a/apps/usr_app/led_manager.c b/apps/usr_app/led_manager.c index cc3c44c..14b8db4 100644 --- a/apps/usr_app/led_manager.c +++ b/apps/usr_app/led_manager.c @@ -2,10 +2,12 @@ * @file led_manager.c * @brief CBC2 灯事件:充电红与待机绿走不同通道,可同时亮 * @author cyWu <1917507415@qq.com> - * @date 2026.08.25 - * @version V1.0.0 + * @date 2026.08.27 + * @version V1.1.0 * @history * - V1.0.0, 2026.08.25, cyWu, 首次发布,实现红绿独立通道灯事件表 + * - V1.1.0, 2026.08.27, cyWu, 新增 LED_EVENT_BOOT_REJECT:拒绝开机低电闪, + * 供 app_boot 在按键判定阶段直接复用事件库 ******************************************************************************/ #include "led_manager.h" @@ -21,6 +23,7 @@ static uint8_t led_pair_ok_handler(LED_Config_t *led_config); static uint8_t led_pair_fail_handler(LED_Config_t *led_config); static uint8_t led_ota_handler(LED_Config_t *led_config); static uint8_t led_empty_handler(LED_Config_t *led_config); +static uint8_t led_boot_reject_handler(LED_Config_t *led_config); /** * @brief 只改掩码里的通道,其它灯保持原样 @@ -139,6 +142,20 @@ static uint8_t led_empty_handler(LED_Config_t *led_config) return 1; } +/** + * @brief 拒绝开机低电闪:闪完 N 下后删事件,随后调用方直接回深睡 + * @param led_config 配置 + * @return 1=还在闪,0=闪完已删事件 + */ +static uint8_t led_boot_reject_handler(LED_Config_t *led_config) +{ + if (LED_Update(led_config) == 0) { + LED_EventDelete(LED_EVENT_BOOT_REJECT); + return 0; + } + return 1; +} + /** * @brief 注册回调并装载 CBC2 事件表(GPIO 已在 bsp_hw_init) * @return 无 @@ -259,6 +276,18 @@ void user_led_init(void) .config.runNum = BOARD_LED_EMPTY_BLINK_N, .ledEventHandler = led_empty_handler, }, + [LED_EVENT_BOOT_REJECT] = { + /* 拒绝开机:电量过低,红灯闪 N 下,参数与运行时 EMPTY 独立解耦 */ + .event = LED_EVENT_BOOT_REJECT, + .priority = PRIORITY_4, + .config.ledMask = LED_CHANNEL(LED_CH_RED), + .config.state = LED_BLINKING, + .config.blinkParams.orDer = 0, /* 先亮后灭 */ + .config.blinkParams.onTime = BOARD_BOOT_LOWBAT_ON_MS, + .config.blinkParams.offTime = BOARD_BOOT_LOWBAT_OFF_MS, + .config.runNum = BOARD_BOOT_LOWBAT_BLINK_N, + .ledEventHandler = led_boot_reject_handler, + }, }; LED_SetStateInit(set_led_multi); diff --git a/apps/usr_jb_proto/usr_jb_main.c b/apps/usr_jb_proto/usr_jb_main.c index f1eb888..b15c459 100644 --- a/apps/usr_jb_proto/usr_jb_main.c +++ b/apps/usr_jb_proto/usr_jb_main.c @@ -2,8 +2,8 @@ * @file usr_jb_main.c * @brief CBC2 业务组合根:只做“先后调用谁、谁通知谁”,不含具体业务算法 * @author cyWu <1917507415@qq.com> - * @date 2026.08.25 - * @version V2.1.0 + * @date 2026.08.27 + * @version V2.2.0 * @history * - V1.0.0, 2026.08.21, cyWu, 首次发布 * - V1.1.0, 2026.08.24, cyWu, 收口未接线模块;DP2 仅第 1 字节点动 1s @@ -18,6 +18,9 @@ * 换向死区判定改用阈值检查而非精确计时, * 取消专门的 1ms 高频档,全系统统一 20ms 节拍, * 只保留"能不能休眠"这一个维度 + * - V2.2.0, 2026.08.27, cyWu, app_led_init() 提前到 app_boot_wait_key() 之前, + * 开机 3s/5s/拒绝开机低电闪直接用灯效事件表, + * 不用再各自摸裸 GPIO 手搓一份闪烁定时 * * @note 协议生成文件 jb_product.c 不要填业务。APP 下行写 gDevData。 * usr_timer_loop 由 BLE 回调,勿再注册第二份。 @@ -256,9 +259,12 @@ static void usr_log_boot_version(void) /** * @brief 业务初始化(在 BLE 栈起来之前由 app_main 调用) * @note 内部会等按键 3s/5s;不足 3s 直接深睡,不会启动业务定时器。 - * 按键判定只摸 bsp_hw 的裸 GPIO,不经过协议栈/灯效表/电机状态机, - * 所以只有 bsp_hw_init() 需要排在它前面——一旦判定要睡回去, - * boot_sleep() 原地喂狗不再返回,后面这些初始化不会被浪费。 + * 按键判定只摸 bsp_hw 的裸 GPIO 和 led_manager 的事件表(3s 常亮 / + * 5s 配对快闪 / 拒绝开机低电闪都要用灯),不经过协议栈/电机状态机, + * 所以 app_led_init() 要排在它前面(跟 bsp_hw_init() 一样)——一旦 + * 判定要睡回去,boot_sleep() 原地喂狗不再返回,后面这些初始化不会 + * 被浪费。app_led_init() 内部有已初始化判断,这里提前调不会导致 + * 后面重复初始化出问题。 * @return 无 */ void usr_jb_init(void) @@ -266,14 +272,14 @@ void usr_jb_init(void) usr_log_boot_version(); /* UART 已在 app_main 起来,按键判定前就能看到版本 */ bsp_hw_init(); + app_led_init(); /* 提前到按键判定之前:3s/5s/拒绝开机低电闪都要直接用灯效事件表 */ app_boot_wait_key(); /* 深睡分支不会返回;返回即代表确定要开机 */ jbInit(); userInit(); - app_led_init(); if (usr_var.usr_goto_updata) { - /* 开机 12s 已进 OTA:灯表刚起来,立刻挂红绿交替 */ + /* 开机 12s 已进 OTA:立刻挂红绿交替 */ app_led_request_ota(); } app_mode_init();