LPC43xx Dual Core Application

Hey there, I got problems with my DualCore Application. I am using a lpc4357 and want freeRTOS running on the M4 and M0.
Of cause I worked myself through the blinky examples (lpcOpen).
On the M4 I got freeRTOS running with emWin displaying some Graphs on a display. So everything’s ok there
On the M0 I tried to get some tasks running. I configured the RIT-Timer to call the sysTick-Function, that’s working.
So I expected that everything would work on the M0, but it looks like my pendSV-Handler is shooting trouble. It causes my Program Counter to run into a Memory Section, where no Code is stored. My Programm Code starts at 0x1b000000 (Flash Memory) while the programm jumps to 0x000000ce (Datasheet: 256 MB Shadow Area) and stops there. Unfortunatly I am not able to do single step through the ASM-Code (I use GNUC Compiler with Red Suite / Red Probe+). When I am stopping inside the Handler using a breakpoint, the programm does not run into the wrong section directly. The program jumps into the Handler again and again. When I deactivate the breakpoint and suspend the application, the program ends up in 0x000000ce. But I am not able to get more details about the “bad moment”. As I understand (correct me if I am wrong) the pendSVHandler is responsible for the context switching, so I assume there occurs an error while storing or loading the correct PC. Is it possible, that there is sth. wrong within the assembler code, or is the reason for the problem somewhere else? (Maybe memory allocation?) Regards,
Flo

LPC43xx Dual Core Application

To my knowledge, FreeRTOS is not set up specifically to handle a multi-core environment. You are going to have to handle a few issues: 1) The current code for a critical section just uses blocking off interrupts. For a multicore system, it must also block the other core from entering a critical section, otherwise it is possible for the two processors to be updating the same data at once, which will cause problems. 2) You may need to worry about cache coherency, just because one processor has written a value doesn’t mean the other processor will immediately see the change, depending on how the cache works, it is also possible that the order of writes may change. 3) It sounds like your system isn’t “symmetrical” so tasks need to organized so that they know which processor they can run in. If no tasks can run on either processor, the simplest would be to have two task lists (and related structures), otherwise you need to add an affinity flag into the TCB. 4) Either of these changes will require other changes in the FreeRTOS kernel. Either the scheduler for a core needs to know how to pass over tasks that can’t run on that core, or other parts need to scan the multiple task list to activate tasks on all cores that are waiting for something. These pieces also need to find tasks on all cores for activation.

LPC43xx Dual Core Application

The LPC43XX has two cores, but FreeRTOS runs independently on each.  One is an M4, the other an M0, and NXP have an API for the two cores to send messages to each other. I believe you can find projects with FreeRTOS running on both cores at http://www.lpcware.com Regards.

LPC43xx Dual Core Application

Hey Richard, thank you for your answer. Excuse me, i think i left some details. The lpc4357 is a microcontroller using two seperate cores sharing some periphery (here is an overview: http://www.nxp.com/scale-image/w-800/documents/block_diagram/LPC4300_block_diagram.jpg). So also my aim is, to set up a seperate FreeRTOS Enviroment on each core (like it is done in lpcOpen Example for a different Board with a different development enviroment).
At the moment the M4 is running his freeRTOS at his own flash and SRAM memory regions. The M0 uses different regions, for now there is no shared memory. So there is no need for cache coherency i think.

LPC43xx Dual Core Application

Hi richardbarry, I used the example project from http://www.lpcware.com. As I don’t use Keil µVision, I ported the project to Red Suite and used IO Functions for my DevBoard (EA 4357). I got everything running correct on the M4 and configured the M0 as told.
I already spend about 1 day checking back to the lpcware example project, but i don’t see any differences anymore. So I am asking here if there’s someone who could imagine the reason for the problem. Regards,
Flo

LPC43xx Dual Core Application

I got the problem. While porting it seems like I lost the naked-Attributes for the pendSV- and portSVC-Handler. I used:
void xPortPendSVHandler( void );
void xPortSysTickHandler( void );
void vPortSVCHandler( void ); instead of void xPortPendSVHandler( void ) __attribute__ (( naked ));
void xPortSysTickHandler( void );
void vPortSVCHandler( void ) __attribute__ (( naked ));
Anyway there’s still a problem:
It looks like my system is not able to do a task switching.
I created a simple testTask wich runs into vTaskDelay(…) and never wakes up.
Instead the IdleTask is running all the time. If I use a ApplicationIdleHook with __WFI()  (makes the core waiting for an interrupt), the idleTask also falls asleep, but doesn’t wake up.
This wouldn’t surprise me, but the RITTimer Interrupt (which I use as a SysTick) gets called all the time and also calls
the xPortPendSVHandler(). This is my xPortSysTickHandler: void xPortSysTickHandler(void)
{
unsigned long ulDummy;     // Clear Interrupt Flags
    LPC_RITIMER->CTRL |= RITINT;
   NVIC_ClearPendingIRQ(RITIMER_IRQn); #if configUSE_PREEMPTION == 1
// If using preemption, also force a context switch.
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
#endif ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(ulDummy);
}

LPC43xx Dual Core Application

Nothing in the FreeRTOS/source directory should require porting.  Please revert any changes in those files, and ensure the interrupt handlers are installed correctly as per item 1 in the following FAQ: http://www.freertos.org/FAQHelp.html Regards.

LPC43xx Dual Core Application

hello
i have a board EA4357 and i’m not able to run even simple example with dual core. not even RIT timer.
while debugging M0 only in this line:
NVIC_EnableIRQ(M0_RITIMER_OR_WWDT_IRQn);
cpu goes to some unknown address so i cannot start rit interrupt in M0 and the other hand while trying to use IPC_queue then when M4 gets first message from M0 after booting M0 the M4 goes to some unknown location or to hard fault handler.
Could you please send me some code you were running in EA4357 just for testing the IPC and RIT timer without RTOS. Thank you in advanced.
Maciek

LPC43xx Dual Core Application

the problem i had was solved by doing followning actions: 1) in lpcexpresso M0/M4 projects configure MCU settings to use different RAM memory regions. proviously M0/M4 were using the same ram and i got hard faults. that allowed me to run M0 from M4 2) change the way of debugging – by using debugger in lpcxpresso i thought i was running the code on M0 but in fact i did it on M4. in order to do it properly configure your Launch configuration for M0 so that it not Load the image to target “Load image” = FALSE @ Launch Configuration->Debugger->Script Values. Then i load both codes on M0/M4 with flasher and while running the code jump into M0 code with debugger – in this way M4 always runs M0 at startup 3) configure timer in M4 and just enable/disable its interrupt in M0. I was not able to configure timer at the M0 (rit or timer0). I don’t know why yet but probably i forgot about something. 4) IPC example on queues did not work. it stopped after the second message recieved from M0. so i decided to simplify that and used IPC interrupts only and made my own communication structure which i located in shared memory space:
CORE_DATA* const coreMasterData = (CORE_DATA*) MASTER_BLOCK_START;
CORE_DATA* const coreSlaveData = (CORE_DATA*) SLAVE_BLOCK_START;
typedef struct {
    Bool        busy;
    uint32_t    cmd;
    uint32_t    param;
}CORE_DATA;
void slaveInterruptCallback(void) {
    command = coreMasterData->cmd;
    parameter = coreMasterData->param;
    switch(command) {
    case ...

        break;
    case ...

        break;
    default:
        break;
    }
    coreSlaveData->cmd = command;
    coreSlaveData->param = parameter;
    IPC_resetIntFlag();
    IPC_sendInterrupt();    //send reply immediately
    return;
}
Status cM4send(uint32_t cmd, uint32_t param) {
    if(coreMasterData->busy) {
        return ERROR;
    }
    coreMasterData->param = param;
    coreMasterData->cmd = cmd;
    coreMasterData->busy = TRUE;
    IPC_sendInterrupt();
    //set some custom timer to wait max time for reply from M0
    return SUCCESS;
}
i don’t know the reson why the eample on queues did not work longterm, probably i did something wrong but for first setup this simple data handling is enough for me. that should be all. mostly the strange things i got was due to the common ram between cores. I hope that helps to somone in solving dual core startup problems

LPC43xx Dual Core Application

Hi, @maszup, could you please share an empty project  with communication between M4/M0, and/or FreeRTOS aps? Thanks.