cancel
Showing results for 
Search instead for 
Did you mean: 

STM32MP257F-DK M class & A class remoteproc msg communication

luke-parkin
Associate

Hi, I'm pretty new to embedded development.

 

I'm trying to set up a really basic 'Hello world' image for my M33 core on STM32MP257F-DK. My Linux A image has remoteproc set up, and rpmesg

Dmesg on linux host:

 

[43834.220252] remoteproc remoteproc1: powering up m33
[43834.258170] remoteproc remoteproc1: Booting fw image zephyr_20251017_095646_e99be8ad.elf, size 1438504
[43834.262810] rproc-virtio rproc-virtio.2.auto: assigned reserved memory node vdev0buffer@812fa000
[43834.271543] virtio_rpmsg_bus virtio0: rpmsg host is online
[43834.276502] rproc-virtio rproc-virtio.2.auto: registered virtio0 (type 7)
[43834.286260] remoteproc remoteproc1: remote processor m33 is now up

 

 

However, Linux won't pick up the remoteproc msg endpoint and present it as I expect it to in /dev/ttyrpmsg

I'm building into my zephyr image an overlay, a resource table, a main.c and a ipcc_shim to patch over what I think is a missing getChannelConfig.

To be honest, I've made a lot of assumptions. If this is all completely wrong and someone could point me in the direction of a good example or guide on how to do this, I'd be immensely grateful. Otherwise, any help or corrections would be massively appreciated

 

My main.c is directly copied from this example from the zephyr repository, written by ST.

ipcc_shim.c

 

#include <zephyr/kernel.h>
#include <stm32mp2xx_ll_ipcc.h>

#ifdef CONFIG_SOC_STM32MP2X_M33
uint32_t LL_IPCC_GetChannelConfig(IPCC_TypeDef *IPCCx)
{
	return LL_IPCC_GetChannelNumber(IPCCx);
}
#endif

 


What I imagine I got wrong is either the resource_table.c (which I believe is used so Linux knows where to look?) 

 

#include <stddef.h>

#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>
#include <resource_table.h>
#include <openamp/rpmsg_virtio.h>

#define SHM_BASE      0x81200000UL
#define SHM_SIZE      0x000F8000UL   /* 1016 KiB buffer pool. */
#define VRING_ALIGN   0x10
#define VRING_NUM     16

/* Linux reserves:
 *  - ipc-shmem-1 : 0x81200000 - 0x812F7FFF (rf buffer pool)
 *  - vdev0vring0 : 0x812F8000 - 0x812F8FFF
 *  - vdev0vring1 : 0x812F9000 - 0x812F9FFF
 *  - vdev0buffer : 0x812FA000 - 0x812FFFFF
 */
#define VRING0_DA     0x812F8000UL
#define VRING1_DA     0x812F9000UL
#define BUFS_DA       0x812FA000UL
#define BUFS_SIZE     0x00006000UL

#define RPMSG_FEATURES BIT(VIRTIO_RPMSG_F_NS)

enum {
	RESOURCE_VDEV = 0,
	RESOURCE_CARVEOUT,
	RESOURCE_COUNT,
};

struct my_resource_table {
	struct resource_table base;
	uint32_t offset[RESOURCE_COUNT];
	struct fw_rsc_vdev vdev;
	struct fw_rsc_vdev_vring vring0;
	struct fw_rsc_vdev_vring vring1;
	struct fw_rsc_carveout carveout;
} __packed;
static struct my_resource_table rsc __used __section(".resource_table") = {
	.base = {
		.ver = 1,
		.num = RESOURCE_COUNT,
		.reserved = {0, 0},
	},
	.offset = {
		offsetof(struct my_resource_table, vdev),
		offsetof(struct my_resource_table, carveout),
	},
	.vdev = {
		.type = RSC_VDEV,
		.id = VIRTIO_ID_RPMSG,
		.notifyid = 0,
		.dfeatures = RPMSG_FEATURES,
		.gfeatures = 0,
		.config_len = 0,
		.status = 0,
		.num_of_vrings = 2,
		.reserved = {0, 0},
	},
	.vring0 = {
		.da = VRING0_DA,
		.align = VRING_ALIGN,
		.num = VRING_NUM,
		.notifyid = 0,
		.reserved = 0,
	},
	.vring1 = {
		.da = VRING1_DA,
		.align = VRING_ALIGN,
		.num = VRING_NUM,
		.notifyid = 1,
		.reserved = 0,
	},
	.carveout = {
		.type = RSC_CARVEOUT,
		.da = BUFS_DA,
		.pa = BUFS_DA,
		.len = BUFS_SIZE,
		.flags = 0,
		.reserved = 0,
		.name = "vdev0buffer",
	},
};

void rsc_table_get(void **table, int *size)
{
	*table = &rsc;
	*size = sizeof(rsc);
}

struct fw_rsc_vdev *rsc_table_to_vdev(void *tbl)
{
	return &((struct my_resource_table *)tbl)->vdev;
}

struct fw_rsc_vdev_vring *rsc_table_get_vring0(void *tbl)
{
	return &((struct my_resource_table *)tbl)->vring0;
}

struct fw_rsc_vdev_vring *rsc_table_get_vring1(void *tbl)
{
	return &((struct my_resource_table *)tbl)->vring1;
}

 

Or the boards/stm32mp257f_dk.overlay

/ {
	chosen {
		/* Point Zephyr IPC to the IPCC node (label below) */
		zephyr,ipc = &ipcc_mbox; /* Tells zephyr to use this mailbox for ipc */

		zephyr,ipc_shm = &rpmsg_shm; /* Points to shared buffer pool */
	};

	rpmsg_shm: memory@81200000 {
		compatible = "mmio-sram";
		reg = <0x81200000 0x000f8000>;
	};
};

/* Define (and enable) the mailbox/IPCC device under the SoC */
&{/soc} {
	ipcc_mbox: ipcc@40490000 {
		compatible = "st,stm32-ipcc-mailbox";

		/* soc also has #address-cells=<1>, #size-cells=<1> */
		reg = <0x40490000 0x400>;

		interrupts = <171 0>, <172 0>;
		interrupt-names = "rxo", "txf";
		mailbox-controller;
		#mbox-cells = <1>;

		/* Equivalent to STM32_CLOCK(IPCC1, STM32_CLK) */
		clocks = <&rcc 0x570 0x2>;
		clock-names = "ipcc";
		status = "okay";
	};
};

Finally, I build them together like this (in a dockerfile)

RUN if [ -f /workdir/src/main.c ]; then \
      cp /workdir/src/main.c \
         zephyr/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c; \
    fi

RUN if [ -f /workdir/src/ipcc_shim.c ]; then \
      cp /workdir/src/ipcc_shim.c \
         zephyr/samples/subsys/ipc/openamp_rsc_table/src/ipcc_shim.c; \
    fi

RUN if [ -f /workdir/CMakeLists.sample.txt ]; then \
      cp /workdir/CMakeLists.sample.txt \
         zephyr/samples/subsys/ipc/openamp_rsc_table/CMakeLists.txt; \
    fi

RUN if [ -f /workdir/prj.conf ]; then \
      cp /workdir/prj.conf \
         zephyr/samples/subsys/ipc/openamp_rsc_table/prj.conf; \
    fi

# Final OpenAMP build using the provided overlay
RUN west build -b "$BOARD" zephyr/samples/subsys/ipc/openamp_rsc_table \
      -- -DEXTRA_DTC_OVERLAY_FILE=/workdir/boards/stm32mp257f_dk.overlay \
 && cp build/zephyr/zephyr_openamp_rsc_table.elf /tmp/zephyr.elf

 

Thank you for any time and help you can provide.

 

 

0 REPLIES 0