This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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

Part Number: CC1312R

Dear TI:

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

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

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

Thanks。

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

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

    RF部分代码逻辑如下:

    while(1) {
            // Wait to receive a packet
            EasyLink_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中的buffer
            Modbus_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中的buffer
            memset(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都不工作,不知道是不是信号量的使用逻辑不对。

    请帮忙查看一下。

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

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

  • 参考RF类似的示例逻辑:

    static void rxTaskFunction(UArg arg0, UArg arg1)
    {
        /* Init UART */
        const char  startPrompt[] = "Opening UART and RF:\r\n";
        const char  packetRxPromt[] = "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);
    }
    

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