在实际应用中,当应用层发数据的速度比蓝牙连接交互的实际节奏要快时, 应用层发送的数据,会在先在消息FIFO中缓存。 然后依次发出。 当FIFO的发出的速度比进来的数据慢的时候,消息占用的内存会越来越多,一段时间后,会发生rw_ke_malloc无法申请到内存而发生soft fault而卡死情况。 为了处理这类问题,应用层应用做个软件流控,控制在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. |