I try to run a program on the M4 core.
On the dual core A7 runs WEC2013 Image 1.1.
I cloned the FreeRTOS repository and opened the hello_world example project.
I can build and debug the project (more precisely I can debug the .axf file).
After that I created a .elf file from the .axf file with the fromelf tool.
Now if I want to start the .elf file from the A7 core, it doesn’t work.
In march @luka.tx has send me a .elf file which is working.
I compared the two .elf files and there is a difference.
I uploaded a .zip archive where you can find the .elf files (see rpmsg_pingpong_freertos.elf and hello_world_imx7_colibri_m4.elf).
The .elf file was created with the following command:
Both files do not work.
I think that in the “good” file rpmsg_pingpong_freertos.elf the program starts at adress 0x2000.
Is there anything wrong in the fromelf command? Do I have to specify other options?
Or is it the wrong scatter file?
In the archive file you can also find some screenshots from my DS-5 preferences.
But I changed nothing in there so these are the defaults from toradex.
The following modified FreeRtos code worked for me to build/run the HelloWorld application:
colibri-imx7-m4-freertos-v8_Modified.zip Edit: the link above accidentially contains unmodified files. The link with modified files is provided in a comment further down
However, there still seems to be a pending issue: if I insert a malloc() into the code, the M4 freezes somewhere in the malloc() implementation. We will look into this.
But the Rpmsg_Open() function never returns and the iMX7 freezes. But only with the simple hello world application.
If I build the rpmsg_freertos_ping_pong with the new project settings and start it with the above code, the Rpmsg_Open() function returns and the application works.
Is there another way to start an m4 application using WEC2013?
I use the same code as you do, but I modified the RpmsgLib to solve the problems you described. These modifications will be part of the next library release V2.3.
Reason:
The RpMsg protocol uses the iMX7’s hardware messaging unit MU-A. There’s two library problems around this peripheral:
The clock of this MU-A is only enabled from the M4 side.
The MU-A unit is not reset upon starting the M4 code
The Hello World example does not use messaging, and therefore does not initialize the MU-A unit, nor does it read any pending messages from this unit.
The Rpmsg_Open() V2.2 tries to read the status of the MU-A unit and hence freezes, as its clock is disabled.
Even if the clock is enabled, Rpmsg_Open() tries to send a message to the M4 and in this process it waits until the A7-to-M4 buffer is empty. This works for the first start, but waits forever in the 2nd run.
If you need an urgent fix, I can send you a preliminary version of the libraries.
Before I investicate more on this: Is the Hello World application running in OCRAM the starting point you will choose?
I can imagine that the failure depends on the chosen memory mapping, so I would like to debug this as close as possible to your real configuration.
I made some tests with both scatterfiles (ocram and tcm).
Debugging in tcm region is much better. I can see variables and tasks in my debug view which i didn’t see while debugging in ocram.
Also malloc and memcpy seems to be working.
However there is a problem while calling xQueueReceive (in tcm and ocram region).
I can create the message queue but receiving frames with the function leads to a hard fault.
Maybe it is better to do the adaptions in tcm region scatter file so that I can create release of the application and run it from A7 core.
I dis some additional investigations, and basically found 3 issues around the malloc problem:
M4 reset sequence
M4 cache
Scatter file
M4 Reset Sequence
The reset sequence used in the RpmsgLib V2.2 does only reset the M4 core, but not the whole M4 platform. This leaves the LMEM memory controller and M4 caches in an undefined state.
For a restart, the A7 updated code and data, but this does not update the M4 cache content. Therefore, after an M4 reset, I suspect that the M4 is reading instructions and data partially from the outdated cache, not from the actual RAM which was modified by the A7 before.
The next release V2.3 of the RpMsgLib will do a proper M4 platform reset.
M4 cache
Not all debug solutions take cache memory into account. Therefore it can happen that variables or memory dumps shown in the debugger don’t reflect the actual values.
To make sure to get consistent information, you might want to disable the M4 instruction / data caches by clearing the ENCACHEbit in the LMEM_PCCCR and LMEM_PSCCR registers.
Unfortunately this has an impact on the software performance.
Scatter file
There were 2 issues in the scatter files:
The reset vector and stack pointer is placed at 0x1fff8000 instead of 0x00000000. This requires the loader on the A7 core to copy the vectors into the correct location, before starting the M4 core. As far as I could see, this is properly handled by the RpMsgLib, so not really an issue.
Too much space is allocated for global variables. if >30kB of variables are declared, they overlap with the heap and the stack
The correct scatterfile for using the TCM memories looks as follows (initial comments stripped):