Hi all, I hope to use FreeRTOS and eventually the MQTT client on our FPGA based system.
I have downloaded and worked through the NIOS II port on the FreeRTOS site,
but it is having problems:
The hardware timer is being configured, and will generate one interrupt at the boot stage as it is being configured, but then it no longer gets the IRQ cleared, and thus there are no timer interrupts.
In my non FreeRTOS applications, the timer is running, and the IRQ is cleared every time.
Once I add in the FreeRTOS code, that timer IRQ goes high and no longer gets cleared. It’s as if the interrupt handler is broken. This happens even if my application code does not call any FreeRTOS routines (like vTaskStartScheduler() ).
I suspect it is the assembly code causing some changes to the IRQ which breaks the timer.
Any places I should continue to dig at?
In a FreeRTOS application, the tick timer isn’t supposed to be running before you call vTaskStartScheduler()
. (Part of that function’s job is to start the timer.) If the timer expires before vTaskStartScheduler()
, the wrong ISR might execute.
If you have a debugger available, put a breakpoint here. If the code reaches the breakpoint at all, then you can see if perhaps it is getting stuck on the asm(“break”) statement.
Ah, I’ll try that out. You have given me food for thought…
One other question, I was trying to run the “standard” FreeRTOS demo, (which doesn’t work yet) and was able to compile it at least, but then I tried a simpler “hello world” FreeRTOS test, and my compiler decided to complain about the “asm” command sprinkled in the code.
Looking into this, one resource said these should be “asm” not “asm”.
I don’t understand why it would be ok in one application and not ok in another… Any ideas?
According to gcc documentation here the availability of asm
is dependent on command-line options used (or not used) when invoking gcc. However, the availability of __asm__
(which has identical functionality) is not dependent on command-line options.
Testing this issue more - the generic Nios II CPU code from Altera seems to set up the timer with an ISR and start it running, before it calls “main()”.
I’m guessing this behavior is causing problems in FreeRTOS…
I’ll have to work out where this code is and comment it out so the FreeRTOS task scheduler isn’t trying to configure an already running timer…
I’m getting closer, very much thanks to your help jefftenney.
I disabled Altera’s init code that sets up and launches the timer before FreeRTOS is ready for it.
I single stepped through the FreeRTOS startup in main, then let it run once I could see that the tick ISR was installed and the timer started.
I added IO port writes to the timer isr toggling my 8 bit LED output between 0x99 and 0xaa, and now I can see, using the Altera logic analyzer that the code seems to be stuck in the IRQ in a loop forever, toggling between those two numbers, far faster than once per millisecond. I suspect it is failing to clear the IRQ. I’ll go look at that next, but at least the timer is actually starting up now!
What is weird, is that the timer IRQ is cleared, but not toggling at a high rate with the ISR looping I see in the analyzer. My ISR never seems to quit, it’s like it’s jumping back to itself every loop.
Seems like maybe the timer period way too short.
Have you set configCPU_CLOCK_HZ
to match the system clock?
Can you add some diagnostic code to the ISR to read and store the current count (snapshot register) and/or the period register just to make sure the values are as expected? Then put a breakpoint immediately after those reads but still in the ISR.
Finally got it running a basic task, thank you for your help jefftenney!
The final glitch was that I had a JTAG debugger device in place, with a higher priority IRQ than the system timer IRQ. It was keeping the CPU busy enough that the timer IRQ would never get a chance to work. Now the jtag debugger is at a lower priority, and the test tasks are running.
Now to add ethernet support .
Nice work figuring it out – and thanks for reporting back.