微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI无线射频设计 > CC1310 RF射频跑死

CC1310 RF射频跑死

时间:12-23 整理:3721RD 点击:

CC1310在挂机测试时出现RF的Tx和Rx跑死的问题,挂机环境和代码如下:

挂机环境:1310模块RF常在Rx模式,用另外一个CC1310发射端给其发射数据,50ms发射一个32Bytes的数据包,长时间挂机后出现Rx不能接收数据(没有进入Rx的callback函数)且切成Tx模式后也不能发射数据的情况;此时1310的UART和GPIO等其他task均运行正常,故判断只有RF出现异常。

请问如何检测到RF状态异常?处于异常状态的时候如何恢复正常?或者有什么方法可以避免这种情况的发生?

RF部分的代码如下:

/* RF driver objects and handles */
static RF_Object rfObject;
static RF_Handle rfHandle;

/* Advanced TX command for sending long preamble */
static rfc_CMD_PROP_TX_ADV_t RF_cmdPropTxAdv;

/* TX packet payload (length +1 to fit length byte) and sequence number */
static uint8_t packet[33];
static uint16_t seqNumber;

typedef struct{
uint8_t packet_tx[32];
uint8_t seq_flag;
short tx_ready;
short rfTx_wakeup;
short rfCarry_Wave;
short factory_flag;
short factory_Rx;
float wake_time;

}RF_CONTROL;

static uint8_t RxData_buffer[10][8];
RF_CONTROL *m_rf_control = NULL;

/* TX task function. Executed in Task context by TI-RTOS when the scheduler starts. */
static void RFTaskFunction(UArg arg0, UArg arg1)
{
int j,k,i;
//add maple for test rf control result,可将其加入RF_CONTROL结构体中,以后若这里出问题直接重启单片机
int maple_result = 66;
RF_CONTROL rf_control;
memset(rf_control.packet_tx,0,sizeof(RF_CONTROL));
//rf_control.tx_ready = 0;
//rf_control.rfTx_wakeup = 0;
m_rf_control = &rf_control;

/* Initialize the radio */
RF_Params rfParams;
RF_Params_init(&rfParams);

/* Initialize TX_ADV command from TX command */
initializeTxAdvCmdFromTxCmd(&RF_cmdPropTxAdv, &RF_cmdPropTx);

/* Set application specific fields */
RF_cmdPropTxAdv.pktLen = PAYLOAD_LENGTH +1; /* +1 for length byte */
//RF_cmdPropTxAdv.pPkt = m_rf_control->packet_tx;
RF_cmdPropTxAdv.pPkt = packet;
RF_cmdPropTxAdv.preTrigger.triggerType = TRIG_REL_START;
RF_cmdPropTxAdv.preTime = WOR_PREAMBLE_TIME_RAT_TICKS(WOR_WAKEUPS_PER_SECOND);

//for rfTx
uint32_t curtime;
//maple note:
RF_cmdPropTx.pktLen = PAYLOAD_LENGTH+1-1;
RF_cmdPropTx.pPkt = m_rf_control->packet_tx; //发送的payload 设置为packet
RF_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME;
RF_cmdPropTx.startTrigger.pastTrig = 1;
RF_cmdPropTx.startTime = 0;


/*Set RF_RX para */
if(RFQueue_defineQueue(&dataQueue,
rxDataEntryBuffer,
sizeof(rxDataEntryBuffer),
NUM_DATA_ENTRIES,
MAX_LENGTH + NUM_APPENDED_BYTES))
{
/* Failed to allocate space for all data entries */
while(1);
}

/* Modify CMD_PROP_RX command for application needs */
RF_cmdPropRx.pQueue = &dataQueue; /* Set the Data Entity queue for received data */
RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1; /* Discard ignored packets from Rx queue */
RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1; /* Discard packets with CRC error from Rx queue */
RF_cmdPropRx.maxPktLen = MAX_LENGTH; /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
RF_cmdPropRx.pktConf.bRepeatOk = 1;
RF_cmdPropRx.pktConf.bRepeatNok = 1;

/* Request access to the radio */
rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);

/* Set the frequency */
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);

/* Enter RX mode and stay forever in RX */
RF_EventMask result = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_ENTRY_DONE);


/* Enter main TX loop */
while(1)
{
/* Wait for a button press */
//Semaphore_pend(txSemaphoreHandle, BIOS_WAIT_FOREVER);
if(m_rf_control->rfTx_wakeup)
{
maple_result = RF_cancelCmd(rfHandle,result,1);
if(maple_result != RF_StatSuccess)
{
//SysCtrlSystemReset();
}
usleep(30*1000);

//Create packet with incrementing sequence number and random payload
//m_rf_control->packet_tx[0] = PAYLOAD_LENGTH;
packet[0] = PAYLOAD_LENGTH;

for (i = 1; i < PAYLOAD_LENGTH +1; i++)
{
packet[i] = m_rf_control->packet_tx[i-1];
}

if(m_rf_control->seq_flag == 0)
{
packet[31] = (uint8_t)(seqNumber >> 8);
packet[32] = (uint8_t)(seqNumber++);
}
else
{
m_rf_control->seq_flag = 0;
}

curtime = RF_getCurrentTime();
RF_cmdPropTxAdv.startTime = curtime;
RF_cmdPropTxAdv.preTime = WOR_PREAMBLE_TIME_RAT_TICKS2(m_rf_control->wake_time);
//set_ledcolor(BLUE_CONSTANT);
/* Send packet */
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0);
//set_ledcolor(GREEN_ONCE);
m_rf_control->rfTx_wakeup = 0;
//maple note RF_runCmd 函数会做延时所以不必手动sleep
//sleep(1);
//usleep(m_rf_control->wake_time*1000*1000);
usleep(30*1000);
//sleep(1);

result = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_ENTRY_DONE);

}

if(m_rf_control->tx_ready)
{
maple_result = RF_cancelCmd(rfHandle,result,1);
if(maple_result != RF_StatSuccess)
{
//SysCtrlSystemReset();
}
usleep(30*1000);

if(m_rf_control->seq_flag == 0)
{
m_rf_control->packet_tx[30] = (uint8_t)(seqNumber >> 8);
m_rf_control->packet_tx[31] = (uint8_t)(seqNumber++);
}
else
{
m_rf_control->seq_flag = 0;
}

curtime = RF_getCurrentTime();
RF_cmdPropTx.startTime = curtime;

RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
usleep(30*1000);
result = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_ENTRY_DONE);
m_rf_control->tx_ready = 0;

}

usleep(100*1000);
}
}

void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
if (e & RF_EventRxEntryDone)
{
/* Toggle pin to indicate RX */
/******************************maple note: test board no led
PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
****************************/

/* Get current unhandled data entry */
currentDataEntry = RFQueue_getDataEntry();

/* Handle the packet data, located at &currentDataEntry->data:
* - Length is the first byte with the current configuration
* - Data starts from the second byte */
packetLength = *(uint8_t*)(&currentDataEntry->data);
packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);

/* Copy the payload + the status byte to the packet variable */
memcpy(packet, packetDataPointer, (packetLength + 1));

//UART_write(uart,packet,packetLength);
RFQueue_nextEntry();

CC1310_Rx_Filter();

if(display_flag == 0x01)
{
Send_To_UartTx(packet,packetLength);
display_flag = 0x00;
}


}
}


void CC1310_Rx_Buffer(uint8_t i)
{
RxData_buffer[i][0] = packet[3];
RxData_buffer[i][1] = packet[4];

RxData_buffer[i][2] = packet[5];
RxData_buffer[i][3] = packet[6];
RxData_buffer[i][4] = packet[7];
RxData_buffer[i][5] = packet[8];

RxData_buffer[i][6] = packet[30];
RxData_buffer[i][7] = packet[31];
}

//过滤相同的数据包

void CC1310_Rx_Filter(void)
{
unsigned int i,j;

display_flag = 0x01;

if((packet[0]!= 'Z')||(packet[1]!= 'M')||(packet[2]!= 'D'))
{
display_flag = 0x00;
return;
}

for(i = 0; i<10; i++) //先判断设备ID与缓冲的是否相同,开了10的缓冲
{
if((packet[3] == RxData_buffer[i][0]) //判断唯一ID和设备类型是否相同:类型+源设备ID
&& (packet[4] == RxData_buffer[i][1])
&& (packet[5] == RxData_buffer[i][2])
&& (packet[6] == RxData_buffer[i][3])
&& (packet[7] == RxData_buffer[i][4])
&& (packet[8] == RxData_buffer[i][5]))
{
if((packet[30] == RxData_buffer[i][6]) //判断序列号是否相同
&& (packet[31] == RxData_buffer[i][7]))
{
display_flag = 0x00; //不再显示多次重传数据,只显示一次即可。消息ID用于多次重传时区分数据
return;
}
else //同个台设备不是重传的数据
{
j++;
}
}
else //不是同一个设备
{
j++;
}

}

if(j == 10) //循环一轮后,接收到的数据与缓冲区数据不同。则存入缓冲区
{
j = 0;
CC1310_Rx_Buffer(buffer_num++); //每进一次此函数,buffer_num才加1,从第一个缓冲开始,修改一个缓冲器的值
if(buffer_num == 10) //表示10个缓冲器都修改过了一遍,下一次从第一个开始修改
buffer_num = 0;
}
}

void Send_To_UartTx(uint8_t* data,int len)
{
memset(uartTx.data,0,UART_LEN);
//uartTx.data = data;
uartTx.data[0] = 0xAA;
uartTx.data[1] = 0x55;
uartTx.data[2] = 0xA2;
memcpy(uartTx.data+UART_HEAD,data+UART_HEAD,UART_LEN-UART_HEAD);

uartTx.len = len;
uartTx.flag = 1;
}

你可以在线跟一下,看看与RF相关的task的状态。

可以使用CCS调试界面下的ROV进行查看。

您好,这个方法只能接烧录线出来在线调试,如果出现问题了也只能提示是哪个task跑死吧,不好追踪具体跑死原因。

你贴出来的代码,由于格式问题,看着比较吃力,建议下次可以以文件的方式上传。

大概看了一下你的代码,有几个地方可以重点检查一下。

1. maple_result = RF_cancelCmd(rfHandle,result,1);执行不成功时的应对机制

2. 发送时使用的RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTxAdv, RF_PriorityNormal, NULL, 0); 没有pCb和bmEvent 

感谢你的建议。

对于第一点,执行不成功时的应对机制有没有一些建议呢? 目前我能想到的处理方法有 :

1.RF_close(),再重新RF_open()。

2.调用 RF_cancelCmd(rfHandle,result,0),docs/tidrivers手册上写了第三个参数为0时可以强制取消。

请问上面两种方法的可行性?或者还有什么其他更好的方法呢?在进入Rx的函数: result = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_ENTRY_DONE);是否也要做相应的保护操作?

对于第二点,在Tx的RF_runCmd()中添加pCb和bmEvent 是否是为了确认Tx是否成功,运行Tx时若有pCb返回视为正常,若无pCb返回则执行异常处理代码?

仿真器跟踪最好了,停机无法接收时查看命令中的STATUS看看是啥情况。

一般来说,就是这两种方法。SDK内的rfPacketErrorRate示例工程中,有RF_cancelCmd相关代码,您可以看一下

rxCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &rx_callback, RF_EventRxEntryDone);

RF_cancelCmd(rfHandle, rxCmdHndl, 0);
RF_pendCmd(rfHandle, rxCmdHndl, RF_EventRxEntryDone);
RF_close(rfHandle);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top