M4 & M0 cores communication via SDRAM or IPC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

M4 & M0 cores communication via SDRAM or IPC

1,173 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maszup on Sat Apr 13 15:18:14 MST 2013
I'm begginer using LPC4357 with lpcxpresso and dual core. i have made both axf files and upladed them to both cores flash.

I'm trying to synchronize both cores in my software.

First i decided to try using SDRAM. M4 is reading first 4bytes of SDRAM and M0 is writing to that bytes but M4 goes immediately to Hard Fault. I don't know if it is possible to read & write SDRAM with two cores in the same time?

//M4

uint32_t *temp = (uint32_t*)SDRAM_BASE;

while(1) {

sprintf(buff, "value = %d\r\n", temp[0]);

console_sendString(buff);

TIM_Waitms(1000);

}



//M0

uint32_t *temp = (uint32_t*)SDRAM_BASE;

uint32_t idx =0;

while(1) {

  temp[0] = idx++%100000;

}

but on cosole i get some rubbish like "<0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0>" and console stops, probably M4 goes to hard fault . WHat is going on here?



Then i thought of using IPC but i do not have examples under LPCxpresso only under Keil. The example of IPC is nice but it is using M0 image read from CM0_image.c file  and M4 is uploading this image to M0. I do not know how to generate such a file in LPCxpresso. The examples is here:

http://www.lpcware.com/content/nxpfile/an11177-inter-processor-communication-lpc43xx
0 Kudos
10 Replies

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maszup on Fri Apr 26 00:14:06 MST 2013
2013-04-25 23:58:58 PDT

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 {
Boolbusy;
uint32_t cmd;
uint32_tparam;
}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
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maszup on Fri Apr 19 02:13:34 MST 2013
Hello


I'm trying to run a simple IPC communication between M4 and M0.

I have LPC4357 Embedded Artists EVB running

http://www.embeddedartists.com/products/kits/lpc4357_kit.php

under LPCxpresso (v5.1.2.2065 - recently downloaded).



I have found example of IPC dual core using queues for LPC4357 cpu (without RTOS):

http://www.lpcware.com/content/nxpfile/an11177-inter-processor-communication-lpc43xx

directly here:

http://sw.lpcware.com/?p=lpc43xx.git;a=tree;f=Examples/DUALCORE/Queue_Demo;h=397e0b718c31c4629070190...

where in API file (IPC_queue.c) i changed only the interrupt functions to 

/* interrupt function for the Slave queue */
void M0_M4CORE_IRQHandler(void) {
LPC_CREG->M4TXEVENT = 0x0;
cmdPending = PENDING;
}

/* interrupt function setting the flags for the application */
/* interrupt to master from slave */
void M0CORE_IRQHandler() {
LPC_CREG->M0TXEVENT = 0x0;
msgPending = PENDING;
}



So...

I have put the code of M0 into its default flash address 0x1b000000. then I'm debugging M4 in following order:

1. M4 boots and runs SystemInit();

2. M4 goes directly to function  cM4restart();

3. There M4 halts slave, configure IPC queue, set M0 shadow register and starts up M0 (I do not load M0's image since it is already loaded into flash)

4. M4 waits for 1st msg from M0 - it gets it

5. M4 checks the 1st msg - status is SUCCESS - everything seems to be fine

6. M4 tries to return from function cM4restart() - it hangs! debugger goes to some unkown address of M0's flash memory 0x1b000338

I have also debugged that M4 enters the  M0CORE_IRQHandler() so it gets the interrupt from M0.


I already switched off everything in my code leaving only IPC. Previously I had used  UART for debugging, systick in M4 for measuring time in M4, Timer0 in M0 for measuring time in M0. But then i had hard faults in M4. so i left only IPC and tried to debug.

I presume that something is going wrong with interrupts but I'm not sure.

I don't know if below addresses are OK:

/* these addresses specify where the IPC queues shall be located */
#define MASTER_CMD_BLOCK_START 0x20008000
#define SLAVE_MSG_BLOCK_START 0x2000A000

and that the interrupts of IPC have priority = 0.



[B]I have attached exported project from LPCxpresso.[/B]


Below is my cM4restart() function:

void cM4restart(void) {
Status status = ERROR;

IPC_haltSlave();
//lpc_printf("%010d Core M0 stopped\r\n",rtcGetTime_ms());

// setup the queue system
IPC_masterInitQueue(&_hostCmdBufferData[0], MASTER_CMDBUF_SIZE, &_hostMsgBufferData[0], SLAVE_MSGBUF_SIZE);
//lpc_printf("%010d Core M4 IPC initialized\r\n", rtcGetTime_ms());

// Set M0's vector table to point to start of M0 image
LPC_CREG->M0APPMEMMAP = 0x1B000000;//(unsigned int)&CM0image_start;
//lpc_printf("%010d Core M0 shadow register 0x%X\r\n", rtcGetTime_ms(), LPC_CREG->M0APPMEMMAP);

IPC_startSlave();
//lpc_printf("%010d Core M0 started\r\n",rtcGetTime_ms());

// wait for the M0 to signal being ready via a message to the command queue
while(!IPC_msgPending())
__WFI();
//lpc_printf("%010d Core M0 IPC ready\r\n", rtcGetTime_ms(),qstatus);

qstatus = IPC_masterPopMsg(&msgBack);
if(qstatus == QVALID) {

msgType = IPC_getMsgType((msgToken*)&msgBack);
if(msgType == MSG_SRV) {
serviceMessage = (srvMsg*) &msgBack;
taskId = serviceMessage->msgClass.parsedMsg.servicingAnswer.id;
statusInfo = serviceMessage->msgClass.parsedMsg.servicingAnswer.ss;

if(taskId == CORE_TASK_INIT && statusInfo) {
//lpc_printf("%010d Core M0 initialized\r\n", rtcGetTime_ms());
status = SUCCESS;
} else {
//err
}
} else {
//err
}
} else {
//err
}

} //here the function does not return - program goes to undefined address


Thank you for any kind of help
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Mon Apr 15 08:28:12 MST 2013
Did you read the Code Red FAQ?
http://support.code-red-tech.com/CodeRedWiki/LPC43DualCoreProjects
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maszup on Mon Apr 15 08:16:45 MST 2013
sorry, i do not ask to debug my own code. i only asked to take a look, but my main question was how to make the binary image of M0 software in LPCxpresso.
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Mon Apr 15 02:41:20 MST 2013
Why not debug you own hard fault, rather than asking somebody else to do it for you?
http://support.code-red-tech.com/CodeRedWiki/DebugHardFault
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by frame on Mon Apr 15 02:26:59 MST 2013
I've got to throw in the towel here, because I neither use LPC43xx dual cores, nor do I use
the LPCXpresso IDE for this kind of development.

And things like organising the code download to the proper core, and debug support
for this setup does much depend on the IDE.

Do you know which of the cores throws the hardfault ?
You can try to implement Joseph Yiu's hardfault handler code, to backtrace the fault.

Why not using Keil ?
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maszup on Mon Apr 15 02:08:19 MST 2013
anyway i would like to try. as I said I am beginner in LPC but not in embedded and especially not in programming. i could start with example of IPC if someone could tell me how to build the image of M0 in LPCxpresso.

in fact in M0 i would like to make fast acquisition of ADC and writing the samples to SDRAM and in M4 i would like to pass the samples further to USB PC application.

M0 and M4 will only use the same SDRAM hardware.

I have attached my functions of communication between cores using SDRAM. i have used beggining of SDRAM to pass the pointer to a structure from M4 to M0:

typedef struct {
CORE_COMM_STAT status;
CORE_COMM_CMD cmd;
uint32_t size;
uint32_t data[512];
}coreDataType;


M4 writes commands and data and set status, M0 read status, command and data, set status (pending), analyze cmd, then write back data and status, M4 read reply from M0.
IT SHOULD WORK!!!

but the only i got was Hard fault in M4

I tried also to point this structure directly to SDRAM memory and keep the structure content in SDRAM. the same result.

if someone could take a look into my code to see if there could be any crucial bug causing this hard fault.
Thanks
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by frame on Mon Apr 15 01:42:25 MST 2013

Quote:
How about Chapter 2 in the User Manual:
LPC43xx ARM Cortex-M0 co-processor and Inter-Process Communication (IPC)

I can only recommend the same.
And to broaden your scope, tutorials about multithreaded programming are helpful too.

But generally, such an assymetric multicore MCU is definitely not the right thing for a beginner.
The concept of concurrency, even of pseudo-concurrency (multithreading) is lost on a lot of people.
As those systems tend to provoke the worst kind of bugs, like race conditions, and are difficult to debug.

For a private project, I would postpone such stuff until sufficiently proficient.

For a commercial project, you will definitely need someone really experienced in this field for help,
or it going to be a recipe for disaster.
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by maszup on Sun Apr 14 02:47:08 MST 2013
i have tried one example of IPC but it is for Keil not for LPCxpresso, and there they load M0 image from M4. I don't know how to do it. in LPCxpresso i can't see the option of making this image.
0 Kudos

874 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Sun Apr 14 02:21:23 MST 2013
How about Chapter 2 in the User Manual:
LPC43xx ARM Cortex-M0 co-processor and Inter-Process Communication (IPC)
[FONT=sans-serif]
[/FONT]

http://www.nxp.com/documents/user_manual/UM10503.pdf
0 Kudos