I am working with a Zynq zc702 board with arm a9 (dual core), with FreeRTOS on both cores, and with the new version of Vitis 2024.2 (not based on Eclipse).
I am having a problem with interrupts and GIC within core1.
Before explaining the problem, here is the architecture:
core 0 = freertos that receives traffic in udp and copies it to ram using a Zero-Copy mechanism with SPSC Lock-Free Ring Buffer (which we can simplify to a ring buffer on ram)
core 1 = freertos with two task.
- task1 = high-priority logger that dequeues from RAM structure
- task2 = ScuTimer at 1Hz + Interrupt (id29) which, when called, performs an operation in the handling function
Application Notes / Considerations:
- In xiltimer, TTC0 is used as the system tick.
- I cannot initialize the GIC in task2, because it would break the UDP connection.
- In task1 on core1, I cannot insert a sleep, since I must dequeue every 0.5 ms
- in port_asm_vector.S is not missing the b FreeRTOS_IRQ_Handler
Issue
:
The timer counts and triggers, but the handler function is not called, and I cannot understand how this is possible.
I want to use the hardware timer.
I found this topic , but it seems obsolete to me ( zynq-7020-interrupts-under-freertos-v10-1-1)
Solutions I tried, but they didnât work :
Solution 1 :
âOnly touch the xInterruptControllerâ but i canât ! Because in the file portZynq7000.c i have this instruction :
#if !defined(XPAR_XILTIMER_ENABLED) && !defined(SDT)
static XScuTimer xTimer;
XScuGic xInterruptController; /* Interrupt controller instance */
#else
extern uintptr_t IntrControllerAddr;
#endif
and i am using the new vitis so i have SDT = 1 and XPAR_XILTIMER_ENABLED=1 , so i canât access to xInterruptController
Solution 2 :
XScuGic_LookupConfig and XScuGic_CfgInitialize â I canât, otherwise the GIC interrupt table is initialized and the UDP connection drops, since the GIC is a resource shared between the different cores.
Solution 3 :
âUse xPortInstallInterruptHandlerâ but didnât work , here the code :
void Logger::xadc_thread_start_3()
{
xil_printf("[XADC Task] Inizio configurazione.\r\n");
Timer_Config = XScuTimer_LookupConfig(XPAR_SCUTIMER_BASEADDR);
//Gic_Config = XScuGic_LookupConfig(XPAR_XSCUGIC_0_BASEADDR);
XScuTimer_CfgInitialize(&my_Timer, Timer_Config,
Timer_Config->BaseAddr);
xPortInstallInterruptHandler(XPS_SCU_TMR_INT_ID,
(Xil_ExceptionHandler)read_and_update_xadc_values,
(void *)this);
vPortEnableInterrupt(XPS_SCU_TMR_INT_ID);
u32 load_value = (XPAR_CPU_CORE_CLOCK_FREQ_HZ / 2) / 10;
// Step 1: Load timer
XScuTimer_LoadTimer(&my_Timer, load_value);
// Step 2: Enable AutoReload
XScuTimer_EnableAutoReload(&my_Timer);
// Step 3: Enable Interrupt
XScuTimer_EnableInterrupt(&my_Timer);
// Step 5: Start
XScuTimer_Start(&my_Timer);
xil_printf("[XADC Task] Task terminato.\r\n");
vTaskDelete(NULL);
}
void Logger::read_and_update_xadc_values(void *CallbackRef)
{
Logger *pLogger = (Logger *)CallbackRef;
XScuTimer *pTimer = &pLogger->my_Timer;
// Clean flag interrupt
XScuTimer_ClearInterruptStatus(pTimer);
xil_printf("[ISR]\n\r");
}
Solution 4 :
I tried accessing IntrControllerAddr, but this option does not work either.
Thank you in advance to anyone who can help me or give me some clues.