测试系统为CC1101+stm32 MCU,一对一测试时,主机通过电脑串口收到指令后,向从机发送命令,从机收到指令后解析并返回响应,主机接收到从机响应后通过串口打印信息。电脑串口发送指令周期为250ms,持续运行2小时后测试系统正常(有丢包,但在正常范围内)。
增加到三组进行测试(每台设备都有唯一地址,每组两个设备通过通信协议中地址校验区分是否为同一组,以保证不会解析/响应其它设备命令),发现一般在20分钟内就会有一组设备出现异常,主从机都有可能。
程序配置为GDO0输出电平指示无线发送/接收状态,在测试异常情况下用万用表测量GDO0管脚电压,发现GDO0一直处于assert状态,那么程序就死在了查询GDO0状态的while(1)循环中,程序仿真发现是在发送时出现了异常。把其他正常通信设备关闭后,异常设备不能恢复正常通信。
多组测试情况下丢包率变高比较好理解,但按上述情况的话,好像硬件出了问题,导致死机。有相关经验大牛还请帮忙分析下!感谢~
Barbara Wu:
请问程序里面是不是有CCA, LBT等防冲突的机制?每一次接收、发送完成之后会转入什么状态?
感觉既然两个没有问题,三个有问题,更像是软件处理冲突导致的状态集变化没有处理好
chen li4:
回复 Barbara Wu:
感谢@WBJ 解答,现在有cca,平时处于接收状态,发送完成后也转为接收状态。发送时相关代码如下
CC1101SetIdle();//MUST BE IDLE MODE CC1101WriteCmd( CC1101_SFTX );
CC1101WriteMultiReg( CC1101_TXFIFO, txbuffer, size ); CC1101WriteCmd(CC1101_SIDLE); CC1101SetTRMode( TX_MODE ); if( (CC1101ReadStatus(CC1101_PKTSTATUS)&0x10) == 0 )//cca { while( CC_IRQ_READ() != 0 ); while( CC_IRQ_READ() == 0 ); }
CC1101SetIdle();//MUST BE IDLE MODE CC1101WriteCmd( CC1101_SFTX ); CC1101SetTRMode(RX_MODE);
现在出问题的测试系统为3组,共6个设备。
按照您说的,如果软件没有处理好冲突,会影响GDO0的输出状态吗?现在GDO0配置为0x06,什么情况下会一直处于assert状态?
Barbara Wu:
回复 chen li4:
assert应该是收到sync word的时候,
可以用一个接收机接smartRF studio抓包看一下当前的空中信号发送状态,
另外可以查一下如果收到错误的包的时候是否有做相应的flush的处理
chen li4:
回复 Barbara Wu:
@WBU 接收机得用官方的demo板是吗?如果买的话,国内比较快的正规渠道能说一下吗?
射频接收这一块我刚看了下 ,应该是做了异常处理。以下是代码,劳烦给看下,感谢~
INT8U CC1101RecPacket( INT8U *rxBuffer ){ INT8U status[2]; INT8U pktLen; INT16U x , j = 0;
if ( CC1101GetRXCnt( ) != 0 ) { pktLen = CC1101ReadReg(CC1101_RXFIFO); // Read length byte if( ( CC1101ReadReg( CC1101_PKTCTRL1 ) & 0x03 ) != 0 ) { x = CC1101ReadReg(CC1101_RXFIFO); } if( pktLen == 0 ) { return 0; } else { pktLen –; } CC1101ReadMultiReg(CC1101_RXFIFO, rxBuffer, pktLen); // Pull data CC1101ReadMultiReg(CC1101_RXFIFO, status, 2); // Read status bytes
CC1101ClrRXBuff( );
if( status[1] & CRC_OK ) { return pktLen; } else { return 0; } } else { return 0; } // Error}
void CC1101ClrRXBuff( void ){ CC1101SetIdle();//MUST BE IDLE MODE CC1101WriteCmd( CC1101_SFRX );}
Barbara Wu:
回复 chen li4:
看代码似乎没有对异常情况做处理啊
参考如下代码实现:
// infinite loop
while(1)
{
// wait for packet received interrupt
if(packetSemaphore == ISR_ACTION_REQUIRED)
{
cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);
do
{
rxBytes = rxBytesVerify;
cc11xLSpiReadReg(CC110L_RXBYTES,&rxBytesVerify,1);
}
while(rxBytes != rxBytesVerify);
// Check that we have bytes in FIFO
if(rxBytes != 0) {
// Read MARCSTATE to check for RX FIFO error
cc11xLSpiReadReg(CC110L_MARCSTATE, &marcState, 1);
// Mask out MARCSTATE bits and check if we have a RX FIFO ERROR (0x11)
if((marcState & 0x1F) == RXFIFO_OVERFLOW) {
// Flush RX FIFO
trxSpiCmdStrobe(CC110L_SFRX);
} else {
cc11xLSpiReadRxFifo(rxBuffer,(rxBytes));
// check CRC ok (CRC_OK: bit7 in second status byte)
if(rxBuffer[rxBytes-1] & 0x80)
{
// toggle led
halLedToggle(LED1);
// update packet counter
packetCounter++;
}
}
}
// reset packet semaphore
packetSemaphore = ISR_IDLE;
// set radio back in RX
trxSpiCmdStrobe(CC110L_SRX);
}
}
Barbara Wu:
回复 Barbara Wu:
另外如果要RX接收端的话,可以用TI的Demo板或者可以连接smartrf studio的第三方板子做都可以。
TI的demo板可以从官方的网站上购买,有433 868不同频段的供选择,例如433的link如下:
http://www.ti.com/tool/cc1101dk433
chen li4:
回复 Barbara Wu:
@WBJ 感谢~ 调试时发现了另外一个小问题,向您请教下。清理信道评估代码 if( (CC1101ReadStatus(CC1101_PKTSTATUS)&0x10) == 0 ),在仿真调试时上述条件似乎一直都没有成立,CCA_MODE设置为If RSSI below threshold,AGC为默认设置,由于是多组异常测试,理论上仿真调试时会有信道被占用情况。清理信道评估代码编写流程有什么注意事项吗?