problem with mcc_recv_nocopy

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

problem with mcc_recv_nocopy

2,025 Views
christianedhofe
Contributor I

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

0 Kudos
Reply
8 Replies

1,515 Views
timesyssupport
Senior Contributor II

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

0 Kudos
Reply

1,515 Views
christianedhofe
Contributor I

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:

a5.png

M4 screen shot:

m4.png

0 Kudos
Reply

1,515 Views
timesyssupport
Senior Contributor II

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

1,515 Views
christianedhofe
Contributor I

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                 |

|---------------------------------------------------------------------------------|

0 Kudos
Reply

1,515 Views
timesyssupport
Senior Contributor II

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:

http://www.freescale.com/webapp/Download?colCode=FSLMQXOS_4_0_2_GA&appType=license&location=null&Par...

Can you try rebuilding your application using this, and let me know if the timing improves.

Thanks,

Timesys Support

0 Kudos
Reply

1,515 Views
johannestraxler
Contributor III

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!

1,515 Views
timesyssupport
Senior Contributor II

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

0 Kudos
Reply

1,515 Views
karina_valencia
NXP Apps Support
NXP Apps Support

timesyssupport can you attend this case?

0 Kudos
Reply