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];
}