This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM2634: How to send 512 bytes of data to another core

Part Number: AM2634
Other Parts Discussed in Thread: SYSCONFIG

hi Ti,

I am working on the am2634 mcu and in the i am working on the dual core r5fss0-0 and r5fss0-1 core in the i am trying to send 512 bytes of data to second core but we could not able to achieve but maximum i tired upto 255 bytes of data it is working fine.

below is my sysconfig configurations,
image 

can u say what i need to do?

  • Hi AK,

    Let me have a look and get back.

    Regards,
    Shaunak

  • Hi AK,

    Can you please share a snippet of your IPC syscfg section? What is the buffer size configured in syscfg and the application?

    Regards,
    Shaunak

  • Hi shaunak,

    I am working on am2634mcu below is mine sysconfig of both the core 


    core - 1


    core - 2




    sample code:


    sending from core - 1

    uint32_t gMainCoreId = CSL_CORE_ID_R5FSS0_0;
    uint32_t gRemoteCoreId=CSL_CORE_ID_R5FSS0_1;
    uint16_t gRemoteServiceEndPt = 13u;
     
    #define MAX_MSG_SIZE        (350)
    #define MAIN_CORE_ACK_REPLY_END_PT  (12U)
     
    extern RPMessage_Object gRecvMsgObject;
    extern RPMessage_CreateParams createParams;
    extern char recvMsg[MAX_MSG_SIZE];
    extern uint16_t recvMsgSize;
     
    uint8_t Rx_flag;
     
    void IPC_init(void);
    void ipc_send_receive_numbers_remote_core(void)
    {
        int32_t status;
        status = RPMessage_send(recvMsg, recvMsgSize, CSL_CORE_ID_R5FSS0_0, MAIN_CORE_ACK_REPLY_END_PT,
                                            RPMessage_getLocalEndPt(&gRecvMsgObject),
                                            SystemP_WAIT_FOREVER);
                    DebugP_assert(status == SystemP_SUCCESS);
    }


    sending from core - 2

    uint32_t gMainCoreId = CSL_CORE_ID_R5FSS0_0;
    uint32_t gRemoteCoreId= CSL_CORE_ID_R5FSS0_1;
    uint16_t gRemoteServiceEndPt = 13u;
    #define MAX_MSG_SIZE        (450)
    #define MAIN_CORE_ACK_REPLY_END_PT  (12U)
     
    RPMessage_Object gAckReplyMsgObject;
    char msgBuf[MAX_MSG_SIZE];
    uint8_t flag;
    uint8_t rx_flag;
    uint16_t msgBufsize;
    RPMessage_CreateParams createParams;
     
     
    void my_callback (RPMessage_Object *obj, void *arg,
       void *data, uint16_t dataLen, int32_t crcStatus,
       uint16_t remoteCoreId, uint16_t remoteEndPt)
    {
        memcpy(msgBuf,data,dataLen);
        msgBufsize=dataLen;
        rx_flag=1;
    }
     



    can you check from your side and please let us know, yours input is mostly welcome. Thank you.

  • Hi AK,

    I did the following in the out-of-box ipc_rpmsg_echo example and was able to achieve a transfer of larger buffer:

    1. In exampel.syscfg, for both cores, modify the buffer size to 512B (please note that the actual payload you can transfer is configures size - 16B), so I can transfer 512-16 = 496 Bytes of payload.

    2. In the application, change the msgBuf size to 512B, and populate that buffer

    3. Rebuild the example and test. I was able to see the data transfer happen as expected.

    In your code above, i see that the buffer size on core-0 is 350B and core-1 is 450B. Can you try increasing these to some other high value, for example 512B and try again? I also verified if correct data is being transmitted.

    For reference, im attaching my modified C file which i used for testing.

    /*
     *  Copyright (C) 2021 Texas Instruments Incorporated
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    #include <stdio.h>
    #include <string.h>
    #include <inttypes.h>
    #include <kernel/dpl/ClockP.h>
    #include <kernel/dpl/DebugP.h>
    #include <drivers/ipc_notify.h>
    #include <drivers/ipc_rpmsg.h>
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    /* This example shows message exchange between multiple cores.
     *
     * One of the core is designated as the 'main' core
     * and other cores are designated as `remote` cores.
     *
     * The main core initiates IPC with remote core's by sending it a message.
     * The remote cores echo the same message to the main core.
     *
     * The main core repeats this for gMsgEchoCount iterations.
     *
     * In each iteration of message exchange, the message value is incremented.
     *
     * When iteration count reaches gMsgEchoCount, the example is completed.
     *
     */
    
    /* number of iterations of message exchange to do */
    uint32_t gMsgEchoCount = 1u;
    
    #if defined(SOC_AM243X)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_M4FSS0_0,
        CSL_CORE_ID_R5FSS0_1,
        CSL_CORE_ID_R5FSS1_0,
        CSL_CORE_ID_R5FSS1_1,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    #if defined (SOC_AM263X) || defined (SOC_AM263PX)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_R5FSS0_1,
        CSL_CORE_ID_R5FSS1_0,
        CSL_CORE_ID_R5FSS1_1,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    #if defined(SOC_AM64X)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_M4FSS0_0,
        CSL_CORE_ID_R5FSS0_1,
        CSL_CORE_ID_R5FSS1_0,
        CSL_CORE_ID_R5FSS1_1,
        CSL_CORE_ID_A53SS0_0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    #if defined(SOC_AM273X) || defined(SOC_AWR294X)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_R5FSS0_1,
        CSL_CORE_ID_C66SS0,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    #if defined(SOC_AM261X)
    /* main core that starts the message exchange */
    uint32_t gMainCoreId = CSL_CORE_ID_R5FSS0_0;
    /* remote cores that echo messages from main core, make sure to NOT list main core in this list */
    uint32_t gRemoteCoreId[] = {
        CSL_CORE_ID_R5FSS0_1,
        CSL_CORE_ID_MAX /* this value indicates the end of the array */
    };
    #endif
    
    /*
     * Remote core service end point
     *
     * pick any unique value on that core between 0..RPMESSAGE_MAX_LOCAL_ENDPT-1
     * the value need not be unique across cores
     */
    uint16_t gRemoteServiceEndPt = 13u;
    
    /* maximum size that message can have in this example */
    #define MAX_MSG_SIZE        (512u)
    
    /* Main core ack reply end point
     *
     * pick any unique value on that core between 0..RPMESSAGE_MAX_LOCAL_ENDPT-1
     * the value need not be unique across cores
     */
    #define MAIN_CORE_ACK_REPLY_END_PT  (12U)
    
    /* RPMessage_Object MUST be global or static */
    RPMessage_Object gAckReplyMsgObject;
    
    void ipc_rpmsg_echo_main_core_start(void)
    {
        RPMessage_CreateParams createParams;
        uint32_t msg, i, numRemoteCores;
        uint64_t curTime;
        char msgBuf[MAX_MSG_SIZE];
        int32_t status;
        uint16_t remoteCoreId, remoteCoreEndPt, msgSize;
    
        for (uint16_t i=0; i<MAX_MSG_SIZE; i++)
        {
            msgBuf[i] = i;
        }
    
        RPMessage_CreateParams_init(&createParams);
        createParams.localEndPt = MAIN_CORE_ACK_REPLY_END_PT;
        status = RPMessage_construct(&gAckReplyMsgObject, &createParams);
        DebugP_assert(status==SystemP_SUCCESS);
    
        numRemoteCores = 0;
        for(i=0; gRemoteCoreId[i]!=CSL_CORE_ID_MAX; i++)
        {
            numRemoteCores++;
        }
    
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        ClockP_usleep(500*1000); /* wait for log messages from remote cores to be flushed, otherwise this delay is not needed */
    
        DebugP_log("[IPC RPMSG ECHO] Message exchange started by main core !!!\r\n");
    
        curTime = ClockP_getTimeUsec();
    
        for(msg=0; msg<gMsgEchoCount; msg++)
        {
            // snprintf(msgBuf, MAX_MSG_SIZE-1, "%" PRIu32, msg);
            // msgBuf[MAX_MSG_SIZE-1] = 0;
            // msgSize = strlen(msgBuf) + 1; /* count the terminating char as well */
    
            /* send the same messages to all cores */
            for(i=0; gRemoteCoreId[i]!=CSL_CORE_ID_MAX; i++ )
            {
                status = RPMessage_send(
                    msgBuf, msgSize,
                    gRemoteCoreId[i], gRemoteServiceEndPt,
                    RPMessage_getLocalEndPt(&gAckReplyMsgObject),
                    SystemP_WAIT_FOREVER);
                DebugP_assert(status==SystemP_SUCCESS);
            }
            /* wait for response from all cores */
            for(i=0; gRemoteCoreId[i]!=CSL_CORE_ID_MAX; i++ )
            {
                /* set 'msgSize' to size of recv buffer,
                * after return `msgSize` contains actual size of valid data in recv buffer
                */
                msgSize = sizeof(msgBuf);
                status = RPMessage_recv(&gAckReplyMsgObject,
                    msgBuf, &msgSize,
                    &remoteCoreId, &remoteCoreEndPt,
                    SystemP_WAIT_FOREVER);
                DebugP_assert(status==SystemP_SUCCESS);
            }
        }
    
        curTime = ClockP_getTimeUsec() - curTime;
    
        DebugP_log("[IPC RPMSG ECHO] All echoed messages received by main core from %d remote cores !!!\r\n", numRemoteCores);
        DebugP_log("[IPC RPMSG ECHO] Messages sent to each core = %d \r\n", gMsgEchoCount);
        DebugP_log("[IPC RPMSG ECHO] Number of remote cores = %d \r\n", numRemoteCores);
        DebugP_log("[IPC RPMSG ECHO] Total execution time = %" PRId64 " usecs\r\n", curTime);
        DebugP_log("[IPC RPMSG ECHO] One way message latency = %" PRId32 " nsec\r\n",
            (uint32_t)(curTime*1000u/(gMsgEchoCount*numRemoteCores*2)));
    
        RPMessage_destruct(&gAckReplyMsgObject);
    
        DebugP_log("All tests have passed!!\r\n");
    }
    
    /* RPMessage_Object MUST be global or static */
    static RPMessage_Object gRecvMsgObject;
    
    void ipc_rpmsg_echo_remote_core_start(void)
    {
        int32_t status;
        RPMessage_CreateParams createParams;
        char recvMsg[MAX_MSG_SIZE];
        uint16_t recvMsgSize, remoteCoreId, remoteCoreEndPt;
    
        RPMessage_CreateParams_init(&createParams);
        createParams.localEndPt = gRemoteServiceEndPt;
        status = RPMessage_construct(&gRecvMsgObject, &createParams);
        DebugP_assert(status==SystemP_SUCCESS);
    
        /* wait for all cores to be ready */
        IpcNotify_syncAll(SystemP_WAIT_FOREVER);
    
        DebugP_log("[IPC RPMSG ECHO] Remote Core waiting for messages from main core ... !!!\r\n");
    
        /* wait for messages forever in a loop */
        while(1)
        {
            /* set 'recvMsgSize' to size of recv buffer,
            * after return `recvMsgSize` contains actual size of valid data in recv buffer
            */
            recvMsgSize = sizeof(recvMsg);
            status = RPMessage_recv(&gRecvMsgObject,
                recvMsg, &recvMsgSize,
                &remoteCoreId, &remoteCoreEndPt,
                SystemP_WAIT_FOREVER);
            DebugP_assert(status==SystemP_SUCCESS);
    
            /* echo the same message string as reply */
    
            /* send ack to sender CPU at the sender end point */
            status = RPMessage_send(
                recvMsg, recvMsgSize,
                remoteCoreId, remoteCoreEndPt,
                RPMessage_getLocalEndPt(&gRecvMsgObject),
                SystemP_WAIT_FOREVER);
            DebugP_assert(status==SystemP_SUCCESS);
        }
        /* This loop will never exit */
    }
    
    void ipc_rpmsg_echo_main(void *args)
    {
        Drivers_open();
        Board_driversOpen();
    
        if(IpcNotify_getSelfCoreId()==gMainCoreId)
        {
            ipc_rpmsg_echo_main_core_start();
        }
        else
        {
            ipc_rpmsg_echo_remote_core_start();
        }
    
        Board_driversClose();
        /* We dont close drivers to let the UART driver remain open and flush any pending messages to console */
        /* Drivers_close(); */
    }
    

    Regards,
    Shaunak