TI中文支持网
TI专业的中文技术问题咨询交流网站

CC1312R: 如何解决UART和RF的阻塞问题

Part Number:CC1312R

Dear TI:

功能说明:CC1312要实现通过串口读取数据并响应输出,使用readCallback函数来实现读取中断,在函数中执行UART_read(handle, recv_buf, wantedRxBytes);函数来获取下一次数据。

然后另一个线程实现RF射频来接受信息。

出现的问题:在串口读取一次之后,只能接受一次RF的信息,当下一次串口执行一次之后又可以接受一次信息,猜想是UART_read()函数阻塞了RF的进程。这种情况怎么办?怎么让两者互相独立?

Thanks。

Kevin Qiu1:

看现象可能是阻塞了,回调函数中不能有任何形式的阻塞,将UART_read()从回调函数中拿出来,尝试使用信号量

,

J M:

您好,尝试去使用信号量去试验,

RF部分代码逻辑如下:

while(1) {// Wait to receive a packetEasyLink_receiveAsync(echoRxDoneCb, 0);/* Wait indefinitely for Rx */Semaphore_pend(echoDoneSem, BIOS_WAIT_FOREVER);}

此处的信号量实现等待RX信号,当接收完成后post信号量。

串口部分由原来的在readcallback函数中调用uart_read函数改成Semaphore_post(echoDoneSem);

static void readCallback(UART_Handle handle, void *recv_buf, size_t size)
{uart = handle;if(size == 8){memset(mdcmd_buf, 0, MAX_BUF_SIZE);memcpy(mdcmd_buf,recv_buf,size);UART_control(handle,(UART_CMD_RESERVED + 2),NULL);//清除uart_read中的bufferModbus_flag = true;memset(recv_buf, 0, MAX_BUF_SIZE);Semaphore_post(echoDoneSem);//UART_read(handle, recv_buf, wantedRxBytes);}else//同时收到多条指令或着不是正确指令时{UART_control(handle,(UART_CMD_RESERVED + 2),NULL);//清除uart_read中的buffermemset(recv_buf, 0, MAX_BUF_SIZE);Semaphore_post(echoDoneSem);//UART_read(handle, recv_buf, wantedRxBytes);}MD_wdg_flag = true;
}

然后在UART执行逻辑中将UART_read函数放到while循环中,并用Semaphore_pend去阻塞。如下:

while(1){UART_read(uart, recv_buf, wantedRxBytes);Semaphore_pend(echoDoneSem, BIOS_WAIT_FOREVER);if(Modbus_flag){func_unpackage(&mdcmd_buf[0], 8);//执行Modbus指令chargeBaudFun();//波特率是否变更Modbus_flag = false;}}

如此操作不知道是不是您之前的意思,我的想法是,在阻塞的时候当RF或者readcallback有响应时执行完释放echoDoneSem,然后继续等待RF和UART。

实验的结果是,RF和UART都不工作,不知道是不是信号量的使用逻辑不对。

请帮忙查看一下。

,

J M:

我尝试将read放外面,然后将RF部分注释掉,UART可以正常使用,通过信号量来等待串口信息。

如果使用同一个信号量是不是还是会出现阻塞的问题?相当于没解决问题是吗?

,

Kevin Qiu1:

参考RF类似的示例逻辑:

static void rxTaskFunction(UArg arg0, UArg arg1)
{/* Init UART */const charstartPrompt[] = "Opening UART and RF:\r\n";const charpacketRxPromt[] = "Packet received \r\n";UART_Handle uart;UART_Params uartParams;UART_init();/* Create a UART with data processing off. */UART_Params_init(&uartParams);uartParams.writeDataMode = UART_DATA_BINARY;uartParams.readDataMode = UART_DATA_BINARY;uartParams.readReturnMode = UART_RETURN_FULL;uartParams.readEcho = UART_ECHO_OFF;uartParams.baudRate = 115200;uart = UART_open(Board_UART0, &uartParams);if (uart == NULL) {/* UART_open() failed */while (1);}/* Init RF */RF_Params rfParams;RF_Params_init(&rfParams);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_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);/* Write to the UART before starting RX */UART_write(uart, startPrompt, sizeof(startPrompt));/* Enter RX mode and stay forever in RX */RF_EventMask terminationReason = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx,RF_PriorityNormal, &callback,RF_EventRxEntryDone);while(1){/* Waiting for packet */Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);/* Writing packet to UART */UART_write(uart, &packet, packetLength);};
}void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{if (e & RF_EventRxEntryDone){/* Toggle pin to indicate RX */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));RFQueue_nextEntry();/* Packet received */Semaphore_post(semHandle);}
}/**======== main ========*/
int main(void)
{Semaphore_Params semParams;/* Construct a Semaphore object to be use as a resource lock, inital count 1 */Semaphore_Params_init(&semParams);Semaphore_construct(&semStruct, 0, &semParams);/* Obtain instance handle */semHandle = Semaphore_handle(&semStruct);/* Call driver init functions. */Board_initGeneral();/* Open LED pins */ledPinHandle = PIN_open(&ledPinState, pinTable);Assert_isTrue(ledPinHandle != NULL, NULL);/* Initialize task */RxTask_init(ledPinHandle);/* Start BIOS */BIOS_start();return (0);
}

,

J M:

您好,刚才我尝试了下将RF里面的Semaphore_handle去掉了,在UART_read那边加Semaphore_handle,这样能解决我的问题了。感谢帮忙

,

Kevin Qiu1:

不客气

赞(0)
未经允许不得转载:TI中文支持网 » CC1312R: 如何解决UART和RF的阻塞问题
分享到: 更多 (0)