From 1c782c2cab0c2a5ed50213f88b8c2918a1401014 Mon Sep 17 00:00:00 2001 From: yaoguangzhong Date: Fri, 7 Feb 2025 14:31:27 +0800 Subject: [PATCH] uniproton: add user and uniproton communication interface service umt add user and uniproton communication interface service umt Signed-off-by: Guangzhong Yao --- demos/kp920/CMakeLists.txt | 9 +- demos/kp920/apps/openamp/main.c | 8 ++ demos/kp920/config/prt_config.h | 2 +- src/component/mica/rpmsg_backend.h | 3 + src/component/mica/rpmsg_service.c | 118 +++++++++++++++++- testsuites/rhealstone/CMakeLists.txt | 3 + testsuites/rhealstone/rcv-data/rcv-data.c | 52 ++++++++ .../rhealstone/rcv-data/rpmsg_backend.h | 57 +++++++++ 8 files changed, 245 insertions(+), 7 deletions(-) create mode 100644 testsuites/rhealstone/rcv-data/rcv-data.c create mode 100644 testsuites/rhealstone/rcv-data/rpmsg_backend.h diff --git a/demos/kp920/CMakeLists.txt b/demos/kp920/CMakeLists.txt index 5845a3c2..bfaab3fe 100644 --- a/demos/kp920/CMakeLists.txt +++ b/demos/kp920/CMakeLists.txt @@ -79,13 +79,18 @@ if (${APP} MATCHES "kp920") list(APPEND OBJS $ $ $ $) add_executable(${APP} ${OBJS}) elseif (${APP} STREQUAL "task-switch" OR + ${APP} STREQUAL "rcv-data" OR ${APP} STREQUAL "task-preempt" OR ${APP} STREQUAL "semaphore-shuffle" OR ${APP} STREQUAL "interrupt-latency" OR ${APP} STREQUAL "deadlock-break" OR ${APP} STREQUAL "message-latency") add_subdirectory(${HOME_PATH}/testsuites/rhealstone tmp) - target_compile_options(rpmsg PUBLIC -DRHEALSTONE_TESTCASE) + if (${APP} STREQUAL "rcv-data") + target_compile_options(rpmsg PUBLIC -DRCV_TEST) + else() + target_compile_options(rpmsg PUBLIC -DRHEALSTONE_TESTCASE) + endif() list(APPEND OBJS $ $ $ $ $) add_executable(${APP} ${OBJS}) elseif (${APP} STREQUAL "linuxTest") @@ -98,4 +103,4 @@ elseif (${APP} STREQUAL "UniPorton_test_proxy_posix_interface") target_compile_options(rpmsg PUBLIC -DPOSIX_TESTCASE) list(APPEND OBJS $ $ $ $ $) add_executable(${APP} ${OBJS}) -endif() \ No newline at end of file +endif() diff --git a/demos/kp920/apps/openamp/main.c b/demos/kp920/apps/openamp/main.c index 582c4eee..c6589710 100644 --- a/demos/kp920/apps/openamp/main.c +++ b/demos/kp920/apps/openamp/main.c @@ -24,6 +24,10 @@ extern U64 g_timerFrequency; void Init(uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4); #endif +#if defined(RCV_TEST) +extern rcv_test(); +#endif + #if defined(OS_OPTION_LINUX) && defined(LINUX_TESTCASE) void kthreadTest(void); void schedTest(void); @@ -88,6 +92,10 @@ void TestTaskEntry() TestOpenamp(); #endif +#if defined(RCV_TEST) + rcv_test(); +#endif + #if defined(POSIX_TESTCASE) || defined(RHEALSTONE_TESTCASE) printf("TESTCASE TestTaskEntry(Freq:%llu)\r\n", g_timerFrequency); Init(0, 0, 0, 0); diff --git a/demos/kp920/config/prt_config.h b/demos/kp920/config/prt_config.h index de32f6f9..9710b1cf 100644 --- a/demos/kp920/config/prt_config.h +++ b/demos/kp920/config/prt_config.h @@ -78,7 +78,7 @@ extern "C" { #define OS_MEM_FSC_PT_ADDR (uintptr_t)&g_memRegion00[0] /* 私有FSC内存分区大小 */ #if defined(OS_OPTION_RSC_TABLE) -#define OS_MEM_FSC_PT_SIZE 0x80000 +#define OS_MEM_FSC_PT_SIZE 0x200000 /* 程序运行堆空间大小,为满足数据传输buffer malloc可申请1M空间大小,将堆空间修改为2M */ #else #define OS_MEM_FSC_PT_SIZE 0x60000000 #endif diff --git a/src/component/mica/rpmsg_backend.h b/src/component/mica/rpmsg_backend.h index a92e2223..34ab8408 100644 --- a/src/component/mica/rpmsg_backend.h +++ b/src/component/mica/rpmsg_backend.h @@ -49,6 +49,9 @@ extern void receive_message(void); /* 下线时,设置rsc_table的reserved[1]为CPU_OFF_FUNCID,告诉mica侧更新状态 */ extern void rsc_table_set_offline_flag(void); +extern int rcv_data_from_nrtos(void *rcv_data, int *data_len); +extern int send_data_to_nrtos(void *send_data, int data_len); + #ifdef __cplusplus } #endif diff --git a/src/component/mica/rpmsg_service.c b/src/component/mica/rpmsg_service.c index 1db4a806..0957c4d4 100644 --- a/src/component/mica/rpmsg_service.c +++ b/src/component/mica/rpmsg_service.c @@ -22,6 +22,12 @@ #include "shmsg.h" #endif #include "prt_config.h" +#include "../proxy/rpc_internal_model.h" + +typedef struct umt_send_msg { + unsigned long phy_addr; + int data_len; +} umt_send_msg_t; struct rpmsg_rcv_msg { void *data; @@ -44,6 +50,12 @@ static SemHandle tty_sem; static struct rpmsg_endpoint tty_ept; static struct rpmsg_rcv_msg tty_msg; +/* RPMsg umt */ +#define RPMSG_UMT_EPT_NAME "rpmsg-umt" +static SemHandle umt_sem; +static struct rpmsg_endpoint umt_ept; +static struct rpmsg_rcv_msg umt_msg; + char *g_s1 = "Hello, UniProton! \r\n"; extern char *g_printf_buffer; @@ -163,6 +175,46 @@ err: pthread_exit(NULL); } +static int rpmsg_rx_umt_callback(struct rpmsg_endpoint *ept, void *data, + size_t len, uint32_t src, void *priv) +{ + struct rpmsg_rcv_msg *umt_msg = priv; + umt_send_msg_t *msg; + int ret = 0; + + rpmsg_hold_rx_buffer(ept, data); + umt_msg->data = data; + umt_msg->len = len; + msg = (umt_send_msg_t *)umt_msg->data; + + if(msg->phy_addr) + PRT_SemPost(umt_sem); + else + rpmsg_release_rx_buffer(ept, data); + return 0; +} + +static void *rpmsg_umt_task(void *arg) +{ + int ret; + ret = PRT_SemCreate(0, &umt_sem); + if (ret != OS_OK) { + PRT_Printf("[openamp] failed to create umt sem\n"); + goto err; + } + PRT_Printf("[openamp] umt task started\n"); + umt_ept.priv = &umt_msg; + ret = rpmsg_create_ept(&umt_ept, rpdev, RPMSG_UMT_EPT_NAME, + RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, + rpmsg_rx_umt_callback, NULL); + if (ret != 0) { + PRT_Printf("[openamp] umt endpoint ret:%d \n", ret); + goto err; + } +err: + pthread_exit(NULL); +} + static void *rpmsg_listen_task(void *arg) { /* Waiting for messages from host */ @@ -173,11 +225,63 @@ static void *rpmsg_listen_task(void *arg) return NULL; } +/** + * @brief 接收来自nrtos的传输数据内容。 + * + * @param rcv_data 指向接收数据的缓冲区的指针。调用者应确保缓冲区已分配足够的内存。 + * @param data_len 指向接收数据长度的指针。调用者应提供一个整型变量的地址,用于存储接收到的数据长度。 + * + * @return 返回值表示函数执行结果。 + * - 0 表示成功接收数据。 + * - -1 值表示接收失败。 + */ +int rcv_data_from_nrtos(void *rcv_data, int *data_len) +{ + umt_send_msg_t *msg; + + PRT_SemPend(umt_sem, OS_WAIT_FOREVER); + if(umt_msg.len) { + msg = (umt_send_msg_t *)umt_msg.data; + memcpy(rcv_data, (void *)msg->phy_addr, msg->data_len); + *data_len = msg->data_len; + rpmsg_release_rx_buffer(&umt_ept, umt_msg.data); + return OS_OK; + } + + return OS_ERROR; +} + +/** + * @brief 发送数据到nrtos。 + * + * @param send_data 指向发送数据内容的指针。调用者应确保该缓冲区包含要发送的数据。 + * @param data_len 要发送的数据长度。调用者应提供实际要发送的数据长度。 + * + * @return int 返回值表示函数执行结果。 + * - 0 表示成功发送数据。 + * - -1 表示发送失败。 + */ +int send_data_to_nrtos(void *send_data, int data_len) +{ + int ret; + + if (data_len > MAX_STRING_LEN) + return OS_ERROR; + + ret = rpmsg_send(&umt_ept, send_data, data_len); + if (ret < 0) { + PRT_Printf("send_data_to_nrtos failed ret %d data_len %d\n", ret, data_len); + return OS_ERROR; + } + + return OS_OK; +} + int rpmsg_service_init(void) { - int ret0, ret1, ret2; + int ret0, ret1, ret2, ret3; pthread_attr_t attr; - pthread_t rpc_thread, tty_thread, listen_thread; + pthread_t rpc_thread, tty_thread, listen_thread, umt_thread; /* init rpmsg device */ rpdev = rpmsg_backend_init(); @@ -201,10 +305,11 @@ int rpmsg_service_init(void) ret0 = pthread_create(&rpc_thread, &attr, rpmsg_rpc_task, NULL); ret1 = pthread_create(&tty_thread, &attr, rpmsg_tty_task, NULL); ret2 = pthread_create(&listen_thread, &attr, rpmsg_listen_task, NULL); + ret3 = pthread_create(&umt_thread, &attr, rpmsg_umt_task, NULL); pthread_attr_destroy(&attr); - if (ret0 != 0 || ret1 != 0 || ret2 != 0) { + if (ret0 != 0 || ret1 != 0 || ret2 != 0 || ret3 != 0) { /* If no rpmsg tasks, release the backend. */ - PRT_Printf("[openamp] create task fail, %d/%d/%d\n", ret0, ret1, ret2); + PRT_Printf("[openamp] create task fail, %d/%d/%d/%d\n", ret0, ret1, ret2, ret3); goto err; } #if defined(OS_OPTION_SMP) @@ -218,6 +323,11 @@ int rpmsg_service_init(void) while (!is_rpmsg_ept_ready(&rpc_ept)) { PRT_TaskDelay(100); } + + while (!is_rpmsg_ept_ready(&umt_ept)) { + PRT_TaskDelay(100); + } + PRT_Printf("[openamp] ept ready\n"); rpmsg_set_default_ept(&rpc_ept); diff --git a/testsuites/rhealstone/CMakeLists.txt b/testsuites/rhealstone/CMakeLists.txt index 0d334eba..77aa07c0 100755 --- a/testsuites/rhealstone/CMakeLists.txt +++ b/testsuites/rhealstone/CMakeLists.txt @@ -23,6 +23,9 @@ elseif(${CONFIG_LOSCFG_SHELL_TEST}) list(REMOVE_ITEM ALL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/support/banchmark_support.c ) +elseif(${APP} STREQUAL "rcv-data") + set(BUILD_APP "rcv-data") + set(ALL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/rcv-data/rcv-data.c) else() return() endif() diff --git a/testsuites/rhealstone/rcv-data/rcv-data.c b/testsuites/rhealstone/rcv-data/rcv-data.c new file mode 100644 index 00000000..62c24d61 --- /dev/null +++ b/testsuites/rhealstone/rcv-data/rcv-data.c @@ -0,0 +1,52 @@ +#include +#include +#include "tmacros.h" +#include "timesys.h" +#include "prt_hwi.h" + +#include + +#define STR_SIZE 1024*1024 + +TskHandle taskId; +U32 status; + + +void Task01(uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4) +{ + char msg[] = "rtos rcv ok"; + char *buffer = NULL; + int data_len = 0; + int ret; + + buffer = (char*)malloc(STR_SIZE + 1); + + while(1) { + memset(buffer, 0, STR_SIZE + 1); + ret = rcv_data_from_nrtos(buffer, &data_len); + if (ret != 0) + break; + printf("rcv buffer %s data_len %d \n", buffer + STR_SIZE - 10, data_len); + send_data_to_nrtos(msg, sizeof(msg)); + } + + return; +} + +void rcv_test() +{ + struct TskInitParam param = { 0 }; + + param.taskEntry = (TskEntryFunc)Task01; + param.stackSize = 0x800; + param.name = "TA01"; + param.taskPrio = OS_TSK_PRIORITY_05; + param.stackAddr = 0; + + status = PRT_TaskCreate(&taskId, ¶m); + directive_failed(status, "PRT_TaskCreate of TA01"); + + status = PRT_TaskResume(taskId); + directive_failed(status, "PRT_TaskResume of TA01"); + +} \ No newline at end of file diff --git a/testsuites/rhealstone/rcv-data/rpmsg_backend.h b/testsuites/rhealstone/rcv-data/rpmsg_backend.h new file mode 100644 index 00000000..edfe9908 --- /dev/null +++ b/testsuites/rhealstone/rcv-data/rpmsg_backend.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * UniProton is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * See the Mulan PSL v2 for more details. + * Create: 2023-11-20 + * Description: openamp backend + */ + +#include "openamp/open_amp.h" +#include "openamp_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RPMSG_VIRTIO_CONSOLE_CONFIG \ + (&(const struct rpmsg_virtio_config) { \ + .h2r_buf_size = 512, \ + .r2h_buf_size = 512, \ + .split_shpool = false,\ +}) + +extern int rpmsg_service_init(void); + +extern void (*g_rpmsg_ipi_handler)(void); + +/** + * rpmsg_backend_init - register rpmsg-virtio-device. + * + * Return: pointer of rpmsg_device(rpdev) on success, NULL on failure. + */ +extern struct rpmsg_device *rpmsg_backend_init(void); + +/** + * rpmsg_backend_remove - remove the backend + */ +extern void rpmsg_backend_remove(void); +/** + * receive_message - Call it to receive messages from host(linux) + */ +extern void receive_message(void); + +/* 下线时,设置rsc_table的reserved[1]为CPU_OFF_FUNCID,告诉mica侧更新状态 */ +extern void rsc_table_set_offline_flag(void); + +extern int rcv_data_from_rtos(void *rcv_data, int *data_len); +extern int send_data_to_fos(void *send_data, int data_len); + +#ifdef __cplusplus +} +#endif -- Gitee