Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FreeRTOS Hello World no interrupts to trigger ticks #301

Open
tlf30 opened this issue Jun 29, 2024 · 8 comments
Open

FreeRTOS Hello World no interrupts to trigger ticks #301

tlf30 opened this issue Jun 29, 2024 · 8 comments

Comments

@tlf30
Copy link

tlf30 commented Jun 29, 2024

When testing with a microblaze core that has a AXI timer, freertos fails to get tick interrupts with the hello world example and the example simply hangs on the first vTaskDelay.

image

image
image

Is there additional configuration required?

image
image

@kedareswararao
Copy link
Contributor

kedareswararao commented Jul 1, 2024

Hi @tlf30,
How are you generating the freertos_hello_world application? if we use template flow(Generating new domain along with application) all the required configuration will be set by the flow, looks like you have created the hello_world application for the already existing platform in this case need to enable XILTIMER_en_interval_timer to true , Modify the configuration and regenerate the application and let us know the test results.

@tlf30
Copy link
Author

tlf30 commented Jul 1, 2024

Hello @kedareswararao,
I am using a platform that I generated. It is a simple platform with two axi timers, axi uart lite, and a microblaze core connected to some ram.

I have tested with XILTIMER_en_interval_timer set to both true and false on my original project, thought that perhaps it was because I had fast interrupts enabled on the interrupt controller. I recreated the hardware from scratch with fast interrupts disabled. This has made no difference, and I have re-tested with XILTIMER_en_interval_timer set to true/false.

I am attaching my xsa here for reference. This is my first time using a Xilinx FPGA along with the tooling, so I am sure I have something wrong somewhere. If there is some specific files that I can provide for troubleshooting, please let me know.

design_1_wrapper.zip

EDIT: Current design for reference:
image

@tlf30
Copy link
Author

tlf30 commented Jul 2, 2024

@kedareswararao if it makes any difference, when I create the platform using the xsa file, I select FreeRTOS for the operating system. I would assume that it should setup all the needed parameters in the platform. The XILTIMER_en_interval_timer are set to false by default. But as mentioned I've tested with it set to true as well.

Any help is greatly appreciated.
Thanks,
Trevor

@tlf30
Copy link
Author

tlf30 commented Jul 4, 2024

Still working on this. As a note, I was able to test the hardware interrupts by creating a platform as a standalone OS, and using the following test code to ensure that the IRQ was getting processed by the microblaze core.

#include <xil_types.h>
#include <xuartlite_l.h>
#include <xintc.h>
#include <xparameters.h>

/* uartlite interrupt service routine */
void uart_int_handler(void *baseaddr_p) {
	char c;
    //xil_printf("Got IRQ \r\n");
	/* till uart FIFOs are empty */
	while (!XUartLite_IsReceiveEmpty(XPAR_AXI_UARTLITE_0_BASEADDR)) {
		/* read a character */
		c = XUartLite_RecvByte(XPAR_AXI_UARTLITE_0_BASEADDR);
		/* print character on hyperterminal (STDOUT) */
		xil_printf ("Character: %c \r\n", c);
	}
}

static XIntc IntcInstance; /* The instance of the Interrupt Controller */

int main(void)
{

    xil_printf ("Loading\r\n");

	// /* Enable Uartlite interrupt */
	XUartLite_EnableIntr(XPAR_AXI_UARTLITE_0_BASEADDR);


    int status;
    status = XIntc_Initialize(&IntcInstance, XPAR_XINTC_0_BASEADDR);
    xil_printf("XIntc_Initialize: %d \r\n", status);

    status = XIntc_Connect(&IntcInstance, XPAR_FABRIC_XUARTLITE_0_INTR, (XInterruptHandler) uart_int_handler, (void*)  XPAR_AXI_UARTLITE_0_BASEADDR);
    xil_printf("XIntc_Connect: %d \r\n", status);

    status = XIntc_Start(&IntcInstance, XIN_REAL_MODE);
    xil_printf("XIntc_Start: %d \r\n", status);

    XIntc_Enable(&IntcInstance, XPAR_FABRIC_XUARTLITE_0_INTR);

    /*
	 * Initialize the exception table.
	 */
	Xil_ExceptionInit();

	/*
	 * Register the interrupt controller handler with the exception table.
	 */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler) XIntc_InterruptHandler, &IntcInstance);

	/*
	 * Enable exceptions.
	 */
	Xil_ExceptionEnable();

    xil_printf("Ready for input\r\n");
	/* Wait for interrupts to occur */
	while (1);
}

At this point, I think that either something is not set correctly by the platform wizard when creating a freertos platform, or the hello world example is missing something. I spent a couple hours this morning diving around the code and it seemed like the IRQs were simply not getting to the freertos IRQ handler, but I was getting deeper into the code than I really wanted to for a
"first cup of coffee" debugging session.

@martinjthompson
Copy link

I don't have the SDK installed here, and it has been a while... but if I remember right, as well as enabling the interrupt on the peripheral, and enabing the interrupt controller, and connecting and registering the interrupt handler and starting the interrupt controller (!) you also need to enable the interrupts in the microblaze itself. I think there is a enable_interrupts() function (maybe in microblaze.h?)

@tlf30
Copy link
Author

tlf30 commented Jul 6, 2024

Yes, that is called via Xil_ExceptionEnable. I attempted to manually enable interrupts in the freertos example using my test above as a working reference. I have not been successful in doing so. I've not found any examples where the interrupts needed to be manually enabled for FreeRTOS, everything I've read indicates that the example should just work as long as the AXI timer exists and interrupts are setup in hardware.

@kedareswararao
Copy link
Contributor

Hello @kedareswararao, I am using a platform that I generated. It is a simple platform with two axi timers, axi uart lite, and a microblaze core connected to some ram.

I have tested with XILTIMER_en_interval_timer set to both true and false on my original project, thought that perhaps it was because I had fast interrupts enabled on the interrupt controller. I recreated the hardware from scratch with fast interrupts disabled. This has made no difference, and I have re-tested with XILTIMER_en_interval_timer set to true/false.

I am attaching my xsa here for reference. This is my first time using a Xilinx FPGA along with the tooling, so I am sure I have something wrong somewhere. If there is some specific files that I can provide for troubleshooting, please let me know.

design_1_wrapper.zip

EDIT: Current design for reference: image

Hi @tlf30 ,
Generated the freertos_hello_world for the xsa provided, Cross verified the defines in xparameters.h file and configuration in the xiltimer everything seems proper, Looks like it's a design issue, to cross check whether it's a design issue or not please test the same use case with the vitis classic tool which can be launched using vitis --classic option if the freertos_hello_world elf generated using this tool also not working means it's a design issue please raise a Support request so that corresponding team can help you on debugging the design.

Regards,
Kedar.

@tlf30
Copy link
Author

tlf30 commented Jul 9, 2024

Hello Kedar,
I'm having issues getting Vitis classic to load, it just locks up on the deprecation notice.
image

I'll keep trying to find a way to fix it. I'm doing a clean install on another computer right now.

Using a standalone platform. I was able to build a test case to verify the timers are working properly.
I had no issues getting the timer interrupts to function.

#include <xil_types.h>
#include <xuartlite_l.h>
#include <xintc.h>
#include <xparameters.h>
#include "xiltimer.h"
#include "xtmrctr.h"
#include "xintc.h"
#include "xil_exception.h"


/* uartlite interrupt service routine */
void uart_int_handler(void *baseaddr_p) {
	char c;
    //xil_printf("Got IRQ \r\n");
	/* till uart FIFOs are empty */
	while (!XUartLite_IsReceiveEmpty(XPAR_AXI_UARTLITE_0_BASEADDR)) {
		/* read a character */
		c = XUartLite_RecvByte(XPAR_AXI_UARTLITE_0_BASEADDR);
		/* print character on hyperterminal (STDOUT) */
		xil_printf ("Character: %c \r\n", c);
	}
}

void TimerCounterHandler(void *CallBackRef, u8 TmrCtrNumber)
{
	XTmrCtr *InstancePtr = (XTmrCtr *)CallBackRef;

	xil_printf ("Timer expired\r\n");
}

static XIntc IntcInstance; /* The instance of the Interrupt Controller */
static XTmrCtr TimerCounterInst;   /* The instance of the Timer Counter */

int main(void)
{

    xil_printf ("Loading\r\n");

	// /* Enable Uartlite interrupt */
	XUartLite_EnableIntr(XPAR_AXI_UARTLITE_0_BASEADDR);

    int status;
    status = XTmrCtr_Initialize(&TimerCounterInst, XPAR_AXI_TIMER_0_BASEADDR);
    xil_printf("XTmrCtr_Initialize: %d \r\n", status);
    
    status = XIntc_Initialize(&IntcInstance, XPAR_XINTC_0_BASEADDR);
    xil_printf("XIntc_Initialize: %d \r\n", status);

    status = XIntc_Connect(&IntcInstance, XPAR_FABRIC_XUARTLITE_0_INTR, (XInterruptHandler) uart_int_handler, (void*)  XPAR_AXI_UARTLITE_0_BASEADDR);
    xil_printf("XIntc_Connect UART: %d \r\n", status);

    status = XIntc_Connect(&IntcInstance, XPAR_FABRIC_AXI_TIMER_0_INTR,	(XInterruptHandler) XTmrCtr_InterruptHandler, (void *) &TimerCounterInst);
    xil_printf("XIntc_Connect Timer0: %d \r\n", status);

    status = XIntc_Start(&IntcInstance, XIN_REAL_MODE);
    xil_printf("XIntc_Start: %d \r\n", status);

    status = XTmrCtr_SelfTest(&TimerCounterInst, 0);
    xil_printf("XTmrCtr_SelfTest: %d \r\n", status);

    XIntc_Enable(&IntcInstance, XPAR_FABRIC_XUARTLITE_0_INTR);
    XIntc_Enable(&IntcInstance, XPAR_FABRIC_AXI_TIMER_0_INTR);

    /*
	 * Initialize the exception table.
	 */
	Xil_ExceptionInit();

	/*
	 * Register the interrupt controller handler with the exception table.
	 */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler) XIntc_InterruptHandler, &IntcInstance);

	/*
	 * Enable exceptions.
	 */
	Xil_ExceptionEnable();

    //Setup timer
    XTmrCtr_SetHandler(&TimerCounterInst, TimerCounterHandler,  &TimerCounterInst);
    XTmrCtr_SetOptions(&TimerCounterInst, 0,  
    XTC_INT_MODE_OPTION 
    | XTC_AUTO_RELOAD_OPTION
    );
    XTmrCtr_SetResetValue(&TimerCounterInst, 0, 0xF0000000);
    XTmrCtr_Start(&TimerCounterInst, 0);

    xil_printf("Ready for input\r\n");
	/* Wait for interrupts to occur */
    int count = 0;
	while (1) {
        int time;
        time = XTmrCtr_GetValue(&TimerCounterInst, 0);
        if (count > 10000) {
            xil_printf("Time: %x\r\n", time);
            count = 0;
        } else {
            count++;
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants