[dm][rpmsg] support Remote Processor Messaging (RPMSG)

Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
GuEe-GUI
2026-05-11 14:09:04 +08:00
committed by Rbb666
parent ecf2409904
commit 46b90df247
8 changed files with 1042 additions and 0 deletions
+1
View File
@@ -25,6 +25,7 @@ rsource "led/Kconfig"
rsource "input/Kconfig"
rsource "mailbox/Kconfig"
rsource "hwspinlock/Kconfig"
rsource "rpmsg/Kconfig"
rsource "phye/Kconfig"
rsource "ata/Kconfig"
rsource "nvme/Kconfig"
+142
View File
@@ -0,0 +1,142 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __RPMSG_H__
#define __RPMSG_H__
#include <rthw.h>
#include <rtthread.h>
#include <drivers/core/dm.h>
#include <drivers/core/driver.h>
#include <drivers/byteorder.h>
#define RT_DEVICE_CTRL_RPMSG_CREATE_EPT (RT_DEVICE_CTRL_BASE(Char) + 'R' + 1)
#define RT_DEVICE_CTRL_RPMSG_DESTROY_EPT (RT_DEVICE_CTRL_BASE(Char) + 'R' + 2)
#define RT_DEVICE_CTRL_RPMSG_DATA_OVERWRITE (RT_DEVICE_CTRL_BASE(Char) + 'R' + 3)
struct rt_rpmsg_device_id
{
#define RT_RPMSG_NAME_SIZE 32
char name[RT_RPMSG_NAME_SIZE];
const void *data;
};
struct rt_rpmsg_ops;
struct rt_rpmsg_endpoint;
struct rt_rpmsg_endpoint_info;
struct rt_rpmsg_device
{
struct rt_device parent;
struct rt_rpmsg_device_id id;
rt_list_t ept_nodes;
struct rt_spinlock lock;
const struct rt_rpmsg_ops *ops;
void *priv;
};
struct rt_rpmsg_driver
{
struct rt_driver parent;
const struct rt_rpmsg_device_id *ids;
rt_err_t (*probe)(struct rt_rpmsg_device *rdev);
rt_err_t (*remove)(struct rt_rpmsg_device *rdev);
rt_err_t (*rx_callback)(struct rt_rpmsg_device *rdev,
rt_uint32_t src, void *data, rt_size_t len);
};
typedef rt_err_t (*rt_rpmsg_rx_callback)(struct rt_rpmsg_device *rdev,
rt_uint32_t src, void *data, rt_size_t len);
struct rt_rpmsg_ops
{
rt_err_t (*create_endpoint)(struct rt_rpmsg_device *, struct rt_rpmsg_endpoint *,
struct rt_rpmsg_endpoint_info *info);
rt_err_t (*destroy_endpoint)(struct rt_rpmsg_device *, struct rt_rpmsg_endpoint *);
rt_err_t (*send)(struct rt_rpmsg_device *, rt_uint32_t src, rt_uint32_t dst,
const void *data, rt_size_t len, rt_int32_t timeout);
};
struct rt_rpmsg_endpoint_info
{
char name[RT_RPMSG_NAME_SIZE];
#define RT_RPMSG_ADDR_ANY 0xffffffff
rt_uint32_t src;
rt_uint32_t dst;
};
struct rt_rpmsg_endpoint
{
rt_list_t list;
struct rt_rpmsg_device *rdev;
struct rt_rpmsg_endpoint_info info;
rt_rpmsg_rx_callback rx_callback;
struct rt_spinlock lock;
void *sysdata;
void *priv;
};
enum rt_rpmsg_ns_flags
{
RT_RPMSG_NS_CREATE = 0,
RT_RPMSG_NS_DESTROY = 1,
};
rt_packed(struct rt_rpmsg_ns_msg
{
char name[RT_RPMSG_NAME_SIZE];
#define RT_RPMSG_NS_ADDR 0x35 /* 0x35 -> 53 */
rt_uint32_t addr;
rt_uint32_t flags;
});
enum
{
RT_RPMSG_MODE_MASTER,
RT_RPMSG_MODE_SLAVE,
RT_RPMSG_MODE_MAX,
};
rt_uint32_t rt_rpmsg_mode(void);
struct rt_rpmsg_endpoint *rt_rpmsg_create_endpoint(struct rt_rpmsg_device *,
struct rt_rpmsg_endpoint_info *info, rt_rpmsg_rx_callback rx_cb);
rt_err_t rt_rpmsg_destroy_endpoint(struct rt_rpmsg_device *,
struct rt_rpmsg_endpoint *);
struct rt_rpmsg_endpoint *rt_rpmsg_find_endpoint(struct rt_rpmsg_device *,
struct rt_rpmsg_endpoint_info *info);
rt_err_t rt_rpmsg_send(struct rt_rpmsg_endpoint *,
const void *data, rt_size_t len);
rt_err_t rt_rpmsg_sendto(struct rt_rpmsg_endpoint *, rt_uint32_t dst,
const void *data, rt_size_t len);
rt_err_t rt_rpmsg_send_wait(struct rt_rpmsg_endpoint *,
const void *data, rt_size_t len, rt_int32_t timeout);
rt_err_t rt_rpmsg_sendto_wait(struct rt_rpmsg_endpoint *, rt_uint32_t dst,
const void *data, rt_size_t len, rt_int32_t timeout);
rt_err_t rt_rpmsg_driver_register(struct rt_rpmsg_driver *rdrv);
rt_err_t rt_rpmsg_device_register(struct rt_rpmsg_device *rdev);
#define RT_RPMSG_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, rpmsg, BUILIN)
#endif /* __RPMSG_H__ */
+4
View File
@@ -79,6 +79,10 @@ extern "C" {
#include "drivers/hwspinlock.h"
#endif /* RT_USING_HWSPINLOCK */
#ifdef RT_USING_RPMSG
#include "drivers/rpmsg.h"
#endif /* RT_USING_RPMSG */
#ifdef RT_USING_BLK
#include "drivers/blk.h"
#endif /* RT_USING_BLK */
+19
View File
@@ -0,0 +1,19 @@
menuconfig RT_USING_RPMSG
bool "Using Remote Processor Messaging (RPMSG)"
select RT_USING_DEVICE_IPC
select RT_USING_SYSTEM_WORKQUEUE
default n
config RT_RPMSG_CHAR_MSG_MAX
int "Char device message receive max"
depends on RT_USING_RPMSG
default 64
config RT_RPMSG_CHAR_MSG_SIZE_MAX
int "Char device message size max"
depends on RT_USING_RPMSG
default 256
if RT_USING_RPMSG
osource "$(SOC_DM_RPMSG_DIR)/Kconfig"
endif
+15
View File
@@ -0,0 +1,15 @@
from building import *
group = []
if not GetDepend(['RT_USING_RPMSG']):
Return('group')
cwd = GetCurrentDir()
CPPPATH = [cwd + '/../include']
src = ['rpmsg.c', 'rpmsg_char.c', 'rpmsg_ns.c']
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+327
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+122
View File
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "rpmsg.ns"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
/*
* Used when rt_rpmsg_create_endpoint(..., RT_NULL) (e.g. remote NS announce);
* application traffic should be bound via a higher layer later.
*/
static rt_err_t rpmsg_ns_remote_default_rx(struct rt_rpmsg_device *rdev,
rt_uint32_t src, void *data, rt_size_t len)
{
LOG_D("%s: remote endpoint rx (no user cb), src=%u len=%u", rt_dm_dev_get_name(&rdev->parent), src, len);
return RT_EOK;
}
static rt_err_t rpmsg_ns_rx_callback(struct rt_rpmsg_device *rdev,
rt_uint32_t src, void *data, rt_size_t len)
{
rt_err_t err = RT_EOK;
struct rt_rpmsg_ns_msg *msg = data;
struct rt_rpmsg_endpoint *ept;
struct rt_rpmsg_endpoint_info info;
if (len != sizeof(*msg))
{
LOG_E("Invalid MSG size = %d", len);
return -RT_EINVAL;
}
/* Fixup the name */
msg->name[RT_RPMSG_NAME_SIZE - 1] = '\0';
rt_strncpy(info.name, msg->name, RT_RPMSG_NAME_SIZE);
info.src = RT_RPMSG_ADDR_ANY;
info.dst = rt_le32_to_cpu(msg->addr);
LOG_D("%s: name: %s, src: %u, dst: %u", rt_dm_dev_get_name(&rdev->parent),
info.name, info.src, info.dst);
if (rt_le32_to_cpu(msg->flags) & RT_RPMSG_NS_DESTROY)
{
ept = rt_rpmsg_find_endpoint(rdev, &info);
if (ept)
{
err = rt_rpmsg_destroy_endpoint(rdev, ept);
}
else
{
err = -RT_EEMPTY;
}
}
else if (rt_le32_to_cpu(msg->flags) == RT_RPMSG_NS_CREATE)
{
ept = rt_rpmsg_create_endpoint(rdev, &info, RT_NULL);
if (rt_is_err(ept))
{
err = rt_ptr_err(ept);
}
}
else
{
LOG_E("Unsupported flags = %x", rt_le32_to_cpu(msg->flags));
}
if (err)
{
LOG_E("%s: name = %s, addr = %x flags = %d error = %s",
rt_dm_dev_get_name(&rdev->parent),
msg->name, msg->addr, msg->flags, rt_strerror(err));
}
return err;
}
static rt_err_t rpmsg_ns_probe(struct rt_rpmsg_device *rdev)
{
struct rt_rpmsg_endpoint *ep;
struct rt_rpmsg_endpoint_info info;
rt_strncpy(info.name, "name-service", RT_RPMSG_NAME_SIZE);
info.src = RT_RPMSG_NS_ADDR;
info.dst = RT_RPMSG_NS_ADDR;
ep = rt_rpmsg_create_endpoint(rdev, &info, &rpmsg_ns_rx_callback);
return rt_is_err(ep) ? rt_ptr_err(ep) : RT_EOK;
}
static struct rt_rpmsg_device_id rpmsg_ns_ids[] =
{
{ .name = "rpmsg-name-service" },
{ /* sentinel */ }
};
static struct rt_rpmsg_driver rpmsg_ns_driver =
{
.parent.parent =
{
.name = "rpmsg-ns",
},
.ids = rpmsg_ns_ids,
.probe = rpmsg_ns_probe,
.rx_callback = rpmsg_ns_remote_default_rx,
};
RT_RPMSG_DRIVER_EXPORT(rpmsg_ns_driver);