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.

TDA2X UART如何配置GIO_read为非阻塞型函数



TI的工程师们好:

我现在遇到一个棘手的问题,我使用"utils_uart.c"文件里面的函数来配置UART3,配置完成后使用GIO_read函数来读取串口3收到的数据。

我把串口3配置为“中断模式”,使用过程中我才发现GIO_read是阻塞性函数,如果没有收到数据程序就一直卡在GIO_read函数里等待。

我的线程还需要处理别的信息,所以我想把GIO_read适配成非阻塞状态,有数据就接收,没有数据就继续运行后面的程序。

然后,我配置了“ioParams.timeout = 10000;”,把UART3配置成等待10ms没有数据后就放弃本次读取操作。配置完成后的好处是GIO_read不会被没有串口数据被阻塞,我的uart_link可以继续做别的事情。但是,有一个问题,程序运行一段时间就会挂掉。报错信息:“XDC ASSERT - ERROR CALLBACK START”。

我现在苦于无法按照我的需求使用GIO_read,特来请教TI的工程师们如何把GIO_read配置成非阻塞,能够让我的uart_link可以在串口没有数据的时候可以做别的事情。

下面附带我的代码:  Private_uart3Init()配置UART3,uartRead3(Int8 *pOption)接受串口数据。

Void Private_uart3Init()
{
    Uart_ChanParams chanParams;
    Error_Block eb;
    GIO_Params  ioParams;
    static char uartName[16]; /* device name MUST be global or static variable */
    static DEV_Struct uartDevObj;
    static GIO_Struct uartTxObj;
    static GIO_Struct uartRxObj;
    static SyncSem_Struct uartTxSyncSemObj;
    static SyncSem_Struct uartRxSyncSemObj;
    static Semaphore_Struct uartTxSemObj;
    static Semaphore_Struct uartRxSemObj;
    static IOM_Packet       uartTxIomObj[UART_ASYNC_IOM_PACKET_MAX];
    static IOM_Packet       uartRxIomObj[UART_ASYNC_IOM_PACKET_MAX];
    DEV_Params    devParams;
    Uart_Params   uartParams;
    SyncSem_Params syncSemParams;
    Semaphore_Params semParams;

    Int32 devId;

    Error_init(&eb);

    /*
     * Initialize channel attributes.
     */
    GIO_Params_init(&ioParams);

    Uart_init();
    
    if(Bsp_platformIsTda2xxFamilyBuild())
    {
        strcpy(uartName, "/uart2");
        devId = 2;
    }
    else
    {   
        Vps_printf("NOT TDA2XX!! PLEASE CHECK YOUR HARDWARE!!\n");
    }

    uartParams              = Uart_PARAMS;
    uartParams.opMode       = UART_OPMODE_POLLED;    //UART_OPMODE_POLLED;   UART_OPMODE_DMAINTERRUPT         UART_OPMODE_INTERRUPT
    uartParams.hwiNumber    = 8u;
    uartParams.rxThreshold  = UART_RXTRIGLVL_8;
    uartParams.txThreshold  = UART_TXTRIGLVL_56;
    uartParams.baudRate     = UART_BAUDRATE_115_2K;
    uartParams.prcmDevId    = 0;
    /* INVARIANT_CONDITION.UNREACH
    * MISRAC_2004_Rule_13.7
    * MISRAC_WAIVER:
    * Code is currently unreachable.
    * This is kept to ensure future updates to modes.
    */
    if(uartParams.opMode == UART_OPMODE_POLLED)
    {
        printf(" SYSTEM: UART: POLLED Mode is Selected \n");
    }
    else if(uartParams.opMode == UART_OPMODE_INTERRUPT)
    {
        printf(" SYSTEM: UART: INTERRUPT Mode is Selected \n");
    }
    else
    {
        /* MISRA WARNING */
    }
    uartParams.enableCache = (Bool)FALSE;

    /* initialise the edma library and get the EDMA handle */
    chanParams.hEdma = NULL;

    /* If cross bar events are being used then make isCrossBarIntEn = TRUE and
     * choose appropriate interrupt number to be mapped (assign it to
     * intNumToBeMapped)
     */
    chanParams.crossBarEvtParam.isCrossBarIntEn = (Bool)FALSE;

    chanParams.crossBarEvtParam.intNumToBeMapped = 0xFFU;

    ioParams.chanParams = (Ptr)&chanParams;

    DEV_Params_init(&devParams);
    devParams.deviceParams = &uartParams;
    devParams.initFxn = NULL;
    devParams.devid = devId;

/* MISRA.CAST.CONST
 * MISRAC_2004 Rule_11.5
 * MISRAC_WAIVER:
 * External package errors like bios which are not
 * part of VSDK package can't be fixed
 */
    DEV_construct(&uartDevObj, uartName, (Ptr)&Uart_IOMFXNS, &devParams, &eb);

    SyncSem_Params_init(&syncSemParams);

    Semaphore_Params_init(&semParams);
    semParams.mode = Semaphore_Mode_BINARY;

    Semaphore_construct(&uartTxSemObj, 0, &semParams);

    syncSemParams.sem = Semaphore_handle(&uartTxSemObj);

    SyncSem_construct(&uartTxSyncSemObj, &syncSemParams, &eb);

    ioParams.sync =
        SyncSem_Handle_upCast(
            SyncSem_handle(
                &uartTxSyncSemObj
            )
        )
        ;

    if(ioParams.numPackets > UART_ASYNC_IOM_PACKET_MAX)
    {
        UTILS_assert(ioParams.numPackets <= UART_ASYNC_IOM_PACKET_MAX);
    }
    memset(&uartTxIomObj[0], 0, ioParams.numPackets * sizeof (IOM_Packet));
    ioParams.packets = &uartTxIomObj[0];

    /* create the required channels(TX/RX) for the UART demo */
    GIO_construct(&uartTxObj, uartName, (UInt32)GIO_OUTPUT, &ioParams, &eb);

    SyncSem_Params_init(&syncSemParams);

    Semaphore_Params_init(&semParams);
    semParams.mode = Semaphore_Mode_BINARY;

    Semaphore_construct(&uartRxSemObj, 0, &semParams);

    syncSemParams.sem = Semaphore_handle(&uartRxSemObj);

    SyncSem_construct(&uartRxSyncSemObj, &syncSemParams, &eb);

    ioParams.sync =
        SyncSem_Handle_upCast(
            SyncSem_handle(
                &uartRxSyncSemObj
            )
        )
        ;
    ioParams.timeout = 10000;
    memset(&uartRxIomObj[0], 0, ioParams.numPackets * sizeof (IOM_Packet));
    ioParams.packets = &uartRxIomObj[0];

    GIO_construct(&uartRxObj, uartName, (UInt32)GIO_INPUT, &ioParams, &eb);

    uartTxHandle2 = GIO_handle(&uartTxObj);
    uartRxHandle2 = GIO_handle(&uartRxObj);
    /* INVARIANT_CONDITION.UNREACH
    * MISRAC_2004_Rule_13.7
    * MISRAC_WAIVER:
    * Code is currently unreachable.
    * This is kept to ensure future updates by the called function.
    */
    if ((NULL == uartRxHandle2) || (NULL ==  uartTxHandle2))
    {
        printf(" SYSTEM: UART: ERROR: GIO_create(%s) Failed !!!\n", uartName);
    }
    else
    {
        InitDone3 = (Bool)TRUE;
    }
}


Void uartRead3(Int8 *pOption)
{
    Int32   nStatus  = IOM_COMPLETED;
    size_t  nLen    = 1u;
    nStatus = GIO_read(uartRxHandle2, &uartReadBuffer2, &nLen);
    if (IOM_COMPLETED != nStatus)
    {
        printf(" SYSTEM: UART: ERROR: GIO_read failed (status = %d) !!! \n",nStatus);
    }
    /* copy only one char */
    *pOption = (Int8)uartReadBuffer2[nLen - 1U];
}