You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32WB BLE5通信循环发送数据丢失问题求助

STM32WB BLE5 循环发送通知丢包问题解决建议

问题根源

  1. 死循环阻塞系统:在P2PS_Send_Notification中使用while(1)死循环连续调用发送函数,直接阻塞UTIL_SEQ任务调度,导致BLE协议栈无法处理发送ACK、连接维护等核心事件,最终触发协议栈丢弃未处理的发送请求。
  2. 异步发送未等待完成:P2PS_STM_App_Update_Char是向BLE协议栈提交发送请求,而非同步完成发送。连续提交请求会造成队列溢出,协议栈直接丢弃后续请求,这是数据丢失、乱序的直接原因。
  3. 类型转换隐患:将int类型变量强转uint8_t*,在32位系统下实际发送的是int的低字节,当前数值巧合正常,但后续ADC多字节数据传输会出现错误。

解决方案

1. 改用事件驱动的分步发送逻辑

移除死循环,利用BLE发送完成回调+UTIL_SEQ任务实现有序发送,确保上一次通知发送完成后再发下一个:

// 全局标志:标记上一次通知是否发送完成
static uint8_t notification_ready = 1;
// 标记发送流程是否已启动
static uint8_t send_running = 0;

// 重写BLE通知完成的回调函数(需对应你工程中的回调接口)
void P2PS_STM_App_Notification_Complete(uint16_t conn_handle, uint16_t attr_handle)
{
    if (attr_handle == P2P_NOTIFY_CHAR_HANDLE) // 确认是目标特征的通知
    {
        notification_ready = 1;
        // 通知完成后,触发下一次发送任务
        UTIL_SEQ_SetTask(1 << CFG_TASK_SEND_BLE_DATA, CFG_SEQ_PRIO_0);
    }
}

void P2PS_Send_Notification(void)
{
    // 避免重复触发发送流程
    if (send_running) return;
    send_running = 1;

    // 重置发送索引
    group_idx = 0;
    data_idx = 0;

    // 启动第一次发送任务
    UTIL_SEQ_SetTask(1 << CFG_TASK_SEND_BLE_DATA, CFG_SEQ_PRIO_0);
}

// 全局索引:记录当前发送的组和数据位置
static uint8_t group_idx = 0;
static uint8_t data_idx = 0;
#define TOTAL_GROUPS 5 // 原代码中的i循环次数
#define PER_GROUP_DATA_CNT 4 // 每组4个数据:4,5,5,5

// 分步发送数据的任务函数
static void Send_Next_Data(void)
{
    uint8_t send_data;

    // 上一次发送未完成,直接退出
    if (!notification_ready) return;

    // 确定当前要发送的数据
    if (data_idx == 0)
    {
        send_data = 4;
    }
    else
    {
        send_data = 5;
    }

    // 提交发送请求,标记未完成
    notification_ready = 0;
    P2PS_STM_App_Update_Char(P2P_NOTIFY_CHAR_UUID, &send_data);

    // 更新发送索引
    data_idx++;
    if (data_idx >= PER_GROUP_DATA_CNT)
    {
        data_idx = 0;
        group_idx++;
        // 完成所有组后停止发送
        if (group_idx >= TOTAL_GROUPS)
        {
            group_idx = 0;
            send_running = 0;
            return;
        }
    }
}

// 在初始化中注册发送任务
void P2PS_APP_Init(void)
{
    UTIL_SEQ_RegTask(1 << CFG_TASK_SW1_BUTTON_PUSHED_ID, UTIL_SEQ_RFU, P2PS_Send_Notification);
    // 注册分步发送任务
    UTIL_SEQ_RegTask(1 << CFG_TASK_SEND_BLE_DATA, UTIL_SEQ_RFU, Send_Next_Data);
}

2. 修复数据类型问题

将发送数据的变量改为uint8_t类型,避免跨类型转换的潜在错误:

// 原代码的int改为uint8_t
uint8_t start_data = 4;
uint8_t local = 5;

3. 优化BLE连接参数(可选)

如果需要更高的发送频率,可调整连接间隔等参数,提升通信效率:

// 示例:设置连接间隔为10ms(单位:0.625ms,16*0.625=10ms)
uint16_t conn_interval_min = 16;
uint16_t conn_interval_max = 16;
uint16_t slave_latency = 0;
uint16_t supervision_timeout = 100; // 超时时间1s(100*10ms)
aci_gap_set_connection_parameters(conn_interval_min, conn_interval_max, slave_latency, supervision_timeout);

核心注意事项

  • 永远不要在UTIL_SEQ任务中写死循环,会阻塞系统调度,导致BLE协议栈无法处理关键事件。
  • BLE通知是异步操作,必须等待发送完成回调后再提交下一个请求,否则会出现丢包。
  • 按键触发仅作为发送流程的启动信号,而非直接执行发送循环。

内容的提问来源于stack exchange,提问作者dfsdf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:54:55