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!
相关推荐
aningx1 小时前
openSUSE Leap 16.0 运行 sunshine 报错的解决方法
linux
爱学习的徐徐1 小时前
Linux 基础IO
linux·服务器
蛋蛋的学习记录1 小时前
C#窗体应用中使用EasyModbusCore通讯
服务器·c#·tcp
zt1985q1 小时前
本地部署源代码管理解决方案 Bitbucket Data Center 并实现外部访问
运维·服务器·数据库·网络协议·postgresql·源代码管理
xiaobobo33301 小时前
面向对象:linux内核中函数转数据的用法
linux·面向对象·隔离·函数指针绑定
极客先躯1 小时前
高级java每日一道面试题-2026年01月18日-实战篇[Docker]-如何清理仓库中的旧镜像?
java·运维·docker·容器
姓刘的哦1 小时前
C++软件架构设计思路
linux
ModestCoder_2 小时前
windows/ubuntu解决挂梯子但是codex reconnecting五次的问题
linux·windows·ubuntu
禹凕2 小时前
Linux基础——环境
linux·运维·服务器·ubuntu