Hi Everyone,
I am developing to Xilinx zcu104 board over the Cortex R5 core and I’m trying to figure out why my code fails.
I developed a system with 2 communication channels: Ethernet and UART.
For both of the channels, I am using interrupts in order to detect a message received.
I receive messages from Ethernet every 10 to 40 milliseconds and form the UART every 1 millisecond.
A few seconds (in some cases a few minutes), after I start sending messages through UART to the board (while the Ethernet channel sends and receives messages), I run into an assert error in the “XUuartPs_InterruptHandler(XUartPs *InstancePtr)
” function.
For some reason, which I’m trying to figure out, The XUartPs instance pointer, received as the “XUartPs_InterruptHandler(XUartPs *InstancePtr)
” parameter, is arriving the function empty and then falls in the Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY)
check.
This is how I initialize the UART interrupt system:
main.c:
int main()
{
sys_thread_new("main_thread", (void(*)(void*))main_thread, 0, THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
vTaskStartScheduler();
// should never arrive here
while(1);
return 0;
}
int main_thread()
{
int Status;
// init uart interrupt
Status = Init_uart_1(&xInterruptController, &UartPs,UART_DEVICE_ID, UART_INT_IRQ_ID); //UART 1 init
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
FreeRTOS_SetupTickInterrupt(); // enable the tick interrupts in order to get delay
xil_printf("\n\r\n\r");
xil_printf("-----lwIP Socket Mode UDP Server Application------\r\n");
/* initialize lwIP before calling sys_thread_new */
lwip_init();
/* any thread using lwIP should be created using sys_thread_new */
BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,
const char * const pcName,
configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pxCreatedTask);
sys_thread_new("nw_thread", network_thread, NULL, THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
...
... // some LWIP code
...
}
comm.c:
int Init_uart_1(XScuGic *IntcInstPtr, XUartPs *UartInstPtr, u16 DeviceId, u16 UartIntrId)
{
int Status;
XUartPs_Config *Config;
u32 IntrMask;
/*
* Initialize the UART driver so that it's ready to use
* Look up the configuration in the config table, then Initialize it.
*/
Config = XUartPs_LookupConfig(DeviceId);
if (NULL == Config)
{
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(UartInstPtr, Config, Config->BaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/* Check hardware build */
Status = XUartPs_SelfTest(UartInstPtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Connect the UART to the interrupt subsystem such that interrupts
* can occur. This function is application specific.
*/
Status = SetupInterruptSystem(IntcInstPtr, UartInstPtr, UartIntrId);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
/*
* Setup the handlers for the UART that will be called from the
* interrupt context when data has been sent and received, specify
* a pointer to the UART driver instance as the callback reference
* so the handlers are able to access the instance data
*/
XUartPs_SetHandler(UartInstPtr, (XUartPs_Handler) Handler_uart_1, UartInstPtr);
/*
* Enable the interrupt of the UART so interrupts will occur, setup
* a local loopback so data that is sent will be received.
*/
IntrMask = XUARTPS_IXR_RXOVR;
XUartPs_SetInterruptMask(UartInstPtr, IntrMask);
XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_NORMAL);
/*
* Set the receiver timeout. If it is not set, and the last few bytes
* of data do not trigger the over-water or full interrupt, the bytes
* will not be received. By default it is disabled.
*
* The setting of 8 will timeout after 8 x 4 = 32 character times.
* Increase the time out value if baud rate is high, decrease it if
* baud rate is low.
*/
XUartPs_SetRecvTimeout(UartInstPtr, 8);
/*
* Set RX FIFO threshold to 1
*/
XUartPs_SetFifoThreshold(UartInstPtr, 1);
return XST_SUCCESS;
}
int SetupInterruptSystem(XScuGic *IntcInstancePtr, XUartPs *UartInstancePtr, u16 UartIntrId)
{
int Status;
GicConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == GicConfig)
{
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, GicConfig, GicConfig->CpuBaseAddress);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler, IntcInstancePtr);
Status = XScuGic_Connect(IntcInstancePtr, (u32) UartIntrId, (Xil_InterruptHandler) XUartPs_InterruptHandler, (void *) UartInstancePtr);
if (Status != XST_SUCCESS)
{
return XST_FAILURE;
}
Xil_ExceptionEnable();
XScuGic_Enable(IntcInstancePtr, (u32) UartIntrId);;
return XST_SUCCESS;
}
Can’t wait to solve this bug.
Thank you!