RTS 在windows和Linux之间ShareMem

如何在双系统之间用共享内存传递数据呢?

首先,我们要创建一个SHM块,在RTS的配置WindowsEFI_Linux64.txt中,找到Shared Memory添加一块SHM区,name为shm的唯一索引,size是大小

bash 复制代码
[/SHM/2]
    "name" = "data"
    "size" = uint64: 0x1000

需要重启整个RTS

rth -sysreboot

找到RTS的开发包,里面有API,需要利用到API的代码和动态链接库。以Linux为例,我们需要准备一台ubuntu24.0的机器,将API包拷贝到Ubuntu中

bash 复制代码
podman@podman:~$ tree -L 3 API
API
├── Linux
│   ├── apps
│   │   ├── eventPingPong
│   │   ├── shmAccessDemo
│   │   ├── shmDataExchangeDemo
│   │   └── tools
│   ├── include
│   │   └── libRth.h
│   ├── lib
│   │   ├── libRth64.so.1.1.0
│   │   └── libRth.so.1.1.0
│   └── readme.txt
└── Windows
    ├── apps
    │   ├── apps.sln
    │   ├── eventPingPong
    │   ├── rthTool
    │   ├── shmAccessDemo
    │   └── shmDataExchangeDemo
    ├── include
    │   └── libRth.h
    ├── lib
    │   ├── Win32
    │   └── x64
    └── readme.txt

我们需要把头文件和动态链接库放到系统目录里

bash 复制代码
sudo cp API/Linux/include/libRth.h /usr/include/

sudo cp API/Linux/lib/libRth64.so.1.1.0 /usr/lib/x86_64-linux-gnu/

ldconfig

然后进入API/Linux/apps/shmAccessDemo 这里有提供一个写/读的案例,我们先用这个案例进行示范。需要修改一下Makefile,这里自带的Makefile过时了,原先的会导致一直在找libRth64.so,但是实际上我们现在用的是libRth64.so.1

bash 复制代码
################################################################################
##
##  Makefile for Shared memory access demo
##
##  Copyright (c) 2012-2025 congatec GmbH, Ravensburg, Germany. All Rights Reserved.
##
##  Target architecture (x86_64 or i386) is determined automatically.
##  To override it, use the ARCH parameter:
##      "make ARCH=i386"       compile and link for 32 bit target
##      "make ARCH=x86_64"     compile and link for 64 bit target
##
##  If libRth.so (or libRth64.so respectively) is not located in the default path
##  you may specify its location using the LPATH parameter:
##
##      "make ARCH=i386 LPATH=~/BSP/Linux"
##
################################################################################

#
# Override BITS if ARCH is specified, otherwise set automatically
ifndef ARCH
BITS = $(shell arch | awk '/x86_64/ {print 64} /i.86/ {print 32}')
else
ifeq ($(ARCH),i386)
BITS = 32
else
ifeq ($(ARCH),x86_64)
BITS = 64
else
$(error failed. Try: ARCH=i386 or ARCH=x86_64)
endif
endif
endif

NAME = shmAccessDemo

RTHLIB = Rth
CC = gcc
CFLAGS_EXTRA = -m$(BITS)

ifeq ($(BITS),64)
LPATH = /lib/x86_64-linux-gnu
RTHLIB := $(RTHLIB)$(BITS)
RTHSONAME = libRth64.so.1
else
LPATH = /lib/i386-linux-gnu
RTHSONAME = libRth.so.1
endif

OBJECTS = $(NAME).o
TARGET = $(NAME)

####################################################################

## link dynamic to libRth.so.1 or libRth64.so.1 (soname; no libRth64.so linker symlink required)
##  1. library has to be located at the default library path (e.g. /usr/lib) or at $(LPATH)
##  2. use -l:filename to link the versioned soname directly
$(TARGET): $(OBJECTS)
	$(CC) $(CFLAGS_EXTRA) $^ -L$(LPATH) -L. -l:$(RTHSONAME) -lrt -o $@

%.o: %.c
	$(CC) $(CFLAGS_EXTRA) -Wall -c $< -o $@

clean:
	rm -f $(OBJECTS) $(TARGET)

安装make工具,然后编译

bash 复制代码
sudo apt install make

make

#文件如下

Makefile  shmAccessDemo  shmAccessDemo.c  shmAccessDemo.o

将生成的可执行文件shmAccessDemo 拷贝到rts的Linux里,如果拷贝过程中丢失了可执行权限的话,我们就给它补上

bash 复制代码
scp shmAccessDemo  rts@<ip>:~/

ssh rts@<ip>


chmod a+x shmAccessDemo  
bash 复制代码
root@rts-deb:/home/rts# ./shmAccessDemo
Found Shared Memory Partition "data" size: 0x00001000 bytes.
Shared Memory Partition Lock acquired.
Write 23 bytes to Shared memory...OK
Read back written data...OK
Read back data via direct pointer access...OK
Shared Memory Partiton Lock released.
Partition closed. Shared Memory Demo successful!

接下来,我们要修改一下代码,让它在linux上只读取,在windows下只写入

CPP in Liunx

bash 复制代码
/**
 * \file    shmAccessDemo.c
 *
 * \brief   Shared Memory API example (read-only access)
 *
 * This is a read-only demonstration of the Real-Time Hypervisor Shared Memory API functions.
 * It requires one configured Shared Memory partition named "data". Run the Windows write-only
 * demo on another OS to populate the partition, then use this demo to read and display the data.
 *
 * Copyright (c) 2008 - 2025 congatec GmbH, Ravensburg, Germany
 *
 * \n
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this file, to deal in this file without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of this file, and to permit persons to whom
 * this file is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies of this file.
 *
 * THIS FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THIS FILE OR THE USE OR OTHER DEALINGS
 * IN THIS FILE.
 *
 */

/***************************************************************************************************
 *                                            INCLUDES
 */

#include "../../include/libRth.h"   /* Real-Time Hypervisor API declaration */
#include <stdio.h>

/***************************************************************************************************
 *                                            DEFINES
 */

/*
 * Name of the Shared Memory partition to test.
 * Must correspond to the partition name defined in the Hypervisor configuration file.
 */
#define SHM_PARTITION_NAME    "data"

/***************************************************************************************************
 *                                         IMPLEMENTATION
 */

int main(void)
{
    char
        pTest[100] = {0},
        *pShmAddress = NULL;
    unsigned long
        partitionSize = 0,
        areaSize = 0;
    tShmKey
        key = SHM_KEY_INVALID;
    int
        ret = -1;

    /* get the size of the Shared Memory Partition */
    partitionSize = shmSizeGet(SHM_PARTITION_NAME);

    /* found the partition? */
    if(0 == partitionSize)
    {
        printf("ERROR: Shared Memory Partition \"" SHM_PARTITION_NAME "\" not found.\n");
        return -1;
    }

    printf("Found Shared Memory Partition \"" SHM_PARTITION_NAME "\" size: 0x%08lX bytes.\n",
           partitionSize);

    /* try to open the whole partition at offset 0 */
    areaSize = partitionSize;
    key = shmOpen(SHM_PARTITION_NAME, 0, &areaSize);

    /* check if the partition could be opened */
    if(key == SHM_KEY_INVALID)
    {
        printf("ERROR: Cannot open Shared Memory Partition \"" SHM_PARTITION_NAME "\".\n");
        return -1;
    }

    /* check the actual size of the opened area */
    if(areaSize != partitionSize)
    {
        printf("WARNING: Opened Shared Memory Area size: 0x%08lX (smaller than desired size 0x%08lX).\n",
               areaSize, partitionSize);
    }

    /* indicate access to the partition, wait up to 2 sec */
    ret = shmLockAcquire(key, 2000);

    /* check for failure */
    if(ret)
    {
        printf("ERROR: Lock is already acquired by another OS.\n");
        /* close the shared memory partition  */
        shmClose(key);
        return -1;
    }

    printf("Shared Memory Partition Lock acquired.\n");

    /* read data from offset 0, use shmRead instead of direct access */
    printf("Read data from Shared memory...");
    ret = shmRead(key, 0, sizeof(pTest) - 1, pTest);

    /* check how much data was read */
    if(ret <= 0)
    {
        printf("\nERROR: Could not read data from Shared Memory (returned %d).\n", ret);
        goto fail;
    }
    pTest[ret] = '\0';
    printf("OK\n");
    printf("Read content via shmRead (%d bytes): '%s'\n", ret, pTest);

    printf("Read data via direct pointer access...");

    /* get direct access via pointer */
    pShmAddress = (char *)shmAddrGet(key);

    /* is address valid? */
    if(NULL == pShmAddress)
    {
        printf("\nERROR: shmAddrGet() failed.\n");
        goto fail;
    }

    printf("OK\n");
    printf("Read content via direct access: '%s'\n", pShmAddress);

    /* release the lock */
    ret = shmLockRelease(key);

    /* check for failure */
    if(ret) {
        printf("ERROR: Failed to release Partition Lock\n");
        shmClose(key);
        return -1;
    }
    printf("Shared Memory Partiton Lock released.\n");

    /* close partition */
    ret = shmClose(key);

    /* did it work? */
    if(ret)
    {
        printf("Cannot close Shared Memory Partition: shmClose() returned %d.\n", ret);
        return -1;
    }

    printf("Partition closed. Shared Memory read demo successful!\n");

    return 0;

fail:
    shmLockRelease(key);
    shmClose(key);
    return -1;
}

Windows CPP

bash 复制代码
 /**
 * \file    shmAccessDemo.c
 *
 * \brief   Shared Memory API example (write-only access)
 *
 * This is a write-only demonstration of the Real-Time Hypervisor Shared Memory API functions.
 * It requires one configured Shared Memory partition named "data". Run the Linux read-only demo
 * on another OS to read and display the data written by this demo.
 *
 * \note
 *
 * Copyright (c) 2008 - 2025 congatec GmbH, Ravensburg, Germany
 *
 * \n
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this file, to deal in this file without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of this file, and to permit persons to whom
 * this file is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies of this file.
 *
 * THIS FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THIS FILE OR THE USE OR OTHER DEALINGS
 * IN THIS FILE.
 *
 */

/***************************************************************************************************
 *                                            INCLUDES
 */

#include "../../include/libRth.h"   /* Real-Time Hypervisor API declaration */
#include <stdio.h>

/***************************************************************************************************
 *                                            DEFINES
 */

/** name of the Shared Memory partition to test (has to be defined in config.txt) */
#define SHM_PARTITION_NAME    "data"

/***************************************************************************************************
 *                                         IMPLEMENTATION
 */

int main(void)
{
    const char
        pBuf[] = "This is a test string from Windows.";
    unsigned long
        partitionSize = 0,
        areaSize = 0;
    tShmKey
        key = SHM_KEY_INVALID;
    int
        ret = -1;

    /* get the size of the Shared Memory Partition */
    partitionSize = shmSizeGet(SHM_PARTITION_NAME);

    /* found the partition? */
    if(0 == partitionSize)
    {
        printf("ERROR: Shared Memory Partition \"" SHM_PARTITION_NAME "\" not found.\n");
        return -1;
    }

    printf("Found Shared Memory Partition \"" SHM_PARTITION_NAME "\" size: 0x%08lX bytes.\n",
           partitionSize);

    /* try to open the whole partition at offset 0 */
    areaSize = partitionSize;
    key = shmOpen(SHM_PARTITION_NAME, 0, &areaSize);

    /* check if the partition could be opened */
    if(key == SHM_KEY_INVALID)
    {
        printf("ERROR: Cannot open Shared Memory Partition \"" SHM_PARTITION_NAME "\".\n");
        return -1;
    }

    /* check the actual size of the opened area */
    if(areaSize != partitionSize)
    {
        printf("WARNING: Opened Shared Memory Area size: 0x%08lX (smaller than desired size 0x%08lX).\n",
               areaSize, partitionSize);
    }

    /* indicate access to the partition, wait up to 2 sec */
    ret = shmLockAcquire(key, 2000);

    /* check for failure */
    if(ret)
    {
        printf("ERROR: Lock is already acquired by another OS.\n");
        /* close the shared memory partition  */
        shmClose(key);
        return -1;
    }

    printf("Shared Memory Partition Lock acquired.\n");

    /* write some data to offset 0, use shmWrite instead of direct access */
    printf("Write %zu bytes to Shared memory: \"%s\"...", sizeof(pBuf), pBuf);
    ret = shmWrite(key, 0, sizeof(pBuf), pBuf);

    /* check it */
    if(sizeof(pBuf) != ret)
    {
        printf("\nERROR: Could only write %d bytes to Shared Memory.\n", ret);
        /* close the shared memory partition  */
        shmLockRelease(key);
        shmClose(key);
        return -1;
    }
    printf("OK\n");
    printf("Written content: \"%s\"\n", pBuf);

    /* release the lock */
    ret = shmLockRelease(key);

    /* check for failure */
    if(ret)
    {
        printf("ERROR: Failed to release Partition Lock\n");
        /* close the shared memory partition  */
        shmClose(key);
        return -1;
    }
    printf("Shared Memory Partiton Lock released.\n");

    /* close partition */
    ret = shmClose(key);

    /* did it work? */
    if(ret)
    {
        printf("ERROR: Cannot close Shared Memory Partition: shmClose() returned %d.\n", ret);
        return -1;
    }

    printf("Partition closed. Shared Memory write demo successful!\n");

    return 0;
}

Windows侧需要安装Visual Studio,然后打开apps.sln文件,进行编译

编译成功以后会获得可执行文件

我们把linux的可执行文件拷贝到rts中,替换之前的,然后先运行Windows下的shm写程序,再运行linux中的shm读程序。(Windows这边运行完就是闪一下结束了,如果想看到内容,需要添加头文件<stdlib>,在return 0 之前添加一个 system("pause");)

可以看到 Windows写入的是This is a test string from Windows.

可以看到Linux这边输出了一样的内容,证明正确读到了Shm里的信息

bash 复制代码
root@rts-deb:/home/rts# ./shmAccessDemo
Found Shared Memory Partition "data" size: 0x00001000 bytes.
Shared Memory Partition Lock acquired.
Read data from Shared memory...OK
Read content via shmRead (99 bytes): 'This is a test string from Windows.'
Read data via direct pointer access...OK
Read content via direct access: 'This is a test string from Windows.'
Shared Memory Partiton Lock released.
Partition closed. Shared Memory read demo successful!
相关推荐
Web3探索者10 小时前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo12 小时前
Linux系统中网线与USB网络共享冲突
linux
荣--14 小时前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森15 小时前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜1 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
Sokach10152 天前
Linux Shell 脚本从零到能用:一个新手的一天学习总结
linux
SelectDB2 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
AlfredZhao2 天前
Docker 容器时区不对,`timedatectl` 不存在怎么办?
linux·timezone
zzzzzz3104 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
XIAOHEZIcode4 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏