请问大佬,有没有关于zigbee sdk上直接使用af框架的说明,手册上写的实在是太简单了,完全起不起指导作用,目前我使用:
af_endpointRegister(CUSTOM_ENDPOINT, (af_simple_descriptor_t *)&taDesc, af_ta_rx_handler, NULL);
注册了一个接收的回调,af_ta_rx_handler,
当用af_dataSend(srcEp, pDstEpInfo, clusterId, asdulength, asdu, &apsCnt)来发送,
网关和收发接点循环收发的时候,发不了几个报文,就不动了,抓包看,应该是发了,接收方没收到。
这个芯片不是一般的难用,资料少的可怜。
No related topics |
采用官网Zigbee SDK,经常出现丢包现象,如何解决? |
telink SDK的堆怎么设置? |
通过Zigbee传一幅图片太慢 |
ZGC该怎么用? |
首先,内存释放问题是否排除?
其次,5000字节的数据空间你是如何定义的?可以将大小改成500,看是否还会出现中断现象。
SDK中默认LARGE_BUFFER的大小为1024-8,无法一次发送5000字节数据。
1. 可以确认,收发两端的内存均已释放,
void af_tl_rx_handler(void *arg)
{
TL_SCHEDULE_TASK(tl_epRxHandler, arg);
}
void tk_epRxHandler(void *arg)
{
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
switch(pApsdeInd->indInfo.cluster_id){
case ZCL_CLUSTER_TL:
tk_cmdHandler(arg);
break;
default:
break;
}
printf("\r\nrx over\r\n");
/* Must be free here. */
ev_buf_free((u8 *)arg);
}
另一端
void tk_rxHandler(void *arg)
{
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
u8 *pData = pApsdeInd->asdu;
switch(pApsdeInd->indInfo.cluster_id){
case ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ:
g_afTest_rcvReqCnt = 0;
afTest_testClearReqPrc(pApsdeInd);
break;
case ZCL_CLUSTER_TELINK_SDK_TEST_REQ:
zbhciAfDataRcvIndPush(arg);
g_afTest_rcvReqCnt++;
afTest_testReqPrc(pApsdeInd);
break;
case ZCL_CLUSTER_TK:
tk_cmdHandler(arg);
break;
case ZCL_CLUSTER_TELINK_SDK_TEST_RSP:
#if ZBHCI_EN
zbhciAfDataPerformanceResultPush();
#endif
break;
default:
break;
}
#if ZBHCI_EN
zbhciAfDataRcvIndPush((void *)pApsdeInd);
#endif
/* Must be free here. */
printf("release arg\r\n");
ev_buf_free((u8 *)arg);
}
2. 5000字节的数据定义,发送端如下,const unsigned char gImage_2in9[FRAME_BUF_SIZE] = { /* 0X00,0X01,0X80,0X00,0X28,0X01, */
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,......};
收端定义的是一个全局数组,UBYTE g_frame_buffer[FRAME_BUF_SIZE] = {0};,是显示器的显示一屏数据。我要实现的就是通过网关将一屏图像数据发送到客户端显示。
3. 代码基本都是基于demo的af收发方式改过来的!
@Bin
我想通过zigbee sdk的af框架,直接完成5000字节的数据传送,传了不几下就莫名其妙的中断了,这中间的协议层在搞什么鬼 , 简直让人抓狂。
5000字节的数据量话,需要做分包处理,你是应用层做的分包处理还是使用的协议栈自身的分帧功能?
从描述上看,应该是1)发送端消息队列溢出,或2)接收端内存未及时释放导致。
1)上层最好不要使用for(;;)循环调用AF发送接口,
2)检查rx_handler()函数处理后是否及时释放内存。
你好,我没有使用协议栈的分帧,我采用的是将5000个字节,每次将50字节通过af_datasend发送,基本都是endpoint向网关一次数据请求,一次数据应答的方式,但是中间总是会中断,中断的位置也没有规律,板子使用的是tlsr8258 usb dongle。
另外,我想问一下,协议栈也能自动分帧吗?可以通过af_datasend一次发5000个字节数据?
首先,内存释放问题是否排除?
其次,5000字节的数据空间你是如何定义的?可以将大小改成500,看是否还会出现中断现象。
SDK中默认LARGE_BUFFER的大小为1024-8,无法一次发送5000字节数据。
1. 可以确认,收发两端的内存均已释放,
void af_tl_rx_handler(void *arg)
{
TL_SCHEDULE_TASK(tl_epRxHandler, arg);
}
void tk_epRxHandler(void *arg)
{
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
switch(pApsdeInd->indInfo.cluster_id){
case ZCL_CLUSTER_TL:
tk_cmdHandler(arg);
break;
default:
break;
}
printf("\r\nrx over\r\n");
/* Must be free here. */
ev_buf_free((u8 *)arg);
}
另一端
void tk_rxHandler(void *arg)
{
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
u8 *pData = pApsdeInd->asdu;
switch(pApsdeInd->indInfo.cluster_id){
case ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ:
g_afTest_rcvReqCnt = 0;
afTest_testClearReqPrc(pApsdeInd);
break;
case ZCL_CLUSTER_TELINK_SDK_TEST_REQ:
zbhciAfDataRcvIndPush(arg);
g_afTest_rcvReqCnt++;
afTest_testReqPrc(pApsdeInd);
break;
case ZCL_CLUSTER_TK:
tk_cmdHandler(arg);
break;
case ZCL_CLUSTER_TELINK_SDK_TEST_RSP:
#if ZBHCI_EN
zbhciAfDataPerformanceResultPush();
#endif
break;
default:
break;
}
#if ZBHCI_EN
zbhciAfDataRcvIndPush((void *)pApsdeInd);
#endif
/* Must be free here. */
printf("release arg\r\n");
ev_buf_free((u8 *)arg);
}
2. 5000字节的数据定义,发送端如下,const unsigned char gImage_2in9[FRAME_BUF_SIZE] = { /* 0X00,0X01,0X80,0X00,0X28,0X01, */
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,......};
收端定义的是一个全局数组,UBYTE g_frame_buffer[FRAME_BUF_SIZE] = {0};,是显示器的显示一屏数据。我要实现的就是通过网关将一屏图像数据发送到客户端显示。
3. 代码基本都是基于demo的af收发方式改过来的!
@Bin
抓包出来,结果如图所示,始终未能抓到ep发送给gw的zcl报文,ep一直在发data request,这是什么?应用层,我什么都没干,也发这个!
示例代码如下
1、发送端
const u8 g_testImage[IMAGE_BUF_SIZE];
u16 g_sendLen = 0;
void afTest_txMsg(u16 shortAddr){
epInfo_t dstEp;
TL_SETSTRUCTCONTENT(dstEp, 0);
dstEp.dstEp = SAMPLE_TEST_ENDPOINT;
dstEp.profileId = HA_PROFILE_ID;
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
dstEp.dstAddr.shortAddr = shortAddr;
if(g_sendLen >= IMAGE_BUF_SIZE){ return; }
u8 dataLen = ((IMAGE_BUF_SIZE - g_sendLen) > 50) ? 50 : (IMAGE_BUF_SIZE - g_sendLen);
u8 *pBuf = (u8 *)ev_buf_allocate(dataLen);
if(pBuf){
memcpy(pBuf, &g_testImage[g_sendLen], dataLen);
g_sendLen += dataLen;
u8 apsCnt = 0;
af_dataSend(SAMPLE_TEST_ENDPOINT, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_REQ, dataLen, pBuf, &apsCnt);
ev_buf_free(pBuf);
}
}
void afTest_rx_handler(void *arg){
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
u16 clusterID = pApsdeInd->indInfo.cluster_id;
u16 dstAddr = pApsdeInd->indInfo.src_short_addr;
if(clusterID == ZCL_CLUSTER_TELINK_SDK_TEST_RSP){
//send next MSG
afTest_txMsg(dstAddr);
}
/* Must be free here. */
ev_buf_free((u8 *)arg);
}
2、接收端
void afTest_rx_handler(void *arg){
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
u16 clusterID = pApsdeInd->indInfo.cluster_id;
if(clusterID == ZCL_CLUSTER_TELINK_SDK_TEST_REQ){
//data process
g_rcvLen += pApsdeInd->asduLen;
printf("recLen = %d\n", g_rcvLen);
DEBUG_ARRAY(TRUE, pApsdeInd->asdu, pApsdeInd->asduLen);
//send response
epInfo_t dstEp;
TL_SETSTRUCTCONTENT(dstEp, 0);
dstEp.dstEp = pApsdeInd->indInfo.src_ep;
dstEp.profileId = pApsdeInd->indInfo.profile_id;
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr;
u8 status = SUCCESS;
u8 apsCnt = 0;
af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_RSP, 1, &status, &apsCnt);
}
/* Must be free here. */
ev_buf_free((u8 *)arg);
}
3、接收端打印结果
Bin,你好,感谢你解答,但是你给我的代码现象和我之前的现象并没有什么不一样,都是中间会断流,偶尔会成功,下面是打印的log信息,如果有必要,我可以把代码贴出来。
start init cmd send:
{
Ep Send data:
0x0 0x4 0x0 0x10 0x5 0x0 0x10 0xA 0xF4 0x1
the apsCnt = E1
}
start init cmd send:
{
Ep Send data:
0x0 0x5 0x0 0x10 0x5 0x0 0x10 0xA 0xF4 0x1
the apsCnt = E2
}
recLen = 50
*********************************
A5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
*********************************
recLen = 100
*********************************
示例代码中,发射端只有当收到ZCL_CLUSTER_TELINK_SDK_TEST_RSP应答后才会继续发送下一帧数据。
可以先确认一下是否是没收到ZCL_CLUSTER_TELINK_SDK_TEST_RSP应答而导致的断流,如果是的话,可以考虑加入重传。
@bin,你前面说的命令没有被响应应该是可以排除的,现在基本可以确定是无线信号受干扰或者协议栈的问题 , 如下图,现在测试出来的规律,大概就是中间只要连接受到干扰,协议栈重试4次,就结束了。
重试的时间间隔这个可以重新配置吗?
我实在是弄不懂,这已经是快贴在一起了,怎么会受干扰。 而且晚上大家都下班了,办公室没什么人,我测试比较OK。
发送端可以添加以下代码,使能APS重传。
这些参数设置在哪个资料里面有说明?能否提供一个靠谱的资料呢?