/* * 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 #include #include #include #include #include #include #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 = 1000u; #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_R5FSS1_0; /* remote cores that echo messages from main core, make sure to NOT list main core in this list */ uint16_t gRemoteCoreId[] = { 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 (64u) /* 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) #define REMOTE_CORE_END_PT (16U) #define SHARED_MEM_ADDR 0x70180000 //共享内存地址 #define SHARED_MEM_SIZE (1024*10) //10k #define DATA_BUFFER_SIZE (1024) /* 消息结构体 */ struct __attribute__((__packed__)) ipc_buf { uint32_t addr; /* 共享内存物理地址 */ uint32_t size; /* 缓冲区大小 */ uint32_t pattern; /* 模式 */ uint8_t data[DATA_BUFFER_SIZE]; }; /* RPMessage_Object MUST be global or static */ RPMessage_Object gAckReplyMsgObject; /* 填充缓冲区 */ void buffer_init(uint32_t *buf, uint32_t size, uint32_t pattern) { for (uint32_t i = 0; i < size / sizeof(uint32_t); i++) { buf[i] = pattern; } CacheP_wb(buf, size, CacheP_TYPE_ALLD); /* 写回缓存 */ DebugP_log("r5fss1-0:Buffer @%p (size %d) filled with pattern 0x%08x\r\n", buf, size, pattern); } /* 验证缓冲区 */ int buffer_validate(uint32_t *buf, uint32_t size, uint32_t pattern) { CacheP_inv(buf, size, CacheP_TYPE_ALLD); /* 失效缓存 */ for (uint32_t i = 0; i < size / sizeof(uint32_t); i++) { if (buf[i] != pattern) { DebugP_log("r5fss1-0:Validation error at %p: expected 0x%08x, got 0x%08x\r\n", &buf[i], pattern, buf[i]); return -1; } } DebugP_log("r5fss1-0:Buffer validated successfully with pattern 0x%08x\r\n", pattern); return 0; } void ipc_rpmsg_echo_main_core_start(void) { int32_t status; struct ipc_buf ibuf; uint16_t msgSize; uint32_t *shared_buf = (uint32_t *)SHARED_MEM_ADDR; uint32_t pattern = 0xAAAA5555; /* 示例模式 */ RPMessage_CreateParams createParams; uint32_t msg, i, numRemoteCores; uint64_t curTime; char msgBuf[MAX_MSG_SIZE]; uint32_t remoteCoreId, remoteEndPt; 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); buffer_init(shared_buf, SHARED_MEM_SIZE, pattern); /* 准备消息 */ ibuf.addr = SHARED_MEM_ADDR; ibuf.size = SHARED_MEM_SIZE; ibuf.pattern = pattern; DebugP_log("[r5fss1-0:] Message exchange started by main core !!!\r\n"); DebugP_log("ibufsize=%d\n",sizeof(ibuf)); curTime = ClockP_getTimeUsec(); for(msg=0; msg