Hi,
I'm working with the PHYTEC Cosmic+ Board and I just want to send data from the A5 core to the M4 core and vice versa. Additionally, I would like to save the message from the M4 core to a textfile.
With the function "mcc_recv_copy" everything works fine, but when I'm trying to use "mcc_recv_nocopy" it doesn't.
This is what I've got for the A5 core:
int main()
{
int ret_value; // Variable ob Funktionen richtig ausgeführt wurden
int u = 0; // Zählvariable
float senddata = 1.2345; // Sendenachricht
void* recv_buffer_ptr;
void* app_buffer_ptr[255];
// Endpoint-Definition
MCC_ENDPOINT linux_endpoint_a5 = {0,0,1};
MCC_ENDPOINT mqx_endpoint_m4 = {1,0,2};
MCC_MEM_SIZE num_available_msgs;
MCC_MEM_SIZE num_of_received_bytes;
printf("Hello, I'm A5.\n");
// MCC-Init
ret_value = mcc_initialize(MCC_MQX_NODE_A5);
if(0==ret_value)printf("MCCinit check\n");
else printf("MCCinit fail\n\n");
// Endpoint-Create
ret_value = mcc_create_endpoint(&linux_endpoint_a5, 1);
if(0==ret_value)printf("endpoint create check\n");
else printf("create fail\n\n");
// Textdatei fuer Zugriff oeffnen
txt = fopen("mcc_float_nocopy.txt", "a+"); // oeffnet txt
if (txt == NULL) // ueberprueft ob txt geoeffnet werden kann
{
printf("Fehler beim Oeffnen der Datei.");
return 1;
}
while(u<10) // 10 x
{
// send msg to M4
ret_value = mcc_send(&mqx_endpoint_m4, &senddata, sizeof(senddata)+1, 0xFFFFFF);
if(0==ret_value)printf("send check\n");
else printf("send fail\n\n");
// wait for msg
mcc_msgs_available(&linux_endpoint_a5, &num_available_msgs);
while(num_available_msgs==0)
{
mcc_msgs_available(&linux_endpoint_a5, &num_available_msgs);
}
// get msg
ret_value = mcc_recv_nocopy(&linux_endpoint_a5, (void**)&recv_buffer_ptr, &num_of_received_bytes, 0xFFFFFF);
if(0==ret_value)printf("receive check\n");
else printf("receive fail\n\n");
// copy msg
memcpy((void*)app_buffer_ptr, (void*)recv_buffer_ptr, num_of_received_bytes);
printf("%f\n", *((float*)app_buffer_ptr));
// free buffer
ret_value = mcc_free_buffer(recv_buffer_ptr);
if(0==ret_value)printf("free check\n");
else printf("free fail\n\n");
// Zeit + Nachricht von M4 in Textdatei schreiben
fprintf(txt, "%f\n", *((float*)app_buffer_ptr));
u++;
}
fclose(txt);
printf("Finish!!\n");
return 0;
}
And this for the M4 core:
void main_task(uint_32 node_num)
{
int ret_value;
float senddata = 1.2345;
void* recv_buffer_ptr;
void* app_buffer_ptr[255];
MCC_MEM_SIZE num_available_msgs;
MCC_MEM_SIZE num_of_received_bytes;
printf("Hello, I'm M4!\n\n");
// MCC Init & Endpoint Init
ret_value = mcc_initialize(MCC_MQX_NODE_M4);
if(0==ret_value)printf("MCCinit check\n");
else printf("MCCinit fail\n\n");
ret_value = mcc_create_endpoint(&mqx_endpoint_m4, 2);
if(0==ret_value)printf("endpoint create check\n");
else printf("create fail\n\n");
while(1)
{
// wait for msg
mcc_msgs_available(&mqx_endpoint_m4, &num_available_msgs);
while(num_available_msgs==0)
{
mcc_msgs_available(&mqx_endpoint_m4, &num_available_msgs);
}
// get msg
ret_value = mcc_recv_nocopy(&mqx_endpoint_m4, (void**)&recv_buffer_ptr, &num_of_received_bytes, 5000000);
if(0==ret_value)printf("receive check\n");
else printf("receive fail\n\n");
// copy msg
memcpy((void*)app_buffer_ptr, (void*)recv_buffer_ptr, num_of_received_bytes);
printf("%f\n", *((float*)app_buffer_ptr));
// free buffer
ret_value = mcc_free_buffer(recv_buffer_ptr);
if(0==ret_value)printf("free check\n");
else printf("free fail\n\n");
// send msg to A5
ret_value = mcc_send(&linux_endpoint_a5, &senddata, sizeof(senddata)+1, 5000000);
if(0==ret_value)printf("send check\n");
else printf("send fail\n\n");
}
}
I can free the buffer on the A5, but it doesn't free the buffer on the M4. And the message from the M4 doesn't get saved to the textfile.
Did I use the function "mcc_recv_nocopy" correct?
Best regards,
Christian
Hello Christian,
I attempted to reproduce on the Phytec Cosmic board, but was not successful. I used almost the exact same code you shared - and saw the message from M4 saved to the text file in Linux. Can you please double check all variables and macros defined in your source? If the issue persists, can you please share the full source code of both applications?
Thanks,
Timesys Support
Thanks Timesys Support for the quick response.
I double checked my program, but it still doesn't work properly. I didn't mention that I would like to examine the timing of the MCC. I did this with the mcc_recv_copy function and I would like to do the same with mcc_recv_nocopy, because I read that this function should be faster.
I also attached two screen shots of the outputs of both cores. I'm still wondering why the M4 is not able to free the buffer. And the program stops after nine repetitions but it should stop after ten. So I don't get the "Finish" message from the A5. Thanks again for your help.
Best,
Christian
Here is the full code for the A5:
/*
* zeit_nocpy_a5.c
*/
// Bibliotheken
#include <string.h>
#include "stdio.h"
#include "stdlib.h"
#include "libmcc.h"
#include "time.h"
#define MCC_MQX_NODE_A5 0
#define MCC_MQX_NODE_M4 0
FILE *txt;
int main()
{
int ret_value;
int u = 0;
float senddata = 1.2345;
float zeit;
void* recv_buffer_ptr_a5;
void* app_buffer_ptr_a5[255];
float blubb;
//void *p_recv_data; // void pointer
//p_recv_data = &recv_data; // Empfangspointer für nocopy
clock_t begin, end;
// Endpoint-Definition
MCC_ENDPOINT linux_endpoint_a5 = {0,0,1};
MCC_ENDPOINT mqx_endpoint_m4 = {1,0,2};
MCC_MEM_SIZE num_available_msgs;
MCC_MEM_SIZE num_of_received_bytes;
printf("Hello, I'm A5.\n");
// MCC-Init
ret_value = mcc_initialize(MCC_MQX_NODE_A5);
if(0==ret_value)printf("MCCinit check\n");
else printf("MCCinit fail\n\n");
// Endpoint-Create
ret_value = mcc_create_endpoint(&linux_endpoint_a5, 1);
if(0==ret_value)printf("endpoint create check\n");
else printf("create fail\n\n");
// for begin
printf("Eingabe:\n");
scanf("%f", &blubb);
txt = fopen("mcc_float_nocopy.txt", "a+");
if (txt == NULL)
{
printf("Fehler beim Oeffnen der Datei.");
return 1;
}
while(u<10) // 10 x
{
begin = clock(); // start time
// msg to M4
ret_value = mcc_send(&mqx_endpoint_m4, &senddata, sizeof(senddata)+1, 5000000);
if(0==ret_value)printf("send check\n");
else printf("send fail\n\n");
printf("%f\n", senddata);
// wait for msg
mcc_msgs_available(&linux_endpoint_a5, &num_available_msgs);
while(num_available_msgs==0)
{
mcc_msgs_available(&linux_endpoint_a5, &num_available_msgs);
}
// get msg
ret_value = mcc_recv_nocopy(&linux_endpoint_a5, (void**)&recv_buffer_ptr_a5, &num_of_received_bytes, 5000000);
if(0==ret_value)printf("receive check\n");
else printf("receive fail\n\n");
// copy msg
memcpy((void*)app_buffer_ptr_a5, (void*)recv_buffer_ptr_a5, num_of_received_bytes);
printf("%f\n", *((float*)app_buffer_ptr_a5));
// free buffer
ret_value = mcc_free_buffer(recv_buffer_ptr_a5);
if(0==ret_value)printf("free check\n");
else printf("free fail\n\n");
end = clock(); // end time
// time in seconds
zeit = end - begin;
zeit /= CLOCKS_PER_SEC;
// time and msg to textfile
fprintf(txt, "%f | %f\n", zeit, *((float*)app_buffer_ptr_a5));
u++;
}
fclose(txt);
printf("Finish!!\n");
return 0;
}
Code for the M4:
/*
* zeit_nocpy_m4.c
*/
#include <mqx.h>
#include <bsp.h>
// Multi-Core Communication
#include "mcc_config.h"
#include "mcc_common.h"
#include "mcc_api.h"
#include "mcc_mqx.h"
#define MAIN_TASK 10
#define MCC_MQX_NODE_A5 0
#define MCC_MQX_NODE_M4 0
// FUNCTION PROTOTYPES
extern void main_task(uint_32);
// TASK Declaration
#if PSP_MQX_CPU_IS_VYBRID_M4
TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
// Task Index, Function, Stack, Priority, Name, Attributes, Param, Time Slice
{ MAIN_TASK, main_task, 2000, 9, "Main", MQX_AUTO_START_TASK, MCC_MQX_NODE_M4, 0 },
{ 0 }
};
#endif
MCC_ENDPOINT linux_endpoint_a5 = {0,0,1};
MCC_ENDPOINT mqx_endpoint_m4 = {1,0,2};
void main_task(uint_32 node_num)
{
int ret_value;
float senddata = 1.2345;
void* recv_buffer_ptr_m4;
void* app_buffer_ptr_m4[255];
//void *p_recv_datam4;
//p_recv_datam4 = &recv_data;
MCC_MEM_SIZE num_available_msgs;
MCC_MEM_SIZE num_of_received_bytes;
printf("Hello, I'm M4!\n\n");
// MCC Init & Endpoint Init
ret_value = mcc_initialize(MCC_MQX_NODE_M4);
if(0==ret_value)printf("MCCinit check\n");
else printf("MCCinit fail\n\n");
ret_value = mcc_create_endpoint(&mqx_endpoint_m4, 2);
if(0==ret_value)printf("endpoint create check\n");
else printf("create fail\n\n");
while(1)
{
// wait for msg
mcc_msgs_available(&mqx_endpoint_m4, &num_available_msgs);
while(num_available_msgs==0)
{
mcc_msgs_available(&mqx_endpoint_m4, &num_available_msgs);
}
// get msg
ret_value = mcc_recv_nocopy(&mqx_endpoint_m4, (void**)&recv_buffer_ptr_m4, &num_of_received_bytes, 5000000);
if(0==ret_value)printf("receive check\n");
else printf("receive fail\n\n");
// copy msg
memcpy((void*)app_buffer_ptr_m4, (void*)recv_buffer_ptr_m4, num_of_received_bytes);
printf("%f\n", *((float*)app_buffer_ptr_m4));
// free buffer
ret_value = mcc_free_buffer(recv_buffer_ptr_m4);
if(0==ret_value)printf("free check\n");
else printf("free fail\n\n");
// send msg
ret_value = mcc_send(&linux_endpoint_a5, &senddata, sizeof(senddata)+1, 5000000);
if(0==ret_value)printf("send check\n");
else printf("send fail\n\n");
}
}
A5 screen shot:
M4 screen shot:
Hi Christian,
Thanks for sharing your application source. I still was not able to reproduce after building your exact source and running on our Phytec Cosmic+. Are you using Timesys Web or Desktop Factory? If the former, can you share a link to your web build; or if the latter, can you share your Desktop Factory configuration (the .config file located in your top-level Factory directory). Also, what version of MQX are you using? Is it 4.0.2 for Linux hosts: http://www.freescale.com/webapp/Download?colCode=FSLMQXOS_4_0_2_GA&appType=license&location=null&Par... Have you made any other source modifications to Linux, MQX, or MCC?
If you are interested, here is the timing data that your program reported (from 2 runs):
0.002695 | 1.234500
0.003494 | 1.234500
0.003798 | 1.234500
0.003907 | 1.234500
0.003827 | 1.234500
0.003872 | 1.234500
0.003880 | 1.234500
0.003890 | 1.234500
0.003911 | 1.234500
0.003793 | 1.234500
0.002707 | 1.234500
0.003237 | 1.234500
0.003874 | 1.234500
0.003822 | 1.234500
0.003846 | 1.234500
0.003811 | 1.234500
0.003907 | 1.234500
0.003882 | 1.234500
0.003840 | 1.234500
0.003913 | 1.234500
Thanks,
Timesys Support
Thanks again for testing my code. I used the Web Factory for my build. I hope I got the right link: Embedded Linux software, platform, distributions, packages, libraries, development and debugging too... Additionally, I attached the Build Summary at the end on this post.
No, I am still using the MQX Version 4.0.1 and haven't made any other source modifications. Does is it only work with Version 4.0.2?
Thank you also for sharing the results. As I said I did this also with mcc_recv_copy and the average time of 10000 messages was about 650 microseconds. The data of the mcc_recv_nocopy bases only on 20 messages, but it seems that this function is much slower than the other. I'm surprised, because I thought the nocopy version would be faster. Do you have any experience with it?
Best,
Christian
Build Summary:
-- Reading configuration and build instructions -- 1405472503 [Tue, 15 Jul 2014 21:01:44 -0400]
Please wait, this will take some time...
-- Workorder Summary -- 1405472505 [Tue, 15 Jul 2014 21:01:45 -0400]
Timesys Factory (Released: 20140714)
System
|----------------------------------------|
| Board Name | pcl052 |
| Architecture | armv7l |
| Kernel Architecture | arm |
| Kernel Version | 3.0 |
| Package Output | |
|----------------------------------------|
Toolchain
|-------------------------------------------------------|
| Binutils | binutils | 2.24 |
| CC | gcc | 4.8.3 |
| libc | glibc | 2.18 |
| Debugger | gdb | 7.7 |
|-------------------------------------------------------|
Host Tools
|----------------------------------------|
| Package | Version |
|----------------------|-----------------|
| cross_scripts | |
| fakeroot | 1.14.4 |
| intltool | 0.41.1 |
| mkimage | 2011.12 |
| pkgconfig | 0.23 |
| ccache | 3.1.9 |
|----------------------------------------|
RFS Optimization Options
|---------------------------------------------|
| Option | Value |
|-------------------------------------|-------|
| Strip Libraries | y |
| Remove Man Pages | y |
| Remove Info Pages | y |
| Remove Development Headers | y |
| Remove static library files | y |
| Remove i18n | y |
| Remove locale | y |
| Remove zoneinfo | y |
| Remove gconv | y |
| Remove doc directories | y |
|---------------------------------------------|
RFS Output Formats
|--------------|
| tar |
|--------------|
Bootloader
|--------------------------------------------|
| Name | Version |
|-------------------------------|------------|
| u-boot | 2011.12 |
|--------------------------------------------|
Packages
|---------------------------------------------------------------------------------|
| Category | Package | Version | License |
|-------------|-------------------------------|------------|----------------------|
| System | busybox | 1.20.2.ts1 | GPLv2 |
| Utilities | bzip2 | 1.0.6 | BSD |
| Host Tools | gdbserver | 7.7 | GPLv3 |
| Utilities | libmcc | 1.04 | GPLv2 |
| Networking | libssh | 0.5.3 | LGPLv2.1 |
| Networking | lighttpd | 1.4.32 | BSD |
| Utilities | mcc-kmod | 1.05 | GPLv2 |
| Utilities | mqxboot | 1.0 | GPLv2 |
| Utilities | nano | 2.3.2 | GPLv3 |
| Graphics | ncurses | 5.9 | MIT |
| Networking | openssh | 6.6p1 | BSD |
| Networking | openssl | 1.0.1h | OpenSSL |
| Utilities | zlib | 1.2.8 | BSD |
|---------------------------------------------------------------------------------|
Hi Christian,
Great, thanks for the info. I would recommend using MQX 4.0.2 - this will likely solve your issue. In the future, you can put a version check string in your application to ensure you are using compatible versions of the MCC library. For example, in your Linux application source:
// initialize the sub-system | |
ret_value = mcc_initialize(THIS_NODE); | |
if (ret_value != MCC_SUCCESS) | |
{ | |
printf("CA5:Error: mcc_initialize error: %d for node: %d\n", ret_value, | |
THIS_NODE); | |
return ret_value; | |
} |
// verify compatible versions | |
ret_value = mcc_get_info(THIS_NODE, &mcc_info); | |
if (ret_value != MCC_SUCCESS) | |
{ | |
printf("CA5:Error: mcc_get_info error: %d for node: %d\n", ret_value, | |
THIS_NODE); | |
return ret_value; | |
} |
if (strcmp(mcc_info.version_string, MCC_VERSION_STRING) != 0) | |
{ | |
printf("CA5:Error: different versions of the MCC library on each core!\n"); | |
mcc_destroy(THIS_NODE); | |
return MCC_ERR_DEV; | |
} |
Here is the link to download MQX 4.0.2 sources:
Can you try rebuilding your application using this, and let me know if the timing improves.
Thanks,
Timesys Support
I also had problems with the MCC library of MQX 4.0.1 and I was affected by this bug described here: https://community.freescale.com/thread/320177
Maybe it's the same for your case! So what did I do? I downloaded the MQX 4.1.0 for Linux Beta, replaced the source files from there in my 4.0.1 directory and recompiled MCC. I know this might not exactly be a bulletproof solution, but I'm working on Phytec PCM052 platform and they haven't ported the new 4.1.0 BSP yet!
Hope this helps!
Hello Christian,
I was not able to reproduce this issue on the Vybrid Tower. I am currently creating a build for the Cosmic board; once this finishes, I will attempt to reproduce there. In the meantime, can you send all application sources and the output from running the application?
Thanks,
Timesys Support
timesyssupport can you attend this case?