I am doing 10.1.1 at the moment, if you frequent the FreeRTOS forums you would have seen
The aarch64 bit version has held me up the context switching has been driving me nuts, well specifically it is when you allow critical nesting. You can turn it off with the config setting but I really don't want to do it because of what I want to do with inter core messaging.
I see you already did what I only realized I needed to do as I got further into the port. That being that the Irq handler section has to come out on it's own for other stuff to access. You will be able to easily get your current system going probably later tonight as I publish the multicore irq block code tonight. That is really all the complication is to porting the FreeRTOS code to multicore.
With your background you probably don't need much more than that so here is what i did with the Irq code to make it multicore
https://github.com/LdB-ECM/Exchange/tre ... r_MacLoad1
So the interrupt handlers now have core numbers as there are four sets of tables one for each core.
The multicore QA7 pending interrupts are available at these addresses as an array of 4 ... 1 for each core
Code: Select all
#define QA7_CORE_IRQ_PENDING ((volatile __attribute__((aligned(4))) uint32_t*)(uintptr_t)(0x40000060)) // Array of 4 .. one for each core
#define QA7_CORE_FIQ_PENDING ((volatile __attribute__((aligned(4))) uint32_t*)(uintptr_t)(0x40000070)) // Array of 4 .. one for each core
The bottom eleven bits have valid Irq pending sources as per datasheet QA7 so I merge them in to the empty bits of the Basic 8 and you now have a new maximum Irq number of 84.
So this is what the IrqHandler looks like
Code: Select all
void irqHandler (void)
uint32_t ulMaskedStatus = (*BCM2835_INTC_IRQ_BASIC); // Read the interrupt basic register
__asm("mrc p15, 0, %0, c0, c0, 5 \t\n" : "=r" (coreId)); // Read Core ID from CPU register
coreId &= 3; // Mask off all but core number
// Bit 8 in IRQBasic indicates interrupts in Pending1 (interrupts 31-0):
if (ulMaskedStatus & (1 << 8))
handleRange(coreId, (*BCM2835_IRQ_PENDING1) & coreICB[coreId].enabled, 0);
// Bit 9 in IRQBasic indicates interrupts in Pending2 (interrupts 63-32):
if (ulMaskedStatus & (1 << 9))
handleRange(coreId, (*BCM2835_IRQ_PENDING2) & coreICB[coreId].enabled, 32);
// Bits 0 to 7 in IRQBasic represent interrupts 64-71
ulMaskedStatus &= 0xFF; // Clear all but bottom 8 bits
// Bits 0 to 11 in Core Irq pending represent interrupts 72-83
ulMaskedStatus |= ((QA7_CORE_IRQ_PENDING[coreId] &0xAFF) << 8); // Add the QA7 irq bits to the IRQbasic (bits 8 & 10) ignored
if (ulMaskedStatus != 0)
handleRange(coreId, ulMaskedStatus & coreICB[coreId].enabled, 64);
Compare it to your source .. so all that happens is the coreid is used to direct it to right struct, no more complex than that
https://github.com/macload1/RPiFreeRTOS ... terrupts.c
You should be able to use that instead of your current one and it should function on your current code on core0. Alternatively you should be able to move your code to execute on another core and core0 should still function correctly with interrupts.
Now finally to deal with FreeRTOS grab all the internal data and simply place them into a struct, like I did with the interrupt handler above.
You add a core number to that structure and make an array of the struct of the number of systems you want.
Then go thru and any access to the internal variables you use the core number as the index of the structure from the array to use. It is just a lot of typing. All you then need is a call which sets the coreId, I just made a call FreeRTOS_Init and it needs to call before anything else and you know the rest from there. I just use static structs because there isn't much data but if you really wanted to push the envelope you could malloc a FreeRTOS struct size of data on demand.
You now have a version of FreeRTOS that can run on any core or multiple at once ... enjoy
One of the things you could possibly help me with is do you know all the Irq numbers from that system, I am trying to make defines for all the common ones. I am going to have to map them all and it could save time if you know some already. The local core timer is 83 by the way if you do decide to play and 64 is the peripheral timer which you already know.