Zynq A9 dual-core FreeRTOS: issues with GIC and SCU Timer interrupts

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.

  1. task1 = high-priority logger that dequeues from RAM structure
  2. task2 = ScuTimer at 1Hz + Interrupt (id29) which, when called, performs an operation in the handling function

Application Notes / Considerations:

  1. In xiltimer, TTC0 is used as the system tick.
  2. I cannot initialize the GIC in task2, because it would break the UDP connection.
  3. In task1 on core1, I cannot insert a sleep, since I must dequeue every 0.5 ms
  4. in port_asm_vector.S is not missing the b FreeRTOS_IRQ_Handler

:red_circle: Issue :red_circle: :
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.

This question is very Xilinx specific. Please reach out to Xilinx as well.

Maybe it helps to take a look at a fork that I have of the FreeRTOS demos. I spent some time updating the demo code for Vitis 2024.2. This file sets up timers for its tests:

The demo is for SMP kernel, and it sounds like you are doing an AMP project, but maybe it still helps.

1 Like