6621x 应用层Notify/Indicate发送流控示例

wen sir · 315次点击 · 2023-06-13

         在实际应用中,当应用层发数据的速度比蓝牙连接交互的实际节奏要快时, 应用层发送的数据,会在先在消息FIFO中缓存。

 然后依次发出。 

        当FIFO的发出的速度比进来的数据慢的时候,消息占用的内存会越来越多,一段时间后,会发生rw_ke_malloc无法申请到内存而发生soft fault而卡死情况。


image.png


为了处理这类问题,应用层应用做个软件流控,控制在FIFO中待发送数据的总个数。

6621Cx 设定Tx_Flow_Control_Cnt小于10 

6621Px 设定Tx_Flow_Control_Cnt小于20


         下面以6621CxB为例,设应用层以50ms 的间隔来定时发送数据,BLE实际以100ms间隔的速度上报数据。通过添加软流控,来避免内存耗尽而死机。


\examples\ble_app_simple_server\src\app_simple_server.c

volatile int Tx_Flow_Control_Cnt = 0; //应用层发次一次,加1。 CMP事件发出一次,减1。
static int simple_server_timeout_timer_handler(ke_msg_id_t const msgid,
        void const *param,
        ke_task_id_t const dest_id,
        ke_task_id_t const src_id)
{
    //log_debug("%s@%d\n", __func__, __LINE__);
    uint8_t ntf_data[] = "SIMPLE_SERVER_SEND_NTF_CMD";
    ke_timer_set(SIMPLE_SERVER_TIMEOUT_TIMER, TASK_APP, 5); //5x10ms
    if (Tx_Flow_Control_Cnt >= 20)                  //举例,大于等于20时,不再发送,直接返回,或者做其它操作。
    {
        log_debug(" _x[%d]", Tx_Flow_Control_Cnt);    // STOP Send data....
        return (KE_MSG_CONSUMED);                   // STOP Send data....
    }
    else
    {
        Tx_Flow_Control_Cnt++; //a new data to fifo
        log_debug(" T[%d]", Tx_Flow_Control_Cnt);
    }
    struct simple_server_send_ntf_cmd *cmd = KE_MSG_ALLOC_DYN(SIMPLE_SERVER_SEND_NTF_CMD,
            prf_get_task_from_id(TASK_ID_SIMPLE_SERVER),
            TASK_APP,
            simple_server_send_ntf_cmd,
            sizeof(ntf_data));
    cmd->conidx = app_simple_server_env.conidx;
    cmd->length = sizeof(ntf_data);
    memcpy(cmd->value, ntf_data, sizeof(ntf_data));
    // Send the message
    ke_msg_send(cmd);
    return (KE_MSG_CONSUMED);
}

......\simple_server\src\simple_server_task.c

KE_MSG_HANDLER_TAB(simple_server)
{
    {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t) simple_server_default_handler},
    {SIMPLE_SERVER_ENABLE_REQ, (ke_msg_func_t) simple_server_enable_req_handler},
    {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) gattc_att_info_req_ind_handler},
    {SIMPLE_SERVER_SEND_NTF_CMD, (ke_msg_func_t) simple_server_send_ntf_cmd_handler},
    {GATTC_WRITE_REQ_IND, (ke_msg_func_t) gattc_write_req_ind_handler},
    {GATTC_READ_REQ_IND, (ke_msg_func_t) gattc_read_req_ind_handler},
    {GATTC_CMP_EVT, (ke_msg_func_t) gattc_cmp_evt_handler},
};


.....\profiles\simple_server\src\simple_server_task.c

extern volatile int Tx_Flow_Control_Cnt; //cmp evt and operate if indicate or notify, -1
__STATIC int gattc_cmp_evt_handler(ke_msg_id_t const msgid,  struct gattc_cmp_evt const *param,
                                   ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
    switch (param->operation)
    {
    case GATTC_INDICATE:  //Indicate send ...
        Tx_Flow_Control_Cnt--;
        log_debug("I"); //Mark for Indicate
        log_debug(" Tx_Flow_Control_Levl= %d", Tx_Flow_Control_Cnt);
        break;
    case GATTC_NOTIFY:  // Notify Send...
        Tx_Flow_Control_Cnt--;
        log_debug("N"); //Mark for Noticy...
        log_debug(" Tx_Flow_Control_Level= %d", Tx_Flow_Control_Cnt);
        break;
    default:
        break;
    }
    return (KE_MSG_CONSUMED);
}



而蓝牙连接间隔 为 Interval=100ms, Latency=0,Timeout=2s 


运行Log如下

[21:01:11.763] T[1]表示应用层发送1次数据,当前FIFO中数据为1包数据未发

[21:01:12.063] T[6]I Tx_Flow_Control_Levl= 5   应用层写入一笔数据,FIFO中有5笔数据,Indicate发出一包数据后, 当前FIFO中有5包数据。

[21:01:22.364] _x[20]   表示跳过一次发送,当前FIFO中有20包数据,已经达到控制线。



[21:01:03.927]running 0

[21:01:06.939]Device type(1) conidx(0) connected, ADDR: E7 64 75 1D 4E 5A [6bytes]
[21:01:10.766]gattc_write_req_ind_handler handle:9(idx:3).
[21:01:11.763] T[1]  //T表示应用层发了一笔,FIFO中有增加1笔数据。
[21:01:11.813] T[2]
[21:01:11.863] T[3] I Tx_Flow_Control_Levl= 2
[21:01:11.913] T[3]
[21:01:11.964] T[4]
[21:01:12.013] T[5]
[21:01:12.063] T[6] I Tx_Flow_Control_Levl= 5
[21:01:12.113] T[6]
[21:01:12.162] T[7]
[21:01:12.213] T[8] I Tx_Flow_Control_Levl= 7
[21:01:12.264] T[8]
[21:01:12.313] T[9] I Tx_Flow_Control_Levl= 8
[21:01:12.363] T[9]
[21:01:12.413] T[10] I Tx_Flow_Control_Levl= 9
[21:01:12.463] T[10]
[21:01:12.514] T[11] I Tx_Flow_Control_Levl= 10
[21:01:12.564] T[11]
[21:01:12.613] T[12]
[21:01:12.664] T[13]
[21:01:12.713] T[14] I Tx_Flow_Control_Levl= 13
[21:01:12.763] T[14]
[21:01:12.813] T[15] I Tx_Flow_Control_Levl= 14
[21:01:12.864] T[15]
[21:01:12.913] T[16] I Tx_Flow_Control_Levl= 15
[21:01:12.964] T[16]
[21:01:13.013] T[17] I Tx_Flow_Control_Levl= 16
[21:01:13.063] T[17]
[21:01:13.114] T[18] I Tx_Flow_Control_Levl= 17
[21:01:13.163] T[18]
[21:01:13.213] T[19]
[21:01:13.264] T[20]
//以下为达到控制线,必须发送去一笔,才会放进来一笔
[21:01:13.312] _x[20]
[21:01:13.363] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:13.414] T[20]
[21:01:13.463] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:13.513] T[20]
[21:01:13.565] _x[20]
[21:01:13.613] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:13.663] T[20]
[21:01:13.713] _x[20]
[21:01:13.763] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:13.814] T[20]
[21:01:13.863] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:13.913] T[20]
[21:01:13.964] _x[20]
[21:01:15.013] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:15.063] T[20]
[21:01:15.112] _x[20]
[21:01:15.163] _x[20] I Tx_Flow_Control_Levl= 19
....
....
[21:01:20.563] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:20.613] T[20]
[21:01:20.662] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:20.713] T[20]
[21:01:20.764] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:20.814] T[20]
[21:01:20.862] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:20.914] T[20]
[21:01:20.963] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:21.013] T[20]
[21:01:21.064] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:21.114] T[20]
[21:01:21.163] _x[20] I Tx_Flow_Control_Levl= 19
.....
.....
[21:01:22.664] T[20]
[21:01:22.713] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:22.764] T[20]
[21:01:22.813] _x[20] I Tx_Flow_Control_Levl= 19
[21:01:22.863] T[20]gattc_write_req_ind_handler handle:9(idx:3).
//以下为已经停止塞数据,只发送FIFO缓冲中的数据
[21:01:22.965] I Tx_Flow_Control_Levl= 19
[21:01:23.067] I Tx_Flow_Control_Levl= 18
[21:01:23.167] I Tx_Flow_Control_Levl= 17
[21:01:23.266] I Tx_Flow_Control_Levl= 16
[21:01:23.365] I Tx_Flow_Control_Levl= 15
[21:01:23.467] I Tx_Flow_Control_Levl= 14
[21:01:23.565] I Tx_Flow_Control_Levl= 13
[21:01:23.716] I Tx_Flow_Control_Levl= 12
[21:01:23.816] I Tx_Flow_Control_Levl= 11
[21:01:23.916] I Tx_Flow_Control_Levl= 10
[21:01:24.067] I Tx_Flow_Control_Levl= 9
[21:01:24.166] I Tx_Flow_Control_Levl= 8
[21:01:24.265] I Tx_Flow_Control_Levl= 7
[21:01:24.366] I Tx_Flow_Control_Levl= 6
[21:01:24.467] I Tx_Flow_Control_Levl= 5
[21:01:24.566] I Tx_Flow_Control_Levl= 4
[21:01:24.716] I Tx_Flow_Control_Levl= 3
[21:01:24.816] I Tx_Flow_Control_Levl= 2
[21:01:24.915] I Tx_Flow_Control_Levl= 1
[21:01:25.016] I Tx_Flow_Control_Levl= 0
[21:51:21.351]Disconnected.

被收藏 1  ∙  0 赞  
加入收藏
点赞
0 回复  
善言善语 (您需要 登录 后才能回复 没有账号 ?)

请先登录网站