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 ¤tDataEntry->data:* - Length is the first byte with the current configuration* - Data starts from the second byte */packetLength= *(uint8_t*)(¤tDataEntry->data);packetDataPointer = (uint8_t*)(¤tDataEntry->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:
不客气