在发送大数据时,发现实际发送长度不对,数据没有发送完全。
发送逻辑为:
发送长度大于MTU时分包发送,第一次只发送MTU长度,
待发送完成后接着发送剩余数据,每次最大发送MTU长度
以下为实现:
1. 封装发送函数
发送长度不能超过MTU值
void myBleNusDataSend(uint8_t *pDat, uint32_t dataLength){
uint16_t length = 0;
uint32_t err_code;
do{
length = (uint16_t)dataLength;
err_code = ble_nus_data_send(&m_nus, pDat, &length, m_conn_handle); //SDK库函数
if ((err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_NOT_FOUND))
{
APP_ERROR_CHECK(err_code);
}
} while (err_code == NRF_ERROR_RESOURCES);
}
2. 大数据发送函数
如果数据长度超过MTU,则只发送MTU长度数据
#define BLE_NUS_MAX_DATA_LEN (244) // MTU值
static int gSendDataLen = 0; // 记录总共需要发送的数据长度
static int gSendDataCurrentLen = 0; // 当前已发送的数据长度
static uint8_t *gpData = 0; // 待发送数据起始位置
void bleNusDataSend(uint8_t *pDat, uint32_t dataLength){
uint16_t length = 0;
if(dataLength > BLE_NUS_MAX_DATA_LEN){
// 超过MTU长度的数据发送
length = BLE_NUS_MAX_DATA_LEN;
gSendDataLen = dataLength;
gSendDataCurrentLen = length;
gpData = pDat;
myBleNusDataSend(pDat,length);
while(gSendDataLen != 0){// 等待发送完毕
}
}else{
// 未超过MTU长度的数据直接一次性发送完毕
length = dataLength;
gSendDataLen = 0;
gSendDataCurrentLen = 0;
gpData = 0;
myBleNusDataSend(pDat,length);
}
}
3. 剩余数据发送
static void nus_data_handler(ble_nus_evt_t * p_evt)
{
if (p_evt->type == BLE_NUS_EVT_RX_DATA)
{
// 接收到数据
}
else if(p_evt->type == BLE_NUS_EVT_TX_RDY){
uint32_t tmpLen = 0;
if(gSendDataLen > 0){
tmpLen = (gSendDataLen - gSendDataCurrentLen);
tmpLen = (tmpLen > gBleSendImgSubpackageLen)?(gBleSendImgSubpackageLen):(tmpLen);
myBleNusDataSend((uint8_t *)&gpData[gSendDataCurrentLen], tmpLen);
gSendDataCurrentLen += tmpLen;
if(gSendDataLen <= gSendDataCurrentLen){
gSendDataLen = 0;
gSendDataCurrentLen = 0;
gpData = 0;
}
}
}
}
4. 错误原因及解决方法
原因:每次发送数据太长,数据发送不完整的原因是使用了全局中间变量,中间变量频率更改及读取时未被更新
解决:将全局变量加上volatile关键词,强制编译器不优化,每次更新全局变量
volatile
static int gSendDataLen = 0; // 记录总共需要发送的数据长度
volatile
static int gSendDataCurrentLen = 0; // 当前已发送的数据长度
volatile
static uint8_t *gpData = 0; // 待发送数据起始位置
版权声明:本文为webuildthings原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。