前言
泰凌微TLSR825X是支持BLE5.0的,SDK包含了data length extension数据包扩展功能,数据最大长度251字节,可以提高大数据通信效率。
本章主要讲解下长包的通信交互与配置,深入可参考泰凌微开发手册3.2.8 Data Length Extension
章节
数据包结构
- 在蓝牙规范Core4.2之后,将PDU定义到最大到257字节
代码实例
可以参考例程feature_slave_dle.c
,将长包的配置代码移植到8258_module工程中
修改缓存
收发改为长包的话需要更大的TX/RX FIFO size,在app.c中修改
// support RF RX/TX MAX data Length: 251byte
#define RX_FIFO_SIZE 288 //rx-24 max:251+24 = 275 16 align-> 288
#define RX_FIFO_NUM 8
#define TX_FIFO_SIZE 264 //tx-12 max:251+12 = 263 4 align-> 264
#define TX_FIFO_NUM 8
#define MTU_SIZE_SETTING 247
#define DLE_TX_SUPPORTED_DATA_LEN MAX_OCTETS_DATA_LEN_EXTENSION //264-12 = 252 > Tx max:251
配置蓝牙
- 在函数 void user_init_normal(void) 中增加MTU修改与注册回调
void user_init_normal(void)
{
//**省略代码
my_att_init(); //GATT initialization
//ATT initialization
blc_att_setRxMtuSize(MTU_SIZE_SETTING);//默认Rx MTU配置
//**省略代码
//注册GAP事件回调
blc_gap_registerHostEventHandler( app_host_event_callback );
blc_gap_setEventMask(GAP_EVT_MASK_ATT_EXCHANGE_MTU);//MTU传输单元回调
//ble event call back
bls_app_registerEventCallback (BLT_EV_FLAG_CONNECT, &task_connect); //连接回调
bls_app_registerEventCallback (BLT_EV_FLAG_TERMINATE, &task_terminate); //断开回调
bls_app_registerEventCallback (BLT_EV_FLAG_DATA_LENGTH_EXCHANGE, &task_dle_exchange);//长度交互回调
}
回调修改
_attribute_data_retention_ u32 connect_event_occurTick = 0; //1.5sec
_attribute_data_retention_ u32 mtuExchange_check_tick = 0;//2sec
_attribute_data_retention_ int dle_started_flg = 0; //长度请求标志
_attribute_data_retention_ int mtuExchange_started_flg = 0;//mtu请求标志
_attribute_data_retention_ u16 final_MTU_size = 23;//有效MTU长度记录
//连接事件
void task_connect (u8 e, u8 *p, int n)
{
printf("----- connected -----\n");
connect_event_occurTick = clock_time()|1; //启动计时
bls_l2cap_requestConnParamUpdate (8, 8, 19, 200); //interval=10ms latency=19 timeout=2s
bls_l2cap_setMinimalUpdateReqSendingTime_after_connCreate(1000);
//MTU size reset to default 23 bytes every new connection, it can be only updated by MTU size exchange procedure
final_MTU_size = 23;//默认23字节
}
//断开事件
void task_terminate (u8 e, u8 *p, int n)
{
printf("----- terminate rsn: 0x%x -----\n", *p);
//清空计时与标志
connect_event_occurTick = 0;
mtuExchange_check_tick = 0;
//MTU size exchange and data length exchange procedure must be executed on every new connection,
//so when connection terminate, relative flags must be cleared
dle_started_flg = 0;
mtuExchange_started_flg = 0;
//MTU size reset to default 23 bytes when connection terminated
final_MTU_size = 23;//回退到23字节
}
//长度交互回调
void task_dle_exchange (u8 e, u8 *p, int n)
{
ll_data_extension_t* dle_param = (ll_data_extension_t*)p;
printf("----- DLE exchange: -----\n");
printf("connEffectiveMaxRxOctets: %d\n", dle_param->connEffectiveMaxRxOctets);
printf("connEffectiveMaxTxOctets: %d\n", dle_param->connEffectiveMaxTxOctets);
printf("connMaxRxOctets: %d\n", dle_param->connMaxRxOctets);
printf("connMaxTxOctets: %d\n", dle_param->connMaxTxOctets);
printf("connRemoteMaxRxOctets: %d\n", dle_param->connRemoteMaxRxOctets);
printf("connRemoteMaxTxOctets: %d\n", dle_param->connRemoteMaxTxOctets);
dle_started_flg = 1;
}
//host事件回调
int app_host_event_callback (u32 h, u8 *para, int n)
{
u8 event = h & 0xFF;
switch(event)
{
case GAP_EVT_ATT_EXCHANGE_MTU:
{
gap_gatt_mtuSizeExchangeEvt_t *pEvt = (gap_gatt_mtuSizeExchangeEvt_t *)para;
printf("MTU Peer MTU(%d)/Effect ATT MTU(%d).\n", pEvt->peer_MTU, pEvt->effective_MTU);
final_MTU_size = pEvt->effective_MTU;//更新MTU size(取两者之间最小的MTU)
mtuExchange_started_flg = 1; //MTU交互标志,启动mtu交互
}
break;
default:
break;
}
return 0;
}
slave主动请求长度扩展
void feature_sdle_test_mainloop(void)
{
if(connect_event_occurTick && clock_time_exceed(connect_event_occurTick, 1500000)){ //建立连接1.5 S 后
connect_event_occurTick = 0;
mtuExchange_check_tick = clock_time() | 1;
if(!mtuExchange_started_flg){ //slave主动发起 master do not send MTU exchange request in time
blc_att_requestMtuSizeExchange(BLS_CONN_HANDLE, MTU_SIZE_SETTING); //请求最大MTU(L2CAP)
printf("After conn 1.5s, S send MTU size req to the Master.\n");
}
}
if(mtuExchange_check_tick && clock_time_exceed(mtuExchange_check_tick, 500000 )){ //建立连接2 S
mtuExchange_check_tick = 0;
if(!dle_started_flg){ //slave主动发起 master do not send data length request in time
printf("Master hasn't initiated the DLE yet, S send DLE req to the Master.\n");
blc_ll_exchangeDataLength(LL_LENGTH_REQ , DLE_TX_SUPPORTED_DATA_LEN);//请求长度,发送最大包长(Link layer)
}
}
}
例程流程讲解
在蓝牙连接成功后,slave判断主机Host是否主动发起长包的请求,1.5sec主机未发起,则从机主动发起MTU流程,2sec后发起长度变更流程;数据请求完成后即可发起长度数据通信