Skip to content

Commit 6f273fd

Browse files
hubertmisPiotr Szkotak
andcommitted
bluetooth: hci: rpmsg: Use RPMsg Service
This patch modifies Bluetooth HCI RPMsg drivers and samples to use RPMsg Service instead of configuring OpenAMP directly in the driver or the sample. Co-authored-by: Piotr Szkotak <[email protected]> Signed-off-by: Hubert Miś <[email protected]>
1 parent ce7535b commit 6f273fd

File tree

5 files changed

+68
-471
lines changed

5 files changed

+68
-471
lines changed

drivers/bluetooth/hci/Kconfig

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,26 +112,16 @@ config BT_RPMSG_NRF53
112112
bool "nRF53 configuration of RPMsg"
113113
default y if SOC_NRF5340_CPUAPP
114114
depends on BT_RPMSG
115-
select IPM
116-
select IPM_NRFX
117-
select IPM_MSG_CH_1_ENABLE
118-
select IPM_MSG_CH_0_ENABLE
119-
select IPM_MSG_CH_0_TX
120-
select IPM_MSG_CH_1_RX
121-
select OPENAMP
115+
select RPMSG_SERVICE
122116
help
123117
Enable RPMsg configuration for nRF53. Two channels of the IPM driver
124118
are used in the HCI driver: channel 0 for TX and channel 1 for RX.
125119

126120
if BT_RPMSG_NRF53
127121

128-
config BT_RPMSG_NRF53_RX_STACK_SIZE
129-
int "RPMsg stack size for RX thread"
130-
default 1024
131-
132-
config BT_RPMSG_NRF53_RX_PRIO
133-
int "RPMsg RX thread priority"
134-
default 8
122+
choice RPMSG_SERVICE_MODE
123+
default RPMSG_SERVICE_MODE_MASTER
124+
endchoice
135125

136126
endif # BT_RPMSG_NRF53
137127

drivers/bluetooth/hci/rpmsg.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
int bt_rpmsg_platform_init(void);
2525
int bt_rpmsg_platform_send(struct net_buf *buf);
26+
int bt_rpmsg_platform_endpoint_is_bound(void);
2627

2728
static bool is_hci_event_discardable(const uint8_t *evt_data)
2829
{
@@ -234,7 +235,10 @@ static int bt_rpmsg_open(void)
234235
{
235236
BT_DBG("");
236237

237-
return bt_rpmsg_platform_init();
238+
while (!bt_rpmsg_platform_endpoint_is_bound()) {
239+
k_sleep(K_MSEC(1));
240+
}
241+
return 0;
238242
}
239243

240244
static const struct bt_hci_driver drv = {
@@ -251,7 +255,20 @@ static int bt_rpmsg_init(const struct device *unused)
251255
{
252256
ARG_UNUSED(unused);
253257

254-
return bt_hci_driver_register(&drv);
258+
int err;
259+
260+
err = bt_rpmsg_platform_init();
261+
if (err < 0) {
262+
BT_ERR("Failed to initialize BT RPMSG (err %d)", err);
263+
return err;
264+
}
265+
266+
err = bt_hci_driver_register(&drv);
267+
if (err < 0) {
268+
BT_ERR("Failed to register BT HIC driver (err %d)", err);
269+
}
270+
271+
return err;
255272
}
256273

257-
SYS_INIT(bt_rpmsg_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
274+
SYS_INIT(bt_rpmsg_init, POST_KERNEL, CONFIG_RPMSG_SERVICE_EP_REG_PRIORITY);

drivers/bluetooth/hci/rpmsg_nrf53.c

Lines changed: 14 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66

77
#include <drivers/ipm.h>
88

9-
#include <openamp/open_amp.h>
10-
#include <metal/sys.h>
11-
#include <metal/device.h>
12-
#include <metal/alloc.h>
9+
#include <ipc/rpmsg_service.h>
1310

1411
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
1512
#define LOG_MODULE_NAME bt_hci_driver_nrf53
@@ -20,107 +17,10 @@ void bt_rpmsg_rx(uint8_t *data, size_t len);
2017
static K_SEM_DEFINE(ready_sem, 0, 1);
2118
static K_SEM_DEFINE(rx_sem, 0, 1);
2219

23-
static K_KERNEL_STACK_DEFINE(bt_rpmsg_rx_thread_stack,
24-
CONFIG_BT_RPMSG_NRF53_RX_STACK_SIZE);
25-
static struct k_thread bt_rpmsg_rx_thread_data;
26-
27-
static const struct device *ipm_tx_handle;
28-
static const struct device *ipm_rx_handle;
29-
30-
/* Configuration defines */
31-
32-
#define SHM_NODE DT_CHOSEN(zephyr_ipc_shm)
33-
#define SHM_BASE_ADDRESS DT_REG_ADDR(SHM_NODE)
34-
35-
#define SHM_START_ADDR (SHM_BASE_ADDRESS + 0x400)
36-
#define SHM_SIZE 0x7c00
37-
#define SHM_DEVICE_NAME "sram0.shm"
38-
39-
BUILD_ASSERT((SHM_START_ADDR + SHM_SIZE - SHM_BASE_ADDRESS)
40-
<= DT_REG_SIZE(SHM_NODE),
41-
"Allocated size exceeds available shared memory reserved for IPC");
42-
43-
#define VRING_COUNT 2
44-
#define VRING_TX_ADDRESS (SHM_START_ADDR + SHM_SIZE - 0x400)
45-
#define VRING_RX_ADDRESS (VRING_TX_ADDRESS - 0x400)
46-
#define VRING_ALIGNMENT 4
47-
#define VRING_SIZE 16
48-
49-
#define VDEV_STATUS_ADDR SHM_BASE_ADDRESS
50-
5120
BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE >= 1024,
5221
"Not enough heap memory for RPMsg queue allocation");
5322

54-
/* End of configuration defines */
55-
56-
static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR };
57-
static struct metal_device shm_device = {
58-
.name = SHM_DEVICE_NAME,
59-
.bus = NULL,
60-
.num_regions = 1,
61-
.regions = {
62-
{
63-
.virt = (void *) SHM_START_ADDR,
64-
.physmap = shm_physmap,
65-
.size = SHM_SIZE,
66-
.page_shift = 0xffffffff,
67-
.page_mask = 0xffffffff,
68-
.mem_flags = 0,
69-
.ops = { NULL },
70-
},
71-
},
72-
.node = { NULL },
73-
.irq_num = 0,
74-
.irq_info = NULL
75-
};
76-
77-
static struct virtqueue *vq[2];
78-
static struct rpmsg_endpoint ep;
79-
80-
static unsigned char virtio_get_status(struct virtio_device *vdev)
81-
{
82-
return VIRTIO_CONFIG_STATUS_DRIVER_OK;
83-
}
84-
85-
static void virtio_set_status(struct virtio_device *vdev, unsigned char status)
86-
{
87-
sys_write8(status, VDEV_STATUS_ADDR);
88-
}
89-
90-
static uint32_t virtio_get_features(struct virtio_device *vdev)
91-
{
92-
return BIT(VIRTIO_RPMSG_F_NS);
93-
}
94-
95-
static void virtio_set_features(struct virtio_device *vdev, uint32_t features)
96-
{
97-
/* No need for implementation */
98-
}
99-
100-
static void virtio_notify(struct virtqueue *vq)
101-
{
102-
int status;
103-
104-
status = ipm_send(ipm_tx_handle, 0, 0, NULL, 0);
105-
if (status != 0) {
106-
BT_ERR("ipm_send failed to notify: %d", status);
107-
}
108-
}
109-
110-
const struct virtio_dispatch dispatch = {
111-
.get_status = virtio_get_status,
112-
.set_status = virtio_set_status,
113-
.get_features = virtio_get_features,
114-
.set_features = virtio_set_features,
115-
.notify = virtio_notify,
116-
};
117-
118-
static void ipm_callback(const struct device *dev, void *context,
119-
uint32_t id, volatile void *data)
120-
{
121-
BT_DBG("Got callback of id %u", id);
122-
k_sem_give(&rx_sem);
123-
}
23+
static int endpoint_id;
12424

12525
static int endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len,
12626
uint32_t src, void *priv)
@@ -133,146 +33,28 @@ static int endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len,
13333
return RPMSG_SUCCESS;
13434
}
13535

136-
static void rpmsg_service_unbind(struct rpmsg_endpoint *ep)
137-
{
138-
rpmsg_destroy_ept(ep);
139-
}
140-
141-
static void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest)
142-
{
143-
(void)rpmsg_create_ept(&ep,
144-
rdev,
145-
name,
146-
RPMSG_ADDR_ANY,
147-
dest,
148-
endpoint_cb,
149-
rpmsg_service_unbind);
150-
151-
k_sem_give(&ready_sem);
152-
}
153-
154-
static void bt_rpmsg_rx_thread(void *p1, void *p2, void *p3)
155-
{
156-
ARG_UNUSED(p1);
157-
ARG_UNUSED(p2);
158-
ARG_UNUSED(p3);
159-
160-
while (1) {
161-
int status = k_sem_take(&rx_sem, K_FOREVER);
162-
163-
if (status == 0) {
164-
virtqueue_notification(vq[0]);
165-
}
166-
}
167-
}
168-
16936
int bt_rpmsg_platform_init(void)
17037
{
17138
int err;
172-
struct metal_init_params metal_params = METAL_INIT_DEFAULTS;
17339

174-
static struct virtio_vring_info rvrings[2];
175-
static struct rpmsg_virtio_shm_pool shpool;
176-
static struct virtio_device vdev;
177-
static struct rpmsg_virtio_device rvdev;
178-
static struct metal_io_region *io;
179-
static struct metal_device *device;
40+
err = rpmsg_service_register_endpoint("nrf_bt_hci", endpoint_cb);
18041

181-
/* Setup thread for RX data processing. */
182-
k_thread_create(&bt_rpmsg_rx_thread_data, bt_rpmsg_rx_thread_stack,
183-
K_KERNEL_STACK_SIZEOF(bt_rpmsg_rx_thread_stack),
184-
bt_rpmsg_rx_thread, NULL, NULL, NULL,
185-
K_PRIO_COOP(CONFIG_BT_RPMSG_NRF53_RX_PRIO),
186-
0, K_NO_WAIT);
187-
188-
/* Libmetal setup */
189-
err = metal_init(&metal_params);
190-
if (err) {
191-
BT_ERR("metal_init: failed - error code %d", err);
192-
return err;
42+
if (err < 0) {
43+
LOG_ERR("Registering endpoint failed with %d", err);
44+
return RPMSG_ERR_INIT;
19345
}
19446

195-
err = metal_register_generic_device(&shm_device);
196-
if (err) {
197-
BT_ERR("Couldn't register shared memory device: %d", err);
198-
return err;
199-
}
47+
endpoint_id = err;
20048

201-
err = metal_device_open("generic", SHM_DEVICE_NAME, &device);
202-
if (err) {
203-
BT_ERR("metal_device_open failed: %d", err);
204-
return err;
205-
}
206-
207-
io = metal_device_io_region(device, 0);
208-
if (!io) {
209-
BT_ERR("metal_device_io_region failed to get region");
210-
return -ENODEV;
211-
}
212-
213-
/* IPM setup */
214-
ipm_tx_handle = device_get_binding("IPM_0");
215-
if (!ipm_tx_handle) {
216-
BT_ERR("Could not get TX IPM device handle");
217-
return -ENODEV;
218-
}
219-
220-
ipm_rx_handle = device_get_binding("IPM_1");
221-
if (!ipm_rx_handle) {
222-
BT_ERR("Could not get RX IPM device handle");
223-
return -ENODEV;
224-
}
225-
226-
ipm_register_callback(ipm_rx_handle, ipm_callback, NULL);
227-
228-
/* Virtqueue setup */
229-
vq[0] = virtqueue_allocate(VRING_SIZE);
230-
if (!vq[0]) {
231-
BT_ERR("virtqueue_allocate failed to alloc vq[0]");
232-
return -ENOMEM;
233-
}
234-
235-
vq[1] = virtqueue_allocate(VRING_SIZE);
236-
if (!vq[1]) {
237-
BT_ERR("virtqueue_allocate failed to alloc vq[1]");
238-
return -ENOMEM;
239-
}
240-
241-
rvrings[0].io = io;
242-
rvrings[0].info.vaddr = (void *)VRING_TX_ADDRESS;
243-
rvrings[0].info.num_descs = VRING_SIZE;
244-
rvrings[0].info.align = VRING_ALIGNMENT;
245-
rvrings[0].vq = vq[0];
246-
247-
rvrings[1].io = io;
248-
rvrings[1].info.vaddr = (void *)VRING_RX_ADDRESS;
249-
rvrings[1].info.num_descs = VRING_SIZE;
250-
rvrings[1].info.align = VRING_ALIGNMENT;
251-
rvrings[1].vq = vq[1];
252-
253-
vdev.role = RPMSG_MASTER;
254-
vdev.vrings_num = VRING_COUNT;
255-
vdev.func = &dispatch;
256-
vdev.vrings_info = &rvrings[0];
257-
258-
rpmsg_virtio_init_shm_pool(&shpool, (void *)SHM_START_ADDR, SHM_SIZE);
259-
err = rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, io, &shpool);
260-
if (err) {
261-
BT_ERR("rpmsg_init_vdev failed %d", err);
262-
return err;
263-
}
264-
265-
/* Wait til nameservice ep is setup */
266-
err = k_sem_take(&ready_sem, K_SECONDS(3));
267-
if (err) {
268-
BT_ERR("No contact with network core EP (err %d)", err);
269-
return err;
270-
}
271-
272-
return 0;
49+
return RPMSG_SUCCESS;
27350
}
27451

27552
int bt_rpmsg_platform_send(struct net_buf *buf)
27653
{
277-
return rpmsg_send(&ep, buf->data, buf->len);
54+
return rpmsg_service_send(endpoint_id, buf->data, buf->len);
55+
}
56+
57+
int bt_rpmsg_platform_endpoint_is_bound(void)
58+
{
59+
return rpmsg_service_endpoint_is_bound(endpoint_id);
27860
}
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
CONFIG_LOG=y
2-
CONFIG_OPENAMP=y
32

4-
CONFIG_IPM=y
5-
CONFIG_IPM_NRFX=y
6-
7-
CONFIG_IPM_MSG_CH_1_ENABLE=y
8-
CONFIG_IPM_MSG_CH_1_TX=y
9-
CONFIG_IPM_MSG_CH_0_ENABLE=y
10-
CONFIG_IPM_MSG_CH_0_RX=y
3+
CONFIG_RPMSG_SERVICE=y
4+
CONFIG_RPMSG_SERVICE_MODE_REMOTE=y
115

126
CONFIG_HEAP_MEM_POOL_SIZE=8192
137

@@ -18,3 +12,7 @@ CONFIG_BT_HCI_RAW=y
1812
CONFIG_BT_MAX_CONN=16
1913
CONFIG_BT_CTLR_ASSERT_HANDLER=y
2014
CONFIG_BT_HCI_RAW_RESERVE=1
15+
16+
CONFIG_ASSERT=y
17+
CONFIG_DEBUG_INFO=y
18+
CONFIG_EXCEPTION_STACK_TRACE=y

0 commit comments

Comments
 (0)