1、低电 3.7V 只闪红灯不再 1 分钟后关机;电量低于约 5% 自动关机,未充电开机先闪 5 下红灯再睡回,只能充电后才能开机

2、自动/手动互相切换都闪 2 下灯;APP 发停止后再发自动模式可正常启动,手动残留停止不再挡住自动
3、自动模式 1~6 单次最长跑 10 分钟后回待机;关机时长按 12 秒进 OTA,OTA 期间红绿交替闪
This commit is contained in:
2026-08-27 10:20:48 +08:00
parent 3d445ae5c5
commit fdb43011b7
28 changed files with 945 additions and 165 deletions
+29 -7
View File
@@ -10,7 +10,7 @@
* - V1.2.0, 2026.08.24, cyWu, 按键:深睡 3s 开机、5s 开机+配对;开机中 3s 深睡
* - V1.3.0, 2026.08.24, cyWu, DP200=空闲,01/02 转,03 停
* - V1.4.0, 2026.08.25, cyWu, 空闲改可休眠定时器,系统才能进 sleep
* - V1.5.0, 2026.08.25, cyWu, LED/按键改充电板事件库,红绿可同时亮
* - V1.5.0, 2026.08.25, cyWu, LED/按键改事件库,红绿可同时亮
* - V2.0.0, 2026.08.25, cyWu, 重构:电源/配对/开机/功能拆成独立模块,
* 本文件只剩初始化顺序、1ms 调度、模块间接线
* - V2.1.0, 2026.08.26, cyWu, 电机运转期间长期占用 1ms 硬件定时器中断,
@@ -24,7 +24,7 @@
* 具体业务逻辑请去对应模块找:
* app_power —— USB/充电/电量/深睡请求
* app_pair —— 配对会话计时
* app_boot —— 开机 3s/5s 按键判定
* app_boot —— 开机 3s/5s/12s 按键判定
* app_function —— DP0/DP1/DP2 与按键动作
* app_led —— 灯效
******************************************************************************/
@@ -179,7 +179,20 @@ static void usr_timer_rearm(UsrTickMode_t mode)
/**
* @brief 业务定时器:固定 USR_TIMER_IDLE_MS 一拍;忙时禁睡,空闲可睡
* @param priv 未使用
* @note 禁止在这里直接 sys_enter_soft_poweroff,一律走 app_power 的深睡钩子
* @note ⚠️ 本函数运行在硬件定时器时基上下文(usr_timer_add 的 SDK 说明:
* "扫描函数将在硬件定时器中时基到时候被调用"),不是普通任务线程。
* priority=1 能禁止休眠正是因为走的这条路——SDK 里能"禁睡"的定时器
* 只有这一种,没有"任务线程 + 禁睡"的组合可选。
* 代价是这里执行的每一行代码都会占用中断时间,跟 BLE 协议栈自己的
* 收发中断抢时序;这次的看门狗复位就是因为这条路径长期以 1kHz
* 触发。现在虽然降到了 20ms 一拍,但仍要守住底线:
* - 禁止阻塞等待(信号量/循环等 ACK 之类)
* - 禁止耗时操作(flash 擦写、大块 memcpy、长循环)
* 按键短按/长按走到的 usr_on_key_short/long、jbSendReqWithAck
* 目前都只是改几个标志位 + 入队发送,没有阻塞,符合这个要求;
* 以后往 user_key_handle / app_function_poll 这条链路上加新功能,
* 必须先确认不违反以上两条,否则会重新引入同一类复位问题。
* 另外,禁止在这里直接 sys_enter_soft_poweroff,一律走 app_power 的深睡钩子
* @return 无
*/
static void usr_timer_tick(void *priv)
@@ -196,7 +209,7 @@ static void usr_timer_tick(void *priv)
if (!app_power_poweroff_pending()) {
user_key_scan(dt);
user_key_handle();
user_key_handle(); /* 长按 3s 会在这里同步触发 app_power_request_poweroff() */
}
pwr_evt = app_power_tick_1ms(dt);
@@ -205,15 +218,20 @@ static void usr_timer_tick(void *priv)
app_function_poll();
app_function_tick_1ms(dt);
if (app_power_poweroff_pending()) {
/* 重新查询而非复用上面的判断:user_key_handle() 可能在本拍内刚请求关机,
* 要用最新状态决定这一拍还要不要播灯效,否则会多播一帧才熄灭。
* OTA 期间灯效优先:关机钩子也不要把红绿交替清掉。 */
if (app_led_is_ota()) {
app_led_run(dt, app_function_is_power_on());
} else if (app_power_poweroff_pending()) {
app_led_clear();
} else {
app_led_run(dt, app_function_is_power_on());
}
want = usr_timer_pick_mode();
want = usr_timer_pick_mode();//判断能不能休眠
if (want != s_sched.mode) {
usr_timer_rearm(want);
usr_timer_rearm(want);//切换业务定时器
}
}
@@ -234,6 +252,10 @@ void usr_jb_init(void)
jbInit();
userInit();
app_led_init();
if (usr_var.usr_goto_updata) {
/* 开机 12s 已进 OTA:灯表刚起来,立刻挂红绿交替 */
app_led_request_ota();
}
app_mode_init();
app_power_init();