找回密码
 立即注册

微信扫码登录

查看: 9|回复: 0

[BLE SDK] 【Telink BLE SDK|功耗】应用层主动Suspend 休眠配置方法

[复制链接]

2

主题

79

回帖

279

积分

版主

积分
279
发表于 3 小时前 | 显示全部楼层 |阅读模式 来自 上海
Information
说明:   建议参照本版块置顶帖内容输入必要信息
芯片型号: TL系列
SDK及版本: 4048
一、前言:为什么要手动配置Suspend休眠?
Telink 原生BLE SDK没有BLE 任务时候不会自动进入休眠,需要用户管理休眠状态
这里分享一套实测可用的应用层Suspend休眠方案,通过六状态机管控 + BLE任务空闲校验机制,搭配GPIO引脚唤醒、定时自动唤醒双模式,实现闭环稳定的休眠唤醒逻辑。

二、方案核心设计思路
采用状态机分层管控 + BLE状态校验 + 休眠前置预处理 + 唤醒完整恢复的闭环

三、核心代码框架与变量说明
3.1 全局变量与状态枚举定义
自定义六段休眠状态机,所有状态变量、计时变量添加 _attribute_data_retention_ 保留属性,确保Suspend休眠过程中数据不丢失、状态不紊乱。
c
// 休眠计时变量,休眠状态保留数据
_attribute_data_retention_ u32 tickLoop_1 = 1;
_attribute_data_retention_ u32 AA_tickLoop_2 = 0;
// BLE状态、任务状态、休眠测试标志
u8 ble_sataus=0;
u8 ble_task_status=0;
u8 sleep_test=0;

/**
* @brief 休眠调试状态机枚举(核心六状态闭环)
*/
typedef enum
{
    DEBUG_RUNNING,          // 正常运行态:设备正常广播、任务运行
    DEBUG_SLEEP_PREPARE,    // 休眠准备态:关闭广播、配置唤醒源
    DEBUG_WAIT_BLE_IDLE,    // 中间态:循环等待BLE任务彻底空闲
    DEBUG_SUSPEND,          // 休眠态:进入Suspend低功耗模式
    DEBUG_WAKEUP,           // 唤醒态:执行射频、外设恢复
    DEBUG_IDLE_RESET        // 重置态:恢复初始状态,新一轮循环
} eDebugSleepState;

// 休眠状态机全局变量,休眠数据保留
_attribute_data_retention_ eDebugSleepState debug_sleep_state;
休眠逻辑挂载在SDK空闲主循环中执行,不抢占、不阻塞BLE核心任务,完全贴合SDK原生架构,兼容性好、移植简单。
c
/**
* @brief BLE主空闲循环,所有应用层逻辑、休眠逻辑入口
*/
int main_idle_loop(void)
{
    // 1. BLE SDK核心任务调度(必须优先执行)
    blc_sdk_main_loop();

    // 2. 调试日志输出
#if (TLKAPI_DEBUG_ENABLE)
    tlkapi_debug_handler();
#endif

    // 3. 电池检测、按键/按钮外设逻辑
#if (BATT_CHECK_ENABLE)
    if (battery_get_detect_enable() && clock_time_exceed(lowBattDet_tick, 500000)) {
        lowBattDet_tick = clock_time();
        user_battery_power_check(BAT_DEEP_THRESHOLD_MV);
    }
#endif
#if (UI_KEYBOARD_ENABLE)
    proc_keyboard(0, 0, 0);
#elif (UI_BUTTON_ENABLE)
    proc_button();
#endif

    // 4. 核心休眠状态机逻辑(下文详细解析)
    sleep_state_machine_process();

    // 5. SDK底层功耗管理兜底
    app_process_power_management();

    return 0; // SDK固定返回值,不可修改
}

/**
* @brief 主循环入口函数
*/
_attribute_no_inline_ void main_loop(void)
{
    main_idle_loop();
}

四、核心休眠状态机逻辑逐段解析
下面逐段拆解状态机流转逻辑,覆盖设备运行、休眠准备、BLE空闲检测、低功耗休眠、射频唤醒恢复、状态重置完整流程。
4.1 正常运行态(DEBUG_RUNNING
设备正常上电运行,每500ms打印一次设备状态,稳定运行10s后再进入休眠准备阶段,规避上电初期BLE状态不稳定导致的异常休眠问题。
c
case DEBUG_RUNNING:
{
    // 500ms周期打印运行状态
    if (tickLoop_1 && clock_time_exceed(tickLoop_1, 500*1000))
    {
        tickLoop_1 = clock_time() | 1;
        AA_tickLoop_2++;

        // 打印BLE当前状态与任务空闲状态
        tlkapi_printf(APP_JERRYLOG_EN, "[JERRY][LOOP] test_cnt=%d\r\n", AA_tickLoop_2);
        tlkapi_printf(APP_JERRYLOG_EN, "[JERRY][LOOP] ble_state=%d\r\n", ble_sataus);
        tlkapi_printf(APP_JERRYLOG_EN, "[JERRY][LOOP] ble_task_idle=%d\r\n", ble_task_status);

        // 稳定运行10s后切入休眠准备状态
        if(AA_tickLoop_2 > 20)
        {
            debug_sleep_state = DEBUG_SLEEP_PREPARE;
        }
    }
    break;
}
4.2 休眠准备态(DEBUG_SLEEP_PREPARE
休眠前置预处理,主动关闭BLE广播、配置GPIO上下拉和唤醒引脚,清除休眠干扰条件,保证后续可以正常进入低功耗。
c
case DEBUG_SLEEP_PREPARE:
{
    // 关闭BLE广播,避免广播持续运行导致休眠失败
    blc_ll_setAdvEnable(BLC_ADV_DISABLE);
    ble_sataus = blc_ll_getBleCurrentState();

    // 配置PE0为上拉,低电平触发唤醒
    gpio_set_up_down_res(GPIO_PE0, GPIO_PIN_PULLUP_1M);
    pm_set_gpio_wakeup(GPIO_PE0, WAKEUP_LEVEL_LOW, 1);

    // 切换状态:等待BLE任务完全空闲
    debug_sleep_state = DEBUG_WAIT_BLE_IDLE;
    break;
}
4.3 等待BLE空闲态(DEBUG_WAIT_BLE_IDLE
实测关键容错逻辑,循环轮询BLE任务运行状态,必须等待BLE任务完全空闲才会进入休眠
c
case DEBUG_WAIT_BLE_IDLE:
{
    ble_task_status = blc_ll_isBleTaskIdle();
    // BLE任务空闲,正式进入休眠模式
    if((ble_task_status == 1))
    {
        debug_sleep_state = DEBUG_SUSPEND;
    }
    break;
}
4.4 休眠态(DEBUG_SUSPEND
设备进入Suspend低功耗模式,配置双唤醒机制,支持PE0引脚低电平唤醒、15秒定时自动唤醒,适配按键唤醒、定时复位等常规场景。
c
case DEBUG_SUSPEND:
{
    // 进入Suspend休眠,双唤醒源配置
    cpu_sleep_wakeup(SUSPEND_MODE,
                       PM_WAKEUP_PAD|PM_WAKEUP_TIMER,
                       (clock_time() + 15*1000*SYSTEM_TIMER_TICK_1MS));

    // 休眠唤醒后切入唤醒处理状态
    debug_sleep_state = DEBUG_WAKEUP;
    break;
}
4.5 唤醒恢复态(DEBUG_WAKEUP
设备唤醒后,统一恢复射频底层、中断配置、发射功率,重新开启BLE广播,保证唤醒后广播、连接、数据通信功能正常,不会出现射频异常。
c
case DEBUG_WAKEUP:
{
    // 射频底层初始化恢复
    rf_drv_ble_init();
    rf_set_irq_mask(FLD_RF_IRQ_RX | FLD_RF_IRQ_TX
                    | FLD_RF_IRQ_CMD_DONE
                    | FLD_RF_IRQ_FIRST_TIMEOUT
                    | FLD_RF_IRQ_RX_TIMEOUT
                    | FLD_RF_IRQ_RX_CRC_2);

    // 射频参数与链路参数恢复
    ble_rf_fast_settle_recover();
    blt_ll_phy_param_reset();
    rf_set_power_level_index(RF_POWER_P0dBm);

    // 重新开启BLE广播
    blc_ll_setAdvEnable(BLC_ADV_ENABLE);

    // 切入状态重置流程
    debug_sleep_state = DEBUG_IDLE_RESET;
    break;
}
4.6 状态重置态(DEBUG_IDLE_RESET
单次休眠唤醒流程结束后,清空计数变量、重置状态机,设备恢复正常运行状态,形成完整闭环。默认分支做异常兜底,避免状态机卡死。
c
case DEBUG_IDLE_RESET:
{
    // 重置计时标记,复位状态机
    AA_tickLoop_2 = 0;
    tickLoop_1 = clock_time() | 1;
    debug_sleep_state = DEBUG_RUNNING;
    break;
}

// 异常兜底,防止状态卡死
default:
{
    debug_sleep_state = DEBUG_RUNNING;
    break;
}

五、关键移植与调试要点
1、变量保留属性必填:休眠相关状态、计数变量必须开启 _attribute_data_retention_,否则休眠后状态丢失,逻辑运行异常。
2、休眠前置校验不能省:必须关闭广播、等待BLE任务空闲,直接休眠会造成BLE时序错乱、整机功耗异常。
3、唤醒底层恢复必填:唤醒后必须复位射频与中断,否则会出现无广播、无法连接、数据丢包等问题。
4、参数可按需修改15s定时唤醒时长、PE0唤醒引脚、唤醒电平逻辑,均可根据需求自行调整。

六、日志打印配置(解决休眠打印丢失问题)
工程调试过程中,休眠唤醒阶段容易出现日志丢失、打印截断的问题。在配置头文件开启以下宏定义,开启实时打印与全模块日志输出,可完整抓取休眠状态机、BLE状态切换日志,方便问题排查。
c
// 调试串口与实时打印配置
#define TLKAPI_DEBUG_ENABLE  1
#define TLKAPI_DEBUG_CHANNEL TLKAPI_DEBUG_CHANNEL_GSUART
#define APP_REAL_TIME_PRINTF 1  // 开启实时打印,解决休眠日志丢失问题

// 全模块日志使能
#define APP_LOG_EN           1
#define APP_CONTR_EVT_LOG_EN 1  // 控制器事件日志
#define APP_HOST_EVT_LOG_EN  1  // 主机事件日志
#define APP_KEY_LOG_EN       1  // 按键日志
#define APP_BUTTON_LOG_EN    1  // 按钮日志
核心配置要点APP_REAL_TIME_PRINTF 1 是解决休眠日志丢失的关键,关闭日志缓存积压,休眠、唤醒全过程打印完整不缺失,可快速定位休眠失败、任务检测异常、唤醒故障等问题。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Telink forum ( 沪ICP备17008231号-1 )

GMT+8, 2026-8-20 18:34 , Processed in 0.094029 second(s), 25 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表