FreeRTOS Cortex A9 with L1 cache

graffitikjt wrote on Thursday, November 05, 2015:

Hi,

I am using FreeRTOS 8.2.1 on a TI AM4379 using the Cortex A9 port.

All is well, I have 6 tasks running, interrupts are working…

Until I enable the L1 cache, at which point I start getting interrupt 1023 being fired (‘spurious interrupt’ according to ARM docs). Sometimes I get the expected interrupts (timer, ethernet packet rx etc) followed immediately by an int 1023, sometimes I only get an int 1023 (and don’t receive the interrupt I was expecting).

The problem only occurs when the MMU is flagging the DDR3 RAM area (from which the code is running) as WriteBack, WriteAllocate (the ‘fastest’ setting). Using WriteThrough, NoWriteAllocate (slower) and the problem goes away. This led me to suspect a timing issue in the FreeRTOS Cortex A9 interrupt handler (maybe writing the IAR and re-enabling interrupts before the write had time to clear the int) but I can’t find anything suspect in there.
I noticed that the FreeRTOS Cortex A9 int handler doesn’t write the Priority Mask Register (PMR), and so doesn’t support nested interrupts. I believe this could potentially cause a 1023, if interrupts are re-enabled in the handler before the interrupt source has been cleared, and the PMR hasn’t been updated with the value of the current int priority, so the same interrupt would be triggered again (interrupting itself, thus the 1023). It looked like this may be possible in the FreeRTOS int handler, as interrupts are enabled just before the OEI register is written, but swapping the int enable and int clear didn’t solve the problem.

Not sure what else to try! I need to enable the L1 cache for performance reasons.

Is anyone using FreeRTOS on a Cortex A9 WITH L1 cache enabled (WriteBack, WriteAllocate)? Has anyone experienced similar problems and found a solution??!

Many thanks and best regards,

Kieran.

rtel wrote on Thursday, November 05, 2015:

Looking at our Zynq examples, I see the following getting called at initialisation time:
Xil_L1DCacheEnable();
Xil_L2CacheEnable();

So the L1 D Cache is being used.

Looking at the RZ/A demo I see:
CP15_ICache(TRUE);

Which is at least turning on the I cache, but I don’t know how it compares to the AM4379.

A question though - are spurious interrupts actually causing you a problem? I think they are expected when using the priority mask register, because an interrupt may be accepted, only to find it is masked by the time it is ready to execute - in which case the interrupt does not need to be cleared using the IER register, and will be accepted again when the priority mask register is cleared.

graffitikjt wrote on Thursday, November 05, 2015:

Thanks for the fast reply,

Extra spurious interrupts aren’t really a problem, but sometimes we seem to get a 1023 INSTEAD of the interrupt we were expecting (causing an interrupt to be missed), and sometimes we don’t get any interrupt at all.

It’s very strange, the L1 cache and interrupt controller are such distinct parts of the system that it’s curious that enabling the cache has any impact on the received interrupts at all.

I have tried relocating the vector table into both DDR3 and internal SRAM with no change.

Any other suggestions greatly appreciated!

Kieran.

graffitikjt wrote on Thursday, November 05, 2015:

Testing the L1 Instruction vs Data cache:
Enabling only L1 Instruction cache, the application runs as expected.
Enabling only L1 Data cache doesn’t seem to be an option. The application runs as expected, but slowly (as if no cache was active).
Enabling both I and D cache, the application runs superfast, but interrupts are missed and spurious interrupts are received.

It’s curious that the RZ/A demo only enables the I cache. I wonder if similar interrupt oddities would be found on the RZ/A if the D cache was also enabled.
And likewise with the Zynq, if it’s similar to the TI then only enabling the D cache doesn’t seem to do anything, so I wonder how that would behave with both I+D cache enabled.

graffitikjt wrote on Friday, November 06, 2015:

Hi again,

Sorry, it appears the missed interrupts were due to a timing bug elsewhere in my code.
Everything seems to be running ok now with L1 cache fully enabled.
I am still getting a number of spurious interrupts (4 or 5 per second), but they don’t seem to be causing any problems, so for the time being I will just ignore them.
Thanks for your help, and sorry for previously suspecting a problem in the FreeRTOS int handler :confused:

Kieran.

rtel wrote on Friday, November 06, 2015:

Hi Kieran,

Thanks for getting back with this information so this thread can be
concluded. No problems with looking at all aspects, including the RTOS,
when trying to debug these things - and its always good for us to
re-visit how we implement things following a third party’s scrutiny too

  • it helps up all.

Regards.