Closed neuberfran closed 5 months ago
Hello,
I'm trying to acheive the same RPSMG communication on an CL-SOM-IMX7D.
Have you got any progress or success ?
I've seen a first thing is that we are missing the ressource table definition in the linker script of the imx7d soc.
Similar to the one on the imx8m m7 core: https://github.com/zephyrproject-rtos/zephyr/blob/main/soc/nxp/imx/imx8m/m7/linker.ld
When you compile the openamp_rsc_table example, there should not be saying "orphaned section .ressource_table...".
add the linker section to a linker.ld file like on the imx8m/m7 example and change the linker script path in the imx7d soc Cmakelist:
imx7/m4: Cmakelist.txt:
#
# Copyright (c) 2017, NXP
# Copyright (c) 2024, MAKEEN Energy A/S
#
# SPDX-License-Identifier: Apache-2.0
#
zephyr_sources(
soc.c
soc_clk_freq.c
)
if(CONFIG_OPENAMP_RSC_TABLE)
zephyr_linker_section(NAME .resource_table GROUP ROM_REGION NOINPUT)
zephyr_linker_section_configure(SECTION .resource_table KEEP INPUT ".resource_table*")
endif()
set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "")
imx7/m4 linker.ld:
/*
* Copyright (c) 2024, MAKEEN Energy A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/arch/arm/cortex_m/scripts/linker.ld>
SECTIONS
{
#ifdef CONFIG_OPENAMP_RSC_TABLE
SECTION_PROLOGUE(.resource_table,, SUBALIGN(4))
{
KEEP(*(.resource_table*))
} GROUP_LINK_IN(ROMABLE_REGION)
#endif
}
I'm not upstreaming my changes for now since I'm still having issues with my linux kernel to get rpmsg to work. But I've cooked some updates to the imx7d and prepared some driver updates that I'd like to upstream at some point.
BTW have you also compiled and inserted the drivers/rpmsg/imx_rpmsg_tty.c kernel module as mentionned by the sample ?
@jlh-makeen I'm glad you showed up about imx7 and remoteproc using resource table. I'm kinda alone in this (imx7d) for now
echo start > /sys/class/remoteproc/remoteproc0/state
[ 667.827358] remoteproc remoteproc0: powering up imx-rproc
[ 667.833825] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 660180
[ 667.842789] remoteproc0#vdev0buffer: assigned reserved memory node vdev0buffer@00924000
[ 667.851255] virtio_rpmsg_bus: probe of virtio1 failed with error -12
[ 667.857725] remoteproc0#vdev0buffer: registered virtio1 (type 7)
[ 667.863868] remoteproc remoteproc0: remote processor imx-rproc is now up
root@scorpion:/lib/firmware#
https://community.toradex.com/t/rpmsg-does-not-work-on-imx8m-plus/13740/92?page=4
-12 = missing memory
Every codes to github analyzer: https://gist.github.com/neuberfran/ce6861c962e8c5fa361ff9453ce85a10
below = imx_rpmsg_tty.c
#define RPMSG_MAX_SIZE 64
`
below = imx_rpmsg.c
``
RPMSG_VRING_ALIGN), PAGE_SIZE)) * PAGE_SIZE)
rpdev->ivdev[i]->vring[0] = start; rpdev->ivdev[i]->vring[1] = start + 0x2000; start += 0x4000;
**below = virtio_rpmsg_bus.c**
BTW have you also compiled and inserted the drivers/rpmsg/imx_rpmsg_tty.c kernel module as mentionned by the sample ?
Yes
And
You said: I've seen a first thing is that we are missing the ressource table definition in the linker script of the imx7d soc.
I suggest you read and participate in this meeting https://github.com/OpenAMP/open-amp/discussions/275#discussioncomment-8283357
my Kconfig.defconfig.mcimx7_m4 don`t have config IPM_IMX_REV2 Compared to mimx8mm6_m4
# iMX7 M4 core series
# Copyright (c) 2017, NXP
# SPDX-License-Identifier: Apache-2.0
if SOC_MCIMX7_M4
config SOC
default "mcimx7d"
config SYS_CLOCK_HW_CYCLES_PER_SEC
default 200000000
config GPIO
default y
endif # SOC_MCIMX7_M4
You are using Yocto kirkstone with Linux kernel 5.15 right ?
A the moment I have a Kirkstone image with Linux 5.10.9 and a backport of the imx-rproc drivers from 5.15 and a hack to boot my image from OCRAM (our app program uses more than 32kB). Might be too outdated as mainline kernel imx-rproc driver for 5.10.9 has quite some differences from 5.15 driver.
As soon as I define the mailboxes in the A7 DT and start the M4, I get a seg fault. That might be our fault from missing something in the backport, but we are struggling with Compulab not having released a kernel and patches for newer than linux 5.10.9.
root@cl-som-imx7:/lib/firmware# ./boot_m4.sh zephyr_pnet_ipm.elf
./boot_m4.sh: line 1: echo: writeremoteproc remoteproc0: powering up imx-rproc
error: Invalid argument
remoteproc remoteproc0: Booting fw image zephyr_pnet_ipm.elf, size 1629760
rproc_elf_load_segments: So... booting from OCRAM on IMX7 ??? Grabbing PC and SP for you...
rproc_elf_load_segments: SP: 0x20003348 PC: 0x00908205
rproc_elf_load_segments: APPLYING TEMPORARY HACK TO GET SP AND PC LOADED INTO M4 BOOT VECTOR
8<--- cut here ---
Unhandled fault: imprecise external abort (0x1c06) at 0xc0800000
pgd = da7dd62d
[c0800000] *pgd=885d2811, *pte=8854365f, *ppte=8854345f
Internal error: : 1c06 [#1] PREEMPT SMP ARM
Modules linked in: wl18xx evbug wlcore mousedev caam_jr caamkeyblob_desc caamhash_desc caamalg_desc crypto_engine wlcore_sdio imx_sdma caam secvio error pnet(O) fsl_ftm_ic(O)
CPU: 0 PID: 371 Comm: sh Tainted: G O 5.10.9 #1
Hardware name: Freescale i.MX7 Dual (Device Tree)
PC is at imx_mu_xcr_rmw+0x0/0x70
LR is at imx_mu_generic_tx+0x8c/0xf8
pc : [<809266e0>] lr : [<80926b10>] psr: 600f0093
sp : 851e9c48 ip : 80dc7cb4 fp : b8144e00
r10: 00002000 r9 : b8144000 r8 : 00000000
r7 : f5ab0004 r6 : 00000000 r5 : 8409b040 r4 : 00000000
r3 : 00000016 r2 : 00000000 r1 : 00400000 r0 : 8409b040
Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
Control: 10c5387d Table: 8849006a DAC: 00000051
Process sh (pid: 371, stack limit = 0xab2517e1)
Stack: (0x851e9c48 to 0x851ea000)
9c40: 8409b128 600f0013 8409b1a0 851e9ca8 00000cc0 80925aac
9c60: 00000036 000007ff 86749260 6759df8c 851e9c78 8409b128 00000000 851e9ca8
9c80: 8409b1a0 80925c60 00000000 84290ae8 84ec0400 00000000 00000cc0 8092c494
9ca0: b8144e00 8092db84 00000000 6759df8c 00000001 885d3180 00000001 8092afd4
9cc0: 885d3180 8062e4ac 885d3100 8092de8c 00000035 00000000 00000000 80308de0
9ce0: 884119f8 81053348 00000000 bfdabd92 00000e00 00000200 00000000 8092e104
9d00: 8092d840 885d3180 885d3200 6759df8c 84ec0600 84ec0410 84ec0400 00000000
9d20: 8141ec14 00000001 00000000 00000001 00000000 8062e38c 84ec0410 00000000
9d40: 814971e4 84ec0410 00000000 814971e4 00000000 814971dc 8141ec14 00000021
9d60: 00000000 806ca270 00000000 84ec0410 8141ec14 806caa88 84ec0454 00000000
9d80: 00000000 814097c0 00000000 806ca930 00000000 851e9dc4 806caa88 806c833c
9da0: 00000000 8415d06c 8437f338 6759df8c 84ec0410 813fb0a0 00000001 806ca700
9dc0: 8106acd8 84ec0410 00000001 6759df8c 84ec0410 84ec0410 813fb0a0 84ec0410
9de0: 84ec1c20 806c93d4 84ec0410 00000000 814971b4 806c5240 813fb0a0 84ec0410
9e00: 84290800 80589940 84ec0400 6759df8c 84ec0400 8092aff8 813fb0a0 84ec0410
9e20: 84290800 84ec0400 88329a40 8062e018 00000000 84ec1c00 00000007 84ec1c20
9e40: 84290800 8092b60c 84ec1c04 84290a48 84290820 88329c80 84290820 88329c80
9e60: 88329a40 80c8876c 84290800 00000000 84290820 80c8897c 842909f8 84290800
9e80: 00000000 84290a04 84290820 80929658 88329c80 6759df8c 84290820 88329cc0
9ea0: 00000006 84290800 8504be90 00000051 00000000 8092ada4 00000006 8504be80
9ec0: 88329cc0 851e9f80 8504be90 8030b700 00000000 00000000 846f6900 846f6780
9ee0: 00000006 8030b608 02082100 851e9f80 851e8000 00000004 00000000 802718d8
9f00: 843f2000 6759df8c 00000001 00000800 84cc7240 00000001 00000000 00000001
9f20: 84cc7240 0000000a 84cc7240 80285660 ffffe000 84cc7240 0000000a 851e8000
9f40: 84cc7240 6759df8c 00000000 84cc7240 883c0a28 883c0800 00000000 6759df8c
9f60: 851e9fb0 846f6780 846f6780 00000000 00000000 80100264 851e8000 80271d80
9f80: 00000000 00000000 80100264 6759df8c 00000006 00000006 02082100 76fa65a0
9fa0: 00000004 80100240 00000006 02082100 00000001 02082100 00000006 00000000
9fc0: 00000006 02082100 76fa65a0 00000004 00000006 0058cc00 00000000 00000000
9fe0: 00000004 7e8729c8 76ec06e7 76e41ae6 40010030 00000001 00000000 00000000
[<809266e0>] (imx_mu_xcr_rmw) from [<000007ff>] (0x7ff)
Code: ebdfb925 e5845000 e3a00000 e8bd8070 (e92d47f0)
---[ end trace 15ec0de3866fc2d9 ]---
note: sh[371] exited with preempt_count 1
Segmentation fault
@jlh-makeen Yes I have Yocto Kirkstone. Linux Kernel version 5.15.52.
What about your device vendor? Do u have qspi (I dont have in my imx7d-pico by TechNexion)? Do u have debug port? (I don
t have).
Why I can`t see vdev0buffer in result of the cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories And cat /sys/kernel/debug/remoteproc/remoteproc0/resource_table commands?
M4 Side is not completely inert. Some main start-of-function messages are shown. But it never shows the hello-world from the imx_rpmsg_tty driver nor the messages from the rpmsg_client_sample driver
What are you trying to do? Maybe like me I want to echo > test /dev/ttyRPMSG using Zephyr's openamp_rsc_table so we can work together on this
We are trying to achieve the same goal which is have /dev/ttyRPMSG up in Linux to talk to the M4 chip.
We are using the Compulab vendor with their CL-SOM-IMX7. The module is a 1GB Ram variant. We have placed the sh_men area at the end of the 1GB.
But their BSP is outdated and is using the linux kernel lf-5.10.y with vendor patches: https://github.com/compulab-yokneam/meta-bsp-imx7/tree/kirkstone
We also have a custom carrier board with 4x RS485 ports used by the Cortex M and 1x UART for the Cortex A.
My kernel at the moment:
Linux cl-som-imx7 5.10.9 #1
As per my colleague who is responsible for the Linux yocto image, the generic ttyRPMSG driver, mentionned by the openamp_rsc_table sample was introduced in Linux 5.16 (CONFIG_TTY_RPMSG).
I'm using this Zephyr version, before the switch to v2 boards/soc directory structure.
*** Booting Zephyr OS build v3.6.0-294-gec089ac5c251 ***
-> My DT on zephyr side, we boot from OCRAM at 0x0901000
/ {
model = "Compulab CL-SOM-IMX7d on Makeen Datagateway carrier";
compatible = "nxp,mcimx7d_m4";
chosen {
zephyr,flash = &ocram_code_linux; /*&tcml_code;*/
zephyr,sram = &tcmu_sys;
zephyr,console = &uart2;
zephyr,shell-uart = &uart2;
zephyr,ipc_shm = &ddr_shm;
zephyr,ipc = &mub;
};
ddr_shm: memory1@bff00000 {
compatible = "mmio-sram";
/* use DDR_SYS area as mmio, 0xbff00000 0x100000 */
reg = <0xbff00000 0x100000>;
status = "okay";
};
...
soc {
ocram_code_linux: code@901000 {
compatible = "nxp,imx-code-bus";
reg = <0x00901000 DT_SIZE_K(124)>;
};
};
Regarding the A7 device tree:
mu@30aa0000 {
compatible = "fsl,imx7d-mu\0fsl,imx6sx-mu";
reg = <0x30aa0000 0x10000>;
interrupts = <0x00 0x58 0x04>;
clocks = <0x01 0x1b1>;
clock-names = "mu";
#mbox-cells = <0x02>;
phandle = <0x4a>;
};
mu@30ab0000 {
compatible = "fsl,imx7d-mu\0fsl,imx6sx-mu";
reg = <0x30ab0000 0x10000>;
interrupts = <0x00 0x61 0x04>;
clocks = <0x01 0x1b1>;
clock-names = "mu";
#mbox-cells = <0x02>;
phandle = <0x60>;
};
...
rpmsg {
compatible = "fsl,imx7d-rpmsg";
mbox-names = "tx\0rx\0rxdb";
mboxes = <0x4a 0x00 0x01 0x4a 0x01 0x01 0x4a 0x03 0x01>;
status = "okay";
};
...
reserved-memory {
#address-cells = <0x01>;
#size-cells = <0x01>;
ranges;
cm4tcmcode@7f8000 {
compatible = "shared-dma-pool";
reg = <0x7f8000 0x8000>;
no-map;
phandle = <0x57>;
};
cm4sramcode@901000 {
compatible = "shared-dma-pool";
reg = <0x901000 0x40000>;
no-map;
phandle = <0x58>;
};
vdev0vring0@bff00000 {
compatible = "shared-dma-pool";
reg = <0xbff00000 0x1000>;
no-map;
phandle = <0x61>;
};
vdev0vring1@bff01000 {
compatible = "shared-dma-pool";
reg = <0xbff01000 0x1000>;
no-map;
phandle = <0x62>;
};
vdev0buffer@bff02000 {
compatible = "shared-dma-pool";
reg = <0xbff02000 0xfe000>;
no-map;
phandle = <0x56>;
};
};
imx7d-cm4 {
compatible = "fsl,imx7d-cm4";
mbox-names = "tx", "rx", "rxdb";
mboxes = <0x60 0x00 0x01 0x60 0x01 0x01 0x60 0x03 0x01>;
memory-region = <0x56 0x61 0x62 0x57 0x58>;
syscon = <0x23>;
clocks = <0x01 0x42>;
};
And the carveout/ressource tables outputs:
root@cl-som-imx7:/# cat /sys/kernel/debug/remoteproc/remoteproc0/resource_table
Entry 0 is of type vdev
ID 7
Notify ID 0
Device features 0x1
Guest features 0x1
Config length 0x0
Status 0x7
Number of vrings 2
Reserved (should be zero) [0][0]
Vring 0
Device Address 0xbff00000
Alignment 16
Number of buffers 8
Notify ID 0
Physical Address 0x0
Vring 1
Device Address 0xbff01000
Alignment 16
Number of buffers 8
Notify ID 1
Physical Address 0x0
root@cl-som-imx7:/# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdev0buffer
Virtual address: dd5cdfbe
DMA address: 0xbff02000
Device address: 0xbff02000
Length: 0xfe000 Bytes
Carveout memory entry:
Name: vdev0vring0
Virtual address: 473e2d00
DMA address: 0xbff00000
Device address: 0xbff00000
Length: 0x1000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: 8d625bae
DMA address: 0xbff01000
Device address: 0xbff01000
Length: 0x1000 Bytes
Carveout memory entry:
Name: cm4tcmcode
Virtual address: 02e0dcc6
DMA address: 0x007f8000
Device address: 0x7f8000
Length: 0x8000 Bytes
Carveout memory entry:
Name: cm4sramcode
Virtual address: 3ecff66e
DMA address: 0x00901000
Device address: 0x901000
Length: 0x40000 Bytes
@jlh-makeen
You said: _"As per my colleague who is responsible for the Linux yocto image, the generic ttyRPMSG driver, mentionned by the openamp_rsc_table sample was introduced in Linux 5.16 (CONFIG_TTYRPMSG)."
I never knew anything about it. If you could provide more details, I would appreciate it.
@neuberfran
I managed to fix my driver crashing and can now start my M4 processor correctly and have rproc probe the core and kick the MU.
root@cl-som-imx7:/lib/firmware# ./boot_m4.sh zephyr_pnet_ipm.elf
./boot_m4.sh: line 1: echo: writeremoteproc remoteproc0: powering up imx-rproc
error: Invalid argument
remoteproc remoteproc0: Booting fw image zephyr_pnet_ipm.elf, size 1638784
rproc_elf_load_segments: So... booting from OCRAM on IMX7 ??? Grabbing PC and SP for you...
rproc_elf_load_segments: SP: 0x20003348 PC: 0x009086a1
rproc_elf_load_segments: APPLYING TEMPORARY HACK TO GET SP AND PC LOADED INTO M4 BOOT VECTOR
remoteproc0#vdev0buffer: vdev 0 buffer already mapped
virtio_rpmsg_bus virtio0: rpmsg host is online
remoteproc0#vdev0buffer: registered virtio0 (type 7)
remoteproc remoteproc0: remote processor imx-rproc is now up
root@cl-som-imx7:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/resource_table
Entry 0 is of type vdev
ID 7
Notify ID 0
Device features 0x1
Guest features 0x1
Config length 0x0
Status 0x7
Number of vrings 2
Reserved (should be zero) [0][0]
Vring 0
Device Address 0xbff00000
Alignment 16
Number of buffers 64
Notify ID 0
Physical Address 0x0
Vring 1
Device Address 0xbff01000
Alignment 16
Number of buffers 64
Notify ID 1
Physical Address 0x0
root@cl-som-imx7:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdev0buffer
Virtual address: 34229b00
DMA address: 0xbff02000
Device address: 0xbff02000
Length: 0xfe000 Bytes
Carveout memory entry:
Name: vdev0vring0
Virtual address: 9abcaa63
DMA address: 0xbff00000
Device address: 0xbff00000
Length: 0x1000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: bc7cb9f6
DMA address: 0xbff01000
Device address: 0xbff01000
Length: 0x1000 Bytes
Carveout memory entry:
Name: cm4tcmcode
Virtual address: 5f71bfd0
DMA address: 0x007f8000
Device address: 0x7f8000
Length: 0x8000 Bytes
Carveout memory entry:
Name: cm4sramcode
Virtual address: 9f061b54
DMA address: 0x00901000
Device address: 0x901000
Length: 0x40000 Bytes
Yes, up until 5.15 we had the imx_rpmsg_tty driver but there was introduced a new more generic one as rpmsg_tty from 5.16. Not sure it has more feature though.
Check out the nxp/linux-imx repo, latest revision: https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/drivers/tty/rpmsg_tty.c
Which is different from: https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/drivers/rpmsg/imx_rpmsg_tty.c
It is now part of the imx_v8_defconfig file: https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/arch/arm64/configs/imx_v8_defconfig#L959
I'm also suspecting that something is missing in about the NS annoucement in the RPMSG on Linux. because the Zephyr side sends some NS annoucements for RPMSG_TTY and RPMSG_CLIENT_SAMPLE endpoints. Therefore my guess is that these should wakeup the right driver that should get probed and mounted by the system.
/* from zephyrproject/lib/open-amp/lib/rpmsg/rpmsg.c */
int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
const char *name, uint32_t src, uint32_t dest,
rpmsg_ept_cb cb, rpmsg_ns_unbind_cb unbind_cb)
{
int status = RPMSG_SUCCESS;
uint32_t addr = src;
...
/* Send NS announcement to remote processor */
if (ept->name[0] && rdev->support_ns &&
ept->dest_addr == RPMSG_ADDR_ANY)
status = rpmsg_send_ns_message(ept, RPMSG_NS_CREATE);
...
}
Here is an associated driver source that listens to annoucements: https://github.com/nxp-imx/linux-imx/blob/lf-6.6.y/drivers/rpmsg/rpmsg_ns.c
Here is a hint that may indicate that I'm right about the NS annoucement thing:
Linux lf 6.6.y:
The tty_rpmsg and imx_rpmsg_tty don't use the same annoucement id's.
And guess what, the Zephyr implementation uses the "rpmsg-tty" channel id:
@jlh-makeen
You have a lot of useful knowledge.
Please help me more on my imx7d-pico (Remoteproc and echo test > /dev/ttyRPMSG regarding mounting the DT and the zephyr overlay file: https://docs.zephyrproject.org/latest/boards/technexion/pico_pi/doc/index.html https://gist.github.com/neuberfran/389a5eb620ccad6e5694816d3ba43de8 https://www.nxp.com/docs/en/application-note/AN5317.pdf There is this undefined question about less to m4: https://community.toradex.com/t/is-it-possible-to-increase-the-m4-memory-in-the-vf61/5591/6 And about why it starts at 0x1ff00000 and not 0x20000000: https://community.nxp.com/t5/Other-NXP-Products/RPMsg-in-imx7d-Why-0x1FF00000-and-Not-0x10000000-in-linux-usable/m-p/1805773#M21111
As you will see below, I am now focusing on using OCRAM (0X00901000 using F000) and not 9FF00000 in Remoteproc. Is it right? My last DT on A7-M4-Linux Kirkstone Side is this (I have rpmsg_ctrl0 and rpmsg_ctrl1, but I never have /dev/ttyRPMSG):
/*
* Copyright 2018 TechNexion Ltd.
*
* Author: Tapani Utriainen <tapani@technexion.com>
* Richard Hu <richard.hu@technexion.com>
* Ray Chang <ray.chang@technexion.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include "imx7d-pico-pi-qca.dts"
/ {
memory {
linux,usable-memory = <0x80000000 0x1ff00000>;
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
// mailbox_reserved: vrings0@30ab0000 {
// reg = <0x30ab0000 0x10000>;
// no-map;
// };
// m4_reserved: m4@8ff00000 {
// reg = <0x8ff00000 0x100000>;
// no-map;
// };
vdev0vring0: vdev0vring0@00902000 {
compatible = "shared-dma-pool";
// compatible = "shared-dma-pool";
// reg = <0x9ff00000 0x8000>;
reg = <0x00902000 0x2000>;
no-map;
};
vdev0vring1: vdev0vring1@00904000 {
compatible = "shared-dma-pool";
// compatible = "shared-dma-pool";
// reg = <0x9ff08000 0x8000>;
reg = <0x00904000 0x2000>;
no-map;
};
// rsc_table: rsc_table@900ff000 {
// reg = <0x900ff000 0x1000>;
// no-map;
// };
vdev0buffer: vdev0buffer@00906000 {
compatible = "shared-dma-pool";
// reg = <0x9ff10000 0x80000>;
reg = <0x00906000 0x9C40>;
no-map;
};
// vdev0vring0: vdev0vring0@8ff00000 {
// compatible = "shared-dma-pool";
// // compatible = "shared-dma-pool";
// reg = <0x8ff00000 0x8000>;
// no-map;
// };
// vdev0vring1: vdev0vring1@8ff08000 {
// compatible = "shared-dma-pool";
// // compatible = "shared-dma-pool";
// reg = <0x8ff08000 0x8000>;
// no-map;
// };
// // rsc_table: rsc_table@900ff000 {
// // reg = <0x900ff000 0x1000>;
// // no-map;
// // };
// vdev0buffer: vdev0buffer@8ff10000 {
// compatible = "shared-dma-pool";
// reg = <0x8ff10000 0x80000>;
// no-map;
// };
cm4tcmcode: cm4tcmcode@0x7f8000 {
compatible = "shared-dma-pool";
reg = <0x007f8000 0x8000>;
no-map;
};
// cm4sramcode: cm4sramcode@0x900000 {
// compatible = "shared-dma-pool";
// reg = <0x00900000 0x40000>;
// no-map;
// };
};
imx7d-cm4 {
compatible = "fsl,imx7d-cm4";
clocks = <&clks IMX7D_ARM_M4_ROOT_CLK>;
// fsl,auto-boot;
mbox-names = "tx0", "rx0", "rxdb0";
mboxes = <&mub 0 1
&mub 1 1
&mub 3 1>;
// memory-region = <&rpmsg_vrings>, <&cm4tcmcode>, <&cm4sramcode>;
memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>;
fsl,rproc-auto-boot = <1>;
fsl,rproc-fw-name="zephyr_openamp_rsc_table.elf";
syscon = <&src>;
status = "okay";
};
m4_tcm: tcml@007f8000 {
compatible = "fsl, m4_tcml";
reg = <0x007f8000 0x8000>;
};
gpio-leds {
status = "disabled";
};
};
&adc1 {
status = "disabled";
};
&adc2 {
status = "disabled";
};
&gpt3 {
status = "disabled";
};
&gpt4 {
status = "disabled";
};
&ocram {
reg = <0x00901000 0xf000>;
};
&rpmsg{
vdev-nums = <1>;
// memory-region = <&vdev0buffer>;
// memory-region = <&vdev0vring0>, <&vdev0vring1>, <&vdevbuffer>, <&cm4tcmcode>, <&cm4sramcode>;
reg = <0x9fff0000 0x10000>;
status = "okay"; // Tava disabled
};
&uart6 {
status = "disabled";
};
&mub {
status = "okay";
};
&wdog3{
status = "disabled";
};
And this is my overlay on zephyr and other settings:
/*
* Copyright (c) 2023 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
/ {
chosen {
/*
* shared memory reserved for the inter-processor communication
*/
zephyr,ipc_shm = &ocramfake;
zephyr,ipc = &mub;
};
ocramfake: memory@00901000 {
compatible = "mmio-sram";
reg = <0x00901000 0xf000>;
};
// ocramfake: memory@8ff00000 {
// compatible = "mmio-sram";
// reg = <0x8ff00000 0x110000>;
// };
};
&mub {
status = "okay";
};
CONFIG_KERNEL_BIN_NAME="zephyr_openamp_rsc_table"
CONFIG_PRINTK=n
CONFIG_IPM=y
CONFIG_MAIN_STACK_SIZE=1024
CONFIG_HEAP_MEM_POOL_SIZE=1024
CONFIG_OPENAMP=y
CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF=16
CONFIG_OPENAMP_RSC_TABLE=y
CONFIG_OPENAMP_MASTER=n
CONFIG_LOG_PRINTK=n
CONFIG_IPM_IMX_MAX_DATA_SIZE_16=n
CONFIG_IPM_IMX_MAX_DATA_SIZE_4=y
#CONFIG_OPENAMP_WITH_DCACHE=y
CmakeLists.txt
zephyr_sources(
soc.c
soc_clk_freq.c
)
if(CONFIG_OPENAMP_RSC_TABLE)
zephyr_linker_section(NAME .resource_table GROUP ROM_REGION NOINPUT)
zephyr_linker_section_configure(SECTION .resource_table KEEP INPUT ".resource_table*")
endif()
#set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "")
# iMX7 M4 core series
# Copyright (c) 2017, NXP
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_IMX7_M4
config SOC_SERIES
default "mcimx7_m4"
# config IPM_IMX
# bool
# default y
# depends on IPM && SOC_MCIMX7_M4 && SOC_SERIES_IMX7_M4
config NUM_IRQS
# must be >= the highest interrupt number used
default 127
config PINCTRL_IMX
default y if HAS_IMX_IOMUXC
depends on PINCTRL
source "soc/arm/nxp_imx/mcimx7_m4/Kconfig.defconfig.mcimx7_m4"
endif # SOC_SERIES_IMX7_M4
#include <zephyr/arch/arm/cortex_m/scripts/linker.ld>
SECTIONS
{
#ifdef CONFIG_OPENAMP_RSC_TABLE
SECTION_PROLOGUE(.resource_table,, SUBALIGN(4))
{
KEEP(*(.resource_table*))
} GROUP_LINK_IN(ROMABLE_REGION)
#endif
}
Are you using ipm_imx_rev2??? Or not?
root@scorpion:/sys/bus/virtio/devices# ls /dev/rpmsg*
/dev/rpmsg_ctrl0 /dev/rpmsg_ctrl1
root@scorpion:/sys/bus/virtio/devices# dmesg | grep -i "virtio"
[ 0.134883] virtio_rpmsg_bus virtio0: rpmsg host is online
[ 55.904751] virtio_rpmsg_bus virtio1: rpmsg host is online
[ 55.912441] remoteproc0#vdev0buffer: registered virtio1 (type 7)
root@scorpion:/sys/bus/virtio/devices# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdev0vring0
Virtual address: 26d194e1
DMA address: 0x00902000
Device address: 0x902000
Length: 0x2000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: d8145475
DMA address: 0x00904000
Device address: 0x904000
Length: 0x2000 Bytes
root@scorpion:/sys/bus/virtio/devices# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdev0vring0
Virtual address: 26d194e1
DMA address: 0x00902000
Device address: 0x902000
Length: 0x2000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: d8145475
DMA address: 0x00904000
Device address: 0x904000
Length: 0x2000 Bytes
root@scorpion:/lib/firmware# modprobe rpmsg_client_sample && modprobe imx_rpmsg_tty
[ 52.776939] NLB imx_rpmmsg_tty
root@scorpion:/lib/firmware# echo start > /sys/class/remoteproc/remoteproc0/state
[ 58.498550] remoteproc remoteproc0: powering up imx-rproc
[ 58.522741] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 660180
[ 58.531721] remoteproc0#vdev0buffer: assigned reserved memory node vdev0buffer@00906000
[ 58.543938] virtio_rpmsg_bus virtio1: rpmsg host is online
[ 58.551535] remoteproc0#vdev0buffer: registered virtio1 (type 7)
[ 58.557738] remoteproc remoteproc0: remote processor imx-rproc is now u
Please, Look it. Nothing about virtio0 (type 7) (this, immediately above.) And And nothing about vdev0buffer in the cat results
@neuberfran
Well it's hard to tell because I've not gotten /dev/ttyRPMSG to appear on my system yet.
I don't see errors in when you start the M4 core though, so that's a first good thing.
I'm not sure if the shared memories and vrings can reside in the OCRAM region 0x009xxxxx.
On our system we have put them in DDR area at address 0xBFF00000 since we only have 1GB of RAM (from 0x80000000 to 0xBFFFFFFF). The nice thing is that when using the DDR, the addresses are the same on A7 and M4 "System bus". (aka from 0x80000000)
I believe you are accessing the sh_mem on the "System bus" aka as RAM and not CODE. Therefore pay attention to the addresses. I think that if you use the OCRAM, you need to change your Zephyr shared memory address to the matching in 0x20200000's.
Maybe I'm wrong, but I'd suggest you use DDR instead of OCRAM.
If you have 1GB ram, use 0xBFF00000, if you have 512MB, use 0x9FF00000 In your case it would probably look something like this:
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
vdev0vring0: vdev0vring0@9ff00000 {
compatible = "shared-dma-pool";
reg = <0x9ff00000 0x1000>;
no-map;
};
vdev0vring1: vdev0vring1@9ff01000 {
compatible = "shared-dma-pool";
reg = <0x9ff01000 0x1000>;
no-map;
};
vdev0buffer: vdev0buffer@9ff02000 {
compatible = "shared-dma-pool";
reg = <0x9ff02000 0xfe000>;
no-map;
};
cm4tcmcode: cm4tcmcode@0x7f8000 {
compatible = "shared-dma-pool";
reg = <0x007f8000 0x8000>;
no-map;
};
cm4sramcode: cm4sramcode@0x900000 {
compatible = "shared-dma-pool";
reg = <0x00900000 0x40000>;
no-map;
};
};
@jlh-makeen I have 1gb here (imx7d-pico with 1gb Model and not 512mb model)
Are you using ipm_imx_rev2??? Or not?
For a better basis, we have this updated an5317: https://www.nxp.com/docs/en/application-note/AN5317.pdf
@jlh-makeen I have 1gb here (imx7d-pico with 1gb Model and not 512mb model)
Are you using ipm_imx_rev2??? Or not?
For a better basis, we have this updated an5317: https://www.nxp.com/docs/en/application-note/AN5317.pdf
I don't believe we are using IPM_IMX_REV2 no.
@jlh-makeen https://community.st.com/t5/stm32cubeide-mpus/decreasing-rpmsg-buffer-size-to-256-bytes-on-linux-kernel-will/td-p/112073 Do you think I will have to make changes to the linux/remoteproc driver files like:
below = imx_rpmsg_tty.c
#define RPMSG_MAX_SIZE 256
below = imx_rpmsg.c
``
RPMSG_VRING_ALIGN), PAGE_SIZE)) * PAGE_SIZE)
rpdev->ivdev[i]->vring[0] = start; rpdev->ivdev[i]->vring[1] = start + 0x8000; start += 0x10000;
**below = virtio_rpmsg_bus.c**
**My last DT on A7-M4-Linux Kirkstone Side is this (I have rpmsg_ctrl0 and rpmsg_ctrl1, but I never have /dev/ttyRPMSG):**
@neuberfran
I'm sorry I'm no sure if this will be useful.
One thing my colleague pointed out is that the function virtqueue_get_available_buffer() fails on my zephyr program:
This could explain why the Name Service (NS) notification don't wakeup the drivers in Linux (as for my case at least).
Here is what I can log from my zephyr appplication:
OpenAMP[remote] Linux responder demo started
metal_init
:metal_register_generic_device
:metal_device_open
:metal_io_init
:metal_device_io_region
:rsc_table_get
:metal_io_init
:metal_device_io_region
:device_is_ready
[00:00:00.541,000] \x1B[0m<dbg> openamp_rsc_table: platform_ipm_callback: platform_ipm_callback: msg received from mb 1
\x1B[0m
:ipm_set_enabled
:platform_init
rproc_virtio_create_vdev
rproc_virtio_create_vdev
rproc_virtio_init_vring0 : 0xbff00000 / 64
rproc_virtio_init_vring1: 0xbff01000 / 64
rpmsg_init_vdev
:platform_create_rpmsg_vdev
[00:00:00.542,000] \x1B[0m<dbg> openamp_rsc_table: receive_message: recv message
\x1B[0m
ERR: virtqueue_get_available_buffer
OpenAMP[remote] Linux sample client responder started
[00:00:00.602,000] \x1B[0m<dbg> openamp_rsc_table: mailbox_notify: mailbox_notify: msg received -> priv:(nil) id:0
\x1B[0m
Endpoint rpmsg-client-sample created: res:0 support_ns: 1
OpenAMP[remote] Linux TTY responder started
[00:00:00.602,000] \x1B[0m<dbg> openamp_rsc_table: mailbox_notify: mailbox_notify: msg received -> priv:(nil) id:0
\x1B[0m
Endpoint rpmsg-tty created: res:0 support_ns: 1
EDIT: Well I've added some printk statements here and there in my Zephyr openamp:
OpenAMP[remote] Linux responder demo started
metal_init
:metal_register_generic_device
:metal_device_open
:metal_io_init
:metal_device_io_region
:rsc_table_get
:metal_io_init
:metal_device_io_region
:device_is_ready
[00:00:00.542,000] \x1B[0m<dbg> openamp_rsc_table: platform_ipm_callback: platform_ipm_callback: msg received from mb 1
\x1B[0m
:ipm_set_enabled
:platform_init
rproc_virtio_create_vdev
rproc_virtio_create_vdev
rproc_virtio_init_vring0 : 0xbff00000 / 64
rproc_virtio_init_vring1: 0xbff01000 / 64
rpmsg_init_vdev
:platform_create_rpmsg_vdev
[00:00:00.542,000] \x1B[0m<dbg> openamp_rsc_table: receive_message: recv message
\x1B[0m
ERR: virtqueue_get_available_buffer
OpenAMP[remote] Linux sample client responder started
DBG: rpmsg_send_offchannel_raw: ept->name:rpmsg-client-sample src:400 dst:35
DBG: virtqueue_get_available_buffer : buffer: 0xbff02000
DBG: rpmsg_virtio_get_tx_payload_buffer : rp_hdr: 0xbff02000
[00:00:00.602,000] \x1B[0m<dbg> openamp_rsc_table: mailbox_notify: mailbox_notify: msg received -> priv:(nil) id:0
\x1B[0m
DBG: rpmsg_create_ept: ept->name:rpmsg-client-sample support_ns:1 ept->dest_addr:ffffffff
Endpoint rpmsg-client-sample created: res:0 support_ns: 1
OpenAMP[remote] Linux TTY responder started
DBG: rpmsg_send_offchannel_raw: ept->name:rpmsg-virtual-tty-channel src:401 dst:35
DBG: virtqueue_get_available_buffer : buffer: 0xbff02200
DBG: rpmsg_virtio_get_tx_payload_buffer : rp_hdr: 0xbff02200
[00:00:00.603,000] \x1B[0m<dbg> openamp_rsc_table: mailbox_notify: mailbox_notify: msg received -> priv:(nil) id:0
\x1B[0m
DBG: rpmsg_create_ept: ept->name:rpmsg-virtual-tty-channel support_ns:1 ept->dest_addr:ffffffff
Endpoint rpmsg-tty created: res:0 support_ns: 1
I can see that the buffers are correctly taken from the vdev0buffer reserved memory which is 0xbff02000 and onwards. The rpmsg channel names and are correctly passed to the endpoints and the mailbox notify function is called which should kick the A7 mailbox and let Linux handle the NS annoucements to get the drivers and tty running.
But nothing else happens on the Linux side unfortunately. I'm wondering if it is due to the first buffer fail I'm seeing. I'll investigate more about this.
@jlh-makeen
Unfortunately, I still don't have carveout for vdev0buffer And /dev/ttyRPMSG.
pico_pi_m4.overlay
/ {
chosen {
/*
* shared memory reserved for the inter-processor communication
*/
zephyr,ipc_shm = &ocramfake;
zephyr,ipc = &mub;
};
ocramfake: memory@9ff00000 {
compatible = "mmio-sram";
reg = <0x9ff0000 0x100000>;
// I tried with 0x110000 and with 0x100000
};
// ocramfake: memory@8ff00000 {
// compatible = "mmio-sram";
// reg = <0x8ff00000 0x110000>;
// };
};
&mub {
status = "okay";
};
imx7d-pico-pi-qca-m4.dts
/*
* Copyright 2018 TechNexion Ltd.
*
* Author: Tapani Utriainen <tapani@technexion.com>
* Richard Hu <richard.hu@technexion.com>
* Ray Chang <ray.chang@technexion.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include "imx7d-pico-pi-qca.dts"
/ {
memory {
linux,usable-memory = <0x80000000 0x1ff00000>;
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
vdev0vring0: vdev0vring0@9ff00000 {
compatible = "shared-dma-pool";
reg = <0x9ff00000 0x1000>;
no-map;
};
vdev0vring1: vdev0vring1@9ff01000 {
compatible = "shared-dma-pool";
reg = <0x9ff01000 0x1000>;
no-map;
};
vdev0buffer: vdev0buffer@9ff02000 {
compatible = "shared-dma-pool";
reg = <0x9ff02000 0xfe000>;
no-map;
};
cm4tcmcode: cm4tcmcode@0x7f8000 {
compatible = "shared-dma-pool";
reg = <0x007f8000 0x8000>;
no-map;
};
cm4sramcode: cm4sramcode@0x900000 {
compatible = "shared-dma-pool";
reg = <0x00900000 0x40000>;
no-map;
};
};
// vdev0vring0: vdev0vring0@00902000 {
// compatible = "shared-dma-pool";
// // compatible = "shared-dma-pool";
// // reg = <0x9ff00000 0x8000>;
// reg = <0x00902000 0x2000>;
// no-map;
// };
// vdev0vring1: vdev0vring1@00904000 {
// compatible = "shared-dma-pool";
// // compatible = "shared-dma-pool";
// // reg = <0x9ff08000 0x8000>;
// reg = <0x00904000 0x2000>;
// no-map;
// };
// vdev0buffer: vdev0buffer@00906000 {
// compatible = "shared-dma-pool";
// // reg = <0x9ff10000 0x80000>;
// reg = <0x00906000 0x9C40>;
// no-map;
// };
// cm4tcmcode: cm4tcmcode@0x7f8000 {
// compatible = "shared-dma-pool";
// reg = <0x007f8000 0x8000>;
// no-map;
// };
// };
imx7d-cm4 {
compatible = "fsl,imx7d-cm4";
clocks = <&clks IMX7D_ARM_M4_ROOT_CLK>;
// fsl,auto-boot;
mbox-names = "tx0", "rx0", "rxdb0";
mboxes = <&mub 0 1
&mub 1 1
&mub 3 1>;
// memory-region = <&rpmsg_vrings>, <&cm4tcmcode>, <&cm4sramcode>;
memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&cm4tcmcode>, <&cm4sramcode>;
fsl,rproc-auto-boot = <1>;
fsl,rproc-fw-name="zephyr_openamp_rsc_table.elf";
syscon = <&src>;
status = "okay";
};
m4_tcm: tcml@007f8000 {
compatible = "fsl, m4_tcml";
reg = <0x007f8000 0x8000>;
};
gpio-leds {
status = "disabled";
};
};
&adc1 {
status = "disabled";
};
&adc2 {
status = "disabled";
};
&gpt3 {
status = "disabled";
};
&gpt4 {
status = "disabled";
};
&ocram {
reg = <0x00901000 0xf000>;
};
&rpmsg{
vdev-nums = <1>;
// memory-region = <&vdev0buffer>;
// memory-region = <&vdev0vring0>, <&vdev0vring1>, <&vdevbuffer>, <&cm4tcmcode>, <&cm4sramcode>;
reg = <0x9fff0000 0x10000>;
status = "okay"; // Tava disabled
};
&uart6 {
status = "disabled";
};
&mub {
status = "okay";
};
&wdog3{
status = "disabled";
};
root@scorpion:/lib/firmware# modprobe rpmsg_client_sample && modprobe imx_rpmsg_tty
[ 86.807476] NLB imx_rpmmsg_tty
root@scorpion:/lib/firmware# echo start > /sys/class/remoteproc/remoteproc0/state
[ 92.828659] remoteproc remoteproc0: powering up imx-rproc
[ 92.852848] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 660180
[ 92.861895] remoteproc0#vdev0buffer: assigned reserved memory node vdev0buffer@9ff02000
[ 92.875105] virtio_rpmsg_bus virtio1: rpmsg host is online
[ 92.882776] remoteproc0#vdev0buffer: registered virtio1 (type 7)
[ 92.889343] remoteproc remoteproc0: remote processor imx-rproc is now up
root@scorpion:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/resource_table
Entry 0 is of type vdev
ID 7
Notify ID 0
Device features 0x1
Guest features 0x1
Config length 0x0
Status 0x7
Number of vrings 2
Reserved (should be zero) [0][0]
Vring 0
Device Address 0x9ff00000
Alignment 16
Number of buffers 16
Notify ID 0
Physical Address 0x0
Vring 1
Device Address 0x9ff01000
Alignment 16
Number of buffers 16
Notify ID 1
Physical Address 0x0
root@scorpion:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdev0vring0
Virtual address: 7b0edb64
DMA address: 0x9ff00000
Device address: 0x9ff00000
Length: 0x1000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: 7c87c534
DMA address: 0x9ff01000
Device address: 0x9ff01000
Length: 0x1000 Bytes
Carveout memory entry:
Name: cm4tcmcode
Virtual address: 75013cd3
DMA address: 0x007f8000
Device address: 0x7f8000
Length: 0x8000 Bytes
Carveout memory entry:
Name: cm4sramcode
Virtual address: 243f5356
DMA address: 0x00900000
Device address: 0x900000
Length: 0x40000 Bytes
root@scorpion:/lib/firmware# ls /dev/r*
/dev/ram0 /dev/ram13 /dev/ram4 /dev/ram9 /dev/rpmsg_ctrl1
/dev/ram1 /dev/ram14 /dev/ram5 /dev/random /dev/rtc
/dev/ram10 /dev/ram15 /dev/ram6 /dev/remoteproc0 /dev/rtc0
/dev/ram11 /dev/ram2 /dev/ram7 /dev/rfkill
/dev/ram12 /dev/ram3 /dev/ram8 /dev/rpmsg_ctrl0
root@scorpion:/lib/firmware# ls /dev/tty*
/dev/tty /dev/tty19 /dev/tty3 /dev/tty40 /dev/tty51 /dev/tty62
/dev/tty0 /dev/tty2 /dev/tty30 /dev/tty41 /dev/tty52 /dev/tty63
/dev/tty1 /dev/tty20 /dev/tty31 /dev/tty42 /dev/tty53 /dev/tty7
/dev/tty10 /dev/tty21 /dev/tty32 /dev/tty43 /dev/tty54 /dev/tty8
/dev/tty11 /dev/tty22 /dev/tty33 /dev/tty44 /dev/tty55 /dev/tty9
/dev/tty12 /dev/tty23 /dev/tty34 /dev/tty45 /dev/tty56 /dev/ttymxc4
/dev/tty13 /dev/tty24 /dev/tty35 /dev/tty46 /dev/tty57 /dev/ttymxc6
/dev/tty14 /dev/tty25 /dev/tty36 /dev/tty47 /dev/tty58
/dev/tty15 /dev/tty26 /dev/tty37 /dev/tty48 /dev/tty59
/dev/tty16 /dev/tty27 /dev/tty38 /dev/tty49 /dev/tty6
/dev/tty17 /dev/tty28 /dev/tty39 /dev/tty5 /dev/tty60
/dev/tty18 /dev/tty29 /dev/tty4 /dev/tty50 /dev/tty61
root@scorpion:/lib/firmware#
root@scorpion:/lib/firmware# dmesg | grep -i "remoteproc"
[ 2.139313] remoteproc remoteproc0: imx-rproc is available
[ 2.159148] remoteproc remoteproc0: attaching to imx-rproc
[ 2.164721] remoteproc remoteproc0: remote processor imx-rproc is now attached
[ 27.148570] remoteproc remoteproc0: stopped remote processor imx-rproc
[ 92.828659] remoteproc remoteproc0: powering up imx-rproc
[ 92.852848] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 660180
[ 92.861895] remoteproc0#vdev0buffer: assigned reserved memory node vdev0buffer@9ff02000
[ 92.882776] remoteproc0#vdev0buffer: registered virtio1 (type 7)
[ 92.889343] remoteproc remoteproc0: remote processor imx-rproc is now up
root@scorpion:/lib/firmware# dmesg | grep -i "virtio0"
[ 0.134940] virtio_rpmsg_bus virtio0: rpmsg host is online
root@scorpion:/lib/firmware# dmesg | grep -i "virtio1"
[ 92.875105] virtio_rpmsg_bus virtio1: rpmsg host is online
[ 92.882776] remoteproc0#vdev0buffer: registered virtio1 (type 7)
root@scorpion:/lib/firmware# dmesg | grep -i "virtio0"
[ 0.134940] virtio_rpmsg_bus virtio0: rpmsg host is online
@neuberfran
So regarding the DT configs, Zephyr needs to use MU_B 0x30ab0000 and Linux needs to use MU_A 0x30aa0000.
Otherwise you get a ressource conflict.
@jlh-makeen Pls. Tell me Why I don't have vdev0buffer in Cat Carveout Cmd Result
@neuberfran
Portanto, com relação às configurações do DT, o Zephyr precisa usar MU_B 0x30ab0000 e o Linux precisa usar MU_A 0x30aa0000.
Caso contrário, você terá um conflito de recursos.
damn! Am I always doing it wrong using mub on Linux and Zephyr?
And what do you think about my mbox-namex (tx0, rx0, rxdb0 and not tx, rx, rxdb) and my mboxes (mub 0 1, mub 1 1 and mub 3 1)
I change my main.c in openamp_tsc_table Zephyr project to ret = rpmsg_create_ept(&tty_ept, rpdev, "rpmsg-virtual-tty-channel",
But not solved yet
I change 9ff00000 to bff00000 But not solved Yet (I can`t see vdev0buffer)
root@scorpion:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdev0vring0
Virtual address: b1a53eef
DMA address: 0xbff00000
Device address: 0xbff00000
Length: 0x1000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: 6aaff1bd
DMA address: 0xbff01000
Device address: 0xbff01000
Length: 0x1000 Bytes
Carveout memory entry:
Name: cm4tcmcode
Virtual address: 7c35a98b
DMA address: 0x007f8000
Device address: 0x7f8000
Length: 0x8000 Bytes
Carveout memory entry:
Name: cm4sramcode
Virtual address: c93cf8ec
DMA address: 0x00900000
Device address: 0x900000
Length: 0x40000 Bytes
@neuberfran
It looks mostly right, your zephyr side was missing a zero in the reg= <0x9ff00000...
But you know I'm not expert here and I still haven't got my ttyrpmsg to show up.
I would disable the rpsmg node as the rproc is also allocating the mailboxes and virtio rpmsg bus. Can you try disabling the "rpmsg" node and double check your addresses in DT ?
@jlh-makeen Tks. There was really a 0 missing. It still hasn't been resolved. I already tried disabling rpmsg but the imx_rproc driver gave an error without rpmsg. Unlike you, I'm using mu (for rpmsg) and mub in imx7d-cm4 (Remoteproc). Maybe that's why I couldn't disable rpmsg: And what do you think about my mbox-namex (tx0, rx0, rxdb0 and not tx, rx, rxdb) and my mboxes (mub 0 1, mub 1 1 and mub 3 1)?
@jlh-makeen Tks. There was really a 0 missing. It still hasn't been resolved. I already tried disabling rpmsg but the imx_rproc driver gave an error without rpmsg. Unlike you, I'm using mu (for rpmsg) and mub in imx7d-cm4 (Remoteproc). Maybe that's why I couldn't disable rpmsg: And what do you think about my mbox-namex (tx0, rx0, rxdb0 and not tx, rx, rxdb) and my mboxes (mub 0 1, mub 1 1 and mub 3 1)?
I believe this is correct for the mbox definitions
You can try with tx/rx/rxdb instead of rx0 etc.. but I don't think it will make a difference as rhe driver is looking up the prefixes tx/rx/rxdb therefore what's after like rx0 doesn't matter.
If thz driver didn't find the mboxes then it would complain in the dmesg logs.
See here: https://github.com/torvalds/linux/blob/master/drivers/mailbox/mailbox.c#L469
@jlh-makeen
I have some steps that I follow that might reveal the issue of /dev/ttyRPMSG not showing up:
1) west build --sysbuild -b pico_pi_m4 samples/subsys/ipc/openamp_rsc_table 1.1) sudo cp zephyr_openamp_rsc_table.bin /media/neuberfran/boot16 1.2) sudo cp zephyr_openamp_rsc_table.elf /media/neuberfran/root/lib/firmware/
I don't know if you are also doing step 1.1 (I would like to know) above, that is, copying the *.bin to the FAT/Uboot partition and starting at 0x7f800000.
So, if I give the command: cat /sys/class/remoteproc/remoteproc0/state I receive the attached message
@jlh-makeen
Since I don't have /dev/ttyRPMSG(just rpmsg_ctrl_0), can I transpose the code below to Python3 and use it to send messages to m4?
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/rpmsg.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(void)
{
char data_buf [] = {'a', 'b', 'c', 'd', 'e', '\0'};
struct rpmsg_endpoint_info ept_info = {"rpmsg-openamp-demo-channel", 0x2, 0x1};
int fd = open("/dev/rpmsg_ctrl0", O_RDWR);
/* create endpoint interface */
ioctl(fd, RPMSG_CREATE_EPT_IOCTL, &ept_info); // /dev/rpmsg0 is created
/* create endpoint */
int fd_ept = open("/dev/rpmsg0", O_RDWR); // backend creates endpoint
/* receive data from remote device */
read(fd_ept, &data_buf, sizeof(data_buf));
/* send data to remote device */
write(fd_ept, &data_buf, sizeof(data_buf));
/* destroy endpoint */
ioctl(fd_ept, RPMSG_DESTROY_EPT_IOCTL);
close(fd_ept);
close(fd);
}
Code source: https://developer.toradex.com/software/real-time/freertos/freertos-on-the-cortex-m4-of-a-colibri-imx7/
@jlh-makeen
Since I don't have /dev/ttyRPMSG(just rpmsg_ctrl_0), can I transpose the code below to Python3 and use it to send messages to m4?
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/rpmsg.h> #include <sys/ioctl.h> #include <unistd.h> int main(void) { char data_buf [] = {'a', 'b', 'c', 'd', 'e', '\0'}; struct rpmsg_endpoint_info ept_info = {"rpmsg-openamp-demo-channel", 0x2, 0x1}; int fd = open("/dev/rpmsg_ctrl0", O_RDWR); /* create endpoint interface */ ioctl(fd, RPMSG_CREATE_EPT_IOCTL, &ept_info); // /dev/rpmsg0 is created /* create endpoint */ int fd_ept = open("/dev/rpmsg0", O_RDWR); // backend creates endpoint /* receive data from remote device */ read(fd_ept, &data_buf, sizeof(data_buf)); /* send data to remote device */ write(fd_ept, &data_buf, sizeof(data_buf)); /* destroy endpoint */ ioctl(fd_ept, RPMSG_DESTROY_EPT_IOCTL); close(fd_ept); close(fd); }
Code source: https://developer.toradex.com/software/real-time/freertos/freertos-on-the-cortex-m4-of-a-colibri-imx7/
I believe you can transpose it to Python :)
Try to ask GPT to give you the code and post the resultd here I'm interested to see what you can do :)
I have an issue starting the M4 from uboot as it prevents my Linux from starting at this point. So more investigation is necessary on my side.
@jlh-makeen
In reality there are three things: First: In the code above, what is the line below for? (since I don't have it: rpmsg-openamp-demo-channe And /dev/ttyRPMSG)
` struct rpmsg_endpoint_info ept_info = {"rpmsg-openamp-demo-channel", 0x2, 0x1};`
Second: I still don't know why vdev0buffer doesn't appear in my case here, when I command cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Third: Technexion has Yocto mickledore in the very early testing phase, I've already tried it on two computers here, but the Yocto build always gives an error: https://github.com/TechNexion/tn-imx-yocto-manifest/issues/40
ERROR: linux-tn-imx-6.1.55+gitAUTOINC+4ce21f3007-r0 do_fetch: Fetcher failure: Fetch command export PSEUDO_DISABLED=1; export PATH="/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/sysroots-uninative/x86_64-linux/usr/bin:/home/neuberfran/edm_yocto/sources/poky/scripts:/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/work/pico_imx7-poky-linux-gnueabi/linux-tn-imx/6.1.55+gitAUTOINC+4ce21f3007-r0/recipe-sysroot-native/usr/bin/arm-poky-linux-gnueabi:/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/work/pico_imx7-poky-linux-gnueabi/linux-tn-imx/6.1.55+gitAUTOINC+4ce21f3007-r0/recipe-sysroot/usr/bin/crossscripts:/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/work/pico_imx7-poky-linux-gnueabi/linux-tn-imx/6.1.55+gitAUTOINC+4ce21f3007-r0/recipe-sysroot-native/usr/sbin:/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/work/pico_imx7-poky-linux-gnueabi/linux-tn-imx/6.1.55+gitAUTOINC+4ce21f3007-r0/recipe-sysroot-native/usr/bin:/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/work/pico_imx7-poky-linux-gnueabi/linux-tn-imx/6.1.55+gitAUTOINC+4ce21f3007-r0/recipe-sysroot-native/sbin:/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/work/pico_imx7-poky-linux-gnueabi/linux-tn-imx/6.1.55+gitAUTOINC+4ce21f3007-r0/recipe-sysroot-native/bin:/home/neuberfran/edm_yocto/sources/poky/bitbake/bin:/home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/hosttools"; export HOME="/home/neuberfran"; LANG=C git -c gc.autoDetach=false -c core.pager=cat clone --bare --mirror https://github.com/TechNexion/linux-tn-imx.git /home/neuberfran/edm_yocto/downloads//git2/github.com.TechNexion.linux-tn-imx.git --progress failed with exit code 128, no output
ERROR: linux-tn-imx-6.1.55+gitAUTOINC+4ce21f3007-r0 do_fetch: Bitbake Fetcher Error: FetchError('Unable to fetch URL from any source.', 'git://github.com/TechNexion/linux-tn-imx.git;protocol=https;branch=tn-imx_6.1.55_2.2.0-next')
ERROR: Logfile of failure stored in: /home/neuberfran/edm_yocto/build-wayland-pico-imx7/tmp/work/pico_imx7-poky-linux-gnueabi/linux-tn-imx/6.1.55+gitAUTOINC+4ce21f3007-r0/temp/log.do_fetch.22758
ERROR: Task (/home/neuberfran/edm_yocto/sources/meta-tn-imx-bsp/recipes-kernel/linux/linux-tn-imx_6.1.bb:do_fetch) failed with exit code '1'
NOTE: Tasks Summary: Attempted 1579 tasks of which 0 didn't need to be rerun and 1 failed.
Summary: 1 task failed:
/home/neuberfran/edm_yocto/sources/meta-tn-imx-bsp/recipes-kernel/linux/linux-tn-imx_6.1.bb:do_fetch
@neuberfran
1- So this line defines a rpmsg driver with the topic/endpoint : "rpmsg-openamp-demo-channel".
This should probe the imx-tty-rpmsg driver or the rpmsg sample client driver as it's part of the endpoint names.
The 0x2/0x1 parameters I'm not sure what they are used for, I'll look up the documentation at some point.
Normally, the RPMSG Name Service should receive the announcement message from the M4 zephyr program and probe the appropriate driver (tty-rpmsg and rpmsg-sample-client).
Here when you use the /dev/rpmsg_ctrl_0 device, you are explicitly asking the kernel to probe the imx-tty-rpmsg or sample-client-rpmsg drivers and therefore have /dev/ttyrpmsg0 to show up.
2- I do not have an explaination for this fact to be honest... It looked like it was defined correctly in your DT
3- I'm not sure I can help with this one unfortunately
@jlh-makeen https://gist.github.com/neuberfran/19fb614a60fa4da8cfc1a3d9fbee83b3
Still investigating here why vdev0buffer does not appear in cat .../caverout_memories, I have questions:
First: Do you have the device tree node called ocram in m4 part?
&ocram {
reg = <0x00901000 0xf000>;
};
Why do you use 0x901000 and not 0x900000 like me? E.g.: If I use 0x901000 I have -22 error in cat start command in linux side (imx-rproc -2 error)
root@scorpion:/lib/firmware# echo stop > /sys/class/remoteproc/remoteproc0/state && echo -n zephyr_openamp_rsc_table.elf > /sys/class/remoteproc/remoteproc0/firmware && cat /sys/class/remoteproc/remoteproc0/firmware && modprobe rpmsg_client_sample && modprobe imx_rpmsg_tty && echo start > /sys/class/remoteproc/remoteproc0/state
[ 43.397202] remoteproc remoteproc0: stopped remote processor imx-rproc
zephyr_openamp_rsc_table.elf
[ 43.442882] remoteproc remoteproc0: powering up imx-rproc
[ 43.448522] remoteproc remoteproc0: Direct firmware load for zephyr_openamp_rsc_table.elf failed with error -2
[ 43.459087] remoteproc remoteproc0: Falling back to sysfs fallback for: zephyr_openamp_rsc_table.elf
[ 43.470151] remoteproc remoteproc0: request_firmware failed: -2
[ 43.476870] remoteproc remoteproc0: Boot failed: -2
-sh: echo: write error: No such file or directory
cm4sramcode: cm4sramcode@0x900000 {
compatible = "shared-dma-pool";
reg = <0x00900000 0x40000>;
no-map;
};
https://www.youtube.com/watch?v=_18E5te_sIw&t=13s https://gist.github.com/neuberfran/19fb614a60fa4da8cfc1a3d9fbee83b3
k
@jlh-makeen I put 64 (egual u) and Not 16 in zephyr_remoteproc.elf And NOW I have vdevbuffer in carveout_memories result.
@jlh-makeen Pls. Help-me to interpreter my issue in main.c code (by openamp_rsc_table Project:
Note: If I don't comment on the line // k_sem_take(&data_tty_sem, K_FOREVER); it doesn't even pass printk("\r\nOpenAMP[remote] Linux tty ccc1.2 started\r\n");
/*
* Copyright (c) 2020, STMICROELECTRONICS
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr/drivers/ipm.h>
#include <openamp/open_amp.h>
#include <metal/device.h>
#include <resource_table.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(openamp_rsc_table, LOG_LEVEL_DBG);
#define SHM_DEVICE_NAME "shm"
#if !DT_HAS_CHOSEN(zephyr_ipc_shm)
#error "Sample requires definition of shared memory for rpmsg"
#endif
/* Constants derived from device tree */
#define SHM_NODE DT_CHOSEN(zephyr_ipc_shm)
#define SHM_START_ADDR DT_REG_ADDR(SHM_NODE)
#define SHM_SIZE DT_REG_SIZE(SHM_NODE)
#define APP_TASK_STACK_SIZE (1024)
/* Add 1024 extra bytes for the TTY task stack for the "tx_buff" buffer. */
#define APP_TTY_TASK_STACK_SIZE (1536)
K_THREAD_STACK_DEFINE(thread_mng_stack, APP_TASK_STACK_SIZE);
K_THREAD_STACK_DEFINE(thread_rp__client_stack, APP_TASK_STACK_SIZE);
K_THREAD_STACK_DEFINE(thread_tty_stack, APP_TTY_TASK_STACK_SIZE);
static struct k_thread thread_mng_data;
static struct k_thread thread_rp__client_data;
static struct k_thread thread_tty_data;
static const struct device *const ipm_handle =
DEVICE_DT_GET(DT_CHOSEN(zephyr_ipc));
static metal_phys_addr_t shm_physmap = SHM_START_ADDR;
struct metal_device shm_device = {
.name = SHM_DEVICE_NAME,
.num_regions = 2,
.regions = {
{.virt = NULL}, /* shared memory */
{.virt = NULL}, /* rsc_table memory */
},
.node = { NULL },
.irq_num = 0,
.irq_info = NULL
};
struct rpmsg_rcv_msg {
void *data;
size_t len;
};
static struct metal_io_region *shm_io;
static struct rpmsg_virtio_shm_pool shpool;
static struct metal_io_region *rsc_io;
static struct rpmsg_virtio_device rvdev;
static void *rsc_table;
static struct rpmsg_device *rpdev;
static char rx_sc_msg[20]; /* should receive "Hello world!" */
static struct rpmsg_endpoint sc_ept;
static struct rpmsg_rcv_msg sc_msg = {.data = rx_sc_msg};
static struct rpmsg_endpoint tty_ept;
static struct rpmsg_rcv_msg tty_msg;
static K_SEM_DEFINE(data_sem, 0, 1);
static K_SEM_DEFINE(data_sc_sem, 0, 1);
static K_SEM_DEFINE(data_tty_sem, 0, 1);
static void platform_ipm_callback(const struct device *dev, void *context,
uint32_t id, volatile void *data)
{
LOG_DBG("%s: msg received from mb %d\n", __func__, id);
k_sem_give(&data_sem);
}
static int rpmsg_recv_cs_callback(struct rpmsg_endpoint *ept, void *data,
size_t len, uint32_t src, void *priv)
{
memcpy(sc_msg.data, data, len);
sc_msg.len = len;
k_sem_give(&data_sc_sem);
return RPMSG_SUCCESS;
}
static int rpmsg_recv_tty_callback(struct rpmsg_endpoint *ept, void *data,
size_t len, uint32_t src, void *priv)
{
struct rpmsg_rcv_msg *msg = priv;
rpmsg_hold_rx_buffer(ept, data);
msg->data = data;
msg->len = len;
k_sem_give(&data_tty_sem);
return RPMSG_SUCCESS;
}
static void receive_message(unsigned char **msg, unsigned int *len)
{
int status = k_sem_take(&data_sem, K_FOREVER);
if (status == 0) {
rproc_virtio_notified(rvdev.vdev, VRING1_ID);
}
}
static void new_service_cb(struct rpmsg_device *rdev, const char *name,
uint32_t src)
{
LOG_ERR("%s: unexpected ns service receive for name %s\n",
__func__, name);
}
int mailbox_notify(void *priv, uint32_t id)
{
ARG_UNUSED(priv);
LOG_DBG("%s: msg received\n", __func__);
ipm_send(ipm_handle, 0, id, NULL, 0);
return 0;
}
int platform_init(void)
{
void *rsc_tab_addr;
int rsc_size;
struct metal_device *device;
struct metal_init_params metal_params = METAL_INIT_DEFAULTS;
int status;
status = metal_init(&metal_params);
if (status) {
LOG_DBG("metal_init: failed: %d\n", status);
return -1;
}
status = metal_register_generic_device(&shm_device);
if (status) {
LOG_DBG("Couldn't register shared memory: %d\n", status);
return -1;
}
status = metal_device_open("generic", SHM_DEVICE_NAME, &device);
if (status) {
LOG_DBG("metal_device_open failed: %d\n", status);
return -1;
}
/* declare shared memory region */
metal_io_init(&device->regions[0], (void *)SHM_START_ADDR, &shm_physmap,
SHM_SIZE, -1, 0, NULL);
shm_io = metal_device_io_region(device, 0);
if (!shm_io) {
LOG_DBG("Failed to get shm_io region\n");
return -1;
}
/* declare resource table region */
rsc_table_get(&rsc_tab_addr, &rsc_size);
rsc_table = (struct st_resource_table *)rsc_tab_addr;
metal_io_init(&device->regions[1], rsc_table,
(metal_phys_addr_t *)rsc_table, rsc_size, -1, 0, NULL);
rsc_io = metal_device_io_region(device, 1);
if (!rsc_io) {
LOG_DBG("Failed to get rsc_io region\n");
return -1;
}
/* setup IPM */
if (!device_is_ready(ipm_handle)) {
LOG_DBG("IPM device is not ready\n");
return -1;
}
ipm_register_callback(ipm_handle, platform_ipm_callback, NULL);
status = ipm_set_enabled(ipm_handle, 1);
if (status) {
LOG_DBG("ipm_set_enabled failed\n");
return -1;
}
return 0;
}
static void cleanup_system(void)
{
ipm_set_enabled(ipm_handle, 0);
rpmsg_deinit_vdev(&rvdev);
metal_finish();
}
struct rpmsg_device *
platform_create_rpmsg_vdev(unsigned int vdev_index,
unsigned int role,
void (*rst_cb)(struct virtio_device *vdev),
rpmsg_ns_bind_cb ns_cb)
{
struct fw_rsc_vdev_vring *vring_rsc;
struct virtio_device *vdev;
int ret;
vdev = rproc_virtio_create_vdev(VIRTIO_DEV_DEVICE, VDEV_ID,
rsc_table_to_vdev(rsc_table),
rsc_io, NULL, mailbox_notify, NULL);
if (!vdev) {
LOG_DBG("failed to create vdev\r\n");
return NULL;
}
/* wait master rpmsg init completion */
rproc_virtio_wait_remote_ready(vdev);
vring_rsc = rsc_table_get_vring0(rsc_table);
ret = rproc_virtio_init_vring(vdev, 0, vring_rsc->notifyid,
(void *)vring_rsc->da, rsc_io,
vring_rsc->num, vring_rsc->align);
if (ret) {
LOG_DBG("failed to init vring 0\r\n");
goto failed;
}
vring_rsc = rsc_table_get_vring1(rsc_table);
ret = rproc_virtio_init_vring(vdev, 1, vring_rsc->notifyid,
(void *)vring_rsc->da, rsc_io,
vring_rsc->num, vring_rsc->align);
if (ret) {
LOG_DBG("failed to init vring 1\r\n");
goto failed;
}
rpmsg_virtio_init_shm_pool(&shpool, NULL, SHM_SIZE);
ret = rpmsg_init_vdev(&rvdev, vdev, ns_cb, shm_io, &shpool);
if (ret) {
LOG_DBG("failed rpmsg_init_vdev\r\n");
goto failed;
}
return rpmsg_virtio_get_rpmsg_device(&rvdev);
failed:
rproc_virtio_remove_vdev(vdev);
return NULL;
}
void app_rpmsg_client_sample(void *arg1, void *arg2, void *arg3)
{
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
unsigned int msg_cnt = 0;
int ret = 0;
k_sem_take(&data_sc_sem, K_FOREVER);
printk("\r\nOpenAMP[remote] Linux sample client responder started\r\n");
ret = rpmsg_create_ept(&sc_ept, rpdev, "rpmsg-client-sample",
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
rpmsg_recv_cs_callback, NULL);
printk("\r\nOpenAMP[remote] Linux tty ccc7 started\r\n");
while (msg_cnt < 100) {
printk("\r\nOpenAMP[remote] Linux tty ccc7.1 started\r\n");
// k_sem_take(&data_sc_sem, K_FOREVER);
printk("\r\nOpenAMP[remote] Linux tty ccc7.2 started\r\n");
msg_cnt++;
rpmsg_send(&sc_ept, sc_msg.data, sc_msg.len);
printk("\r\nOpenAMP[remote] Linux tty ccc8 started\r\n");
}
printk("\r\nOpenAMP[remote] Linux tty ccc9 started\r\n");
rpmsg_destroy_ept(&sc_ept);
printk("\r\nOpenAMP[remote] Linux tty ccc10 started\r\n");
printk("OpenAMP Linux sample client responder ended\n");
}
void app_rpmsg_tty(void *arg1, void *arg2, void *arg3)
{
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
unsigned char tx_buff[512];
int ret = 0;
k_sem_take(&data_tty_sem, K_FOREVER);
printk("\r\nOpenAMP[remote] Linux tty responder started\r\n");
tty_ept.priv = &tty_msg;
ret = rpmsg_create_ept(&tty_ept, rpdev, "rpmsg-openamp-demo-channel",
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
rpmsg_recv_tty_callback, NULL);
printk("\r\nOpenAMP[remote] Linux tty ccc1 started\r\n");
while (tty_ept.addr != RPMSG_ADDR_ANY) {
printk("\r\nOpenAMP[remote] Linux tty ccc1.1 started\r\n");
// k_sem_take(&data_tty_sem, K_FOREVER);
printk("\r\nOpenAMP[remote] Linux tty ccc1.2 started\r\n");
if (tty_msg.len) {
snprintf(tx_buff, 13, "TTY 0x%04x: ", tty_ept.addr);
memcpy(&tx_buff[12], tty_msg.data, tty_msg.len);
rpmsg_send(&tty_ept, tx_buff, tty_msg.len + 13);
rpmsg_release_rx_buffer(&tty_ept, tty_msg.data);
}
printk("\r\nOpenAMP[remote] Linux tty ccc3 started\r\n");
tty_msg.len = 0;
tty_msg.data = NULL;
}
printk("\r\nOpenAMP[remote] Linux tty ccc4 started\r\n");
rpmsg_destroy_ept(&tty_ept);
printk("OpenAMP Linux TTY responder ended\n");
}
void rpmsg_mng_task(void *arg1, void *arg2, void *arg3)
{
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
unsigned char *msg;
unsigned int len;
int ret = 0;
printk("\r\nOpenAMP[remote] linux responder demo started\r\n");
/* Initialize platform */
ret = platform_init();
if (ret) {
LOG_ERR("Failed to initialize platform\n");
ret = -1;
goto task_end;
printk("\r\nOpenAMP[remote] Linux tty ccc12 started\r\n");
}
rpdev = platform_create_rpmsg_vdev(0, VIRTIO_DEV_DEVICE, NULL,
new_service_cb);
printk("\r\nOpenAMP[remote] Linux tty ccc13 started\r\n");
if (!rpdev) {
LOG_ERR("Failed to create rpmsg virtio device\n");
printk("\r\nOpenAMP[remote] Linux tty ccc14 started\r\n");
ret = -1;
goto task_end;
}
/* start the rpmsg clients */
printk("\r\nOpenAMP[remote] Linux tty ccc17 started\r\n");
k_sem_give(&data_sc_sem);
printk("\r\nOpenAMP[remote] Linux tty ccc18 started\r\n");
k_sem_give(&data_tty_sem);
printk("\r\nOpenAMP[remote] Linux tty ccc19 started\r\n");
while (1) {
printk("\r\nOpenAMP[remote] Linux tty ccc20 started\r\n");
receive_message(&msg, &len);
printk("\r\nOpenAMP[remote] Linux tty ccc21 started\r\n");
}
task_end:
cleanup_system();
printk("OpenAMP demo ended\n");
}
int main(void)
{
printk("Starting application threads!\n");
k_thread_create(&thread_mng_data, thread_mng_stack, APP_TASK_STACK_SIZE,
(k_thread_entry_t)rpmsg_mng_task,
NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT);
k_thread_create(&thread_rp__client_data, thread_rp__client_stack, APP_TASK_STACK_SIZE,
(k_thread_entry_t)app_rpmsg_client_sample,
NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
k_thread_create(&thread_tty_data, thread_tty_stack, APP_TTY_TASK_STACK_SIZE,
(k_thread_entry_t)app_rpmsg_tty,
NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
return 0;
}
Logs results here
OpenAMP Linux sample client responder ended
OpenAMP[remote] Linux tty responder started
OpenAMP[remote] Linux tty ccc1 started
OpenAMP[remote] Linux tty ccc1.1 started
OpenAMP[remote] Linux tty ccc1.2 started
OpenAMP[remote] Linux tty ccc3 started
OpenAMP[remote] Linux tty ccc1.1 started
OpenAMP[remote] Linux tty ccc1.2 started
OpenAMP[remote] Linux tty ccc3 started
OpenAMP[remote] Linux tty ccc1.1 started
OpenAMP[remote] Linux tty ccc1.2 started
OpenAMP[remote] Linux tty ccc3 started
OpenAMP[remote] Linux tty ccc1.1 started
OpenAMP[remote] Linux tty ccc1.2 started
OpenAMP[remote] Linux tty ccc3 started
@jlh-makeen Pls. Help-me to interpreter my issue in main.c code (by openamp_rsc_table Project:
Note: If I don't comment on the line // k_sem_take(&data_tty_sem, K_FOREVER); it doesn't even pass printk("\r\nOpenAMP[remote] Linux tty ccc1.2 started\r\n");
/* * Copyright (c) 2020, STMICROELECTRONICS * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/kernel.h> #include <zephyr/device.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <zephyr/drivers/ipm.h> #include <openamp/open_amp.h> #include <metal/device.h> #include <resource_table.h> #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(openamp_rsc_table, LOG_LEVEL_DBG); #define SHM_DEVICE_NAME "shm" #if !DT_HAS_CHOSEN(zephyr_ipc_shm) #error "Sample requires definition of shared memory for rpmsg" #endif /* Constants derived from device tree */ #define SHM_NODE DT_CHOSEN(zephyr_ipc_shm) #define SHM_START_ADDR DT_REG_ADDR(SHM_NODE) #define SHM_SIZE DT_REG_SIZE(SHM_NODE) #define APP_TASK_STACK_SIZE (1024) /* Add 1024 extra bytes for the TTY task stack for the "tx_buff" buffer. */ #define APP_TTY_TASK_STACK_SIZE (1536) K_THREAD_STACK_DEFINE(thread_mng_stack, APP_TASK_STACK_SIZE); K_THREAD_STACK_DEFINE(thread_rp__client_stack, APP_TASK_STACK_SIZE); K_THREAD_STACK_DEFINE(thread_tty_stack, APP_TTY_TASK_STACK_SIZE); static struct k_thread thread_mng_data; static struct k_thread thread_rp__client_data; static struct k_thread thread_tty_data; static const struct device *const ipm_handle = DEVICE_DT_GET(DT_CHOSEN(zephyr_ipc)); static metal_phys_addr_t shm_physmap = SHM_START_ADDR; struct metal_device shm_device = { .name = SHM_DEVICE_NAME, .num_regions = 2, .regions = { {.virt = NULL}, /* shared memory */ {.virt = NULL}, /* rsc_table memory */ }, .node = { NULL }, .irq_num = 0, .irq_info = NULL }; struct rpmsg_rcv_msg { void *data; size_t len; }; static struct metal_io_region *shm_io; static struct rpmsg_virtio_shm_pool shpool; static struct metal_io_region *rsc_io; static struct rpmsg_virtio_device rvdev; static void *rsc_table; static struct rpmsg_device *rpdev; static char rx_sc_msg[20]; /* should receive "Hello world!" */ static struct rpmsg_endpoint sc_ept; static struct rpmsg_rcv_msg sc_msg = {.data = rx_sc_msg}; static struct rpmsg_endpoint tty_ept; static struct rpmsg_rcv_msg tty_msg; static K_SEM_DEFINE(data_sem, 0, 1); static K_SEM_DEFINE(data_sc_sem, 0, 1); static K_SEM_DEFINE(data_tty_sem, 0, 1); static void platform_ipm_callback(const struct device *dev, void *context, uint32_t id, volatile void *data) { LOG_DBG("%s: msg received from mb %d\n", __func__, id); k_sem_give(&data_sem); } static int rpmsg_recv_cs_callback(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) { memcpy(sc_msg.data, data, len); sc_msg.len = len; k_sem_give(&data_sc_sem); return RPMSG_SUCCESS; } static int rpmsg_recv_tty_callback(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) { struct rpmsg_rcv_msg *msg = priv; rpmsg_hold_rx_buffer(ept, data); msg->data = data; msg->len = len; k_sem_give(&data_tty_sem); return RPMSG_SUCCESS; } static void receive_message(unsigned char **msg, unsigned int *len) { int status = k_sem_take(&data_sem, K_FOREVER); if (status == 0) { rproc_virtio_notified(rvdev.vdev, VRING1_ID); } } static void new_service_cb(struct rpmsg_device *rdev, const char *name, uint32_t src) { LOG_ERR("%s: unexpected ns service receive for name %s\n", __func__, name); } int mailbox_notify(void *priv, uint32_t id) { ARG_UNUSED(priv); LOG_DBG("%s: msg received\n", __func__); ipm_send(ipm_handle, 0, id, NULL, 0); return 0; } int platform_init(void) { void *rsc_tab_addr; int rsc_size; struct metal_device *device; struct metal_init_params metal_params = METAL_INIT_DEFAULTS; int status; status = metal_init(&metal_params); if (status) { LOG_DBG("metal_init: failed: %d\n", status); return -1; } status = metal_register_generic_device(&shm_device); if (status) { LOG_DBG("Couldn't register shared memory: %d\n", status); return -1; } status = metal_device_open("generic", SHM_DEVICE_NAME, &device); if (status) { LOG_DBG("metal_device_open failed: %d\n", status); return -1; } /* declare shared memory region */ metal_io_init(&device->regions[0], (void *)SHM_START_ADDR, &shm_physmap, SHM_SIZE, -1, 0, NULL); shm_io = metal_device_io_region(device, 0); if (!shm_io) { LOG_DBG("Failed to get shm_io region\n"); return -1; } /* declare resource table region */ rsc_table_get(&rsc_tab_addr, &rsc_size); rsc_table = (struct st_resource_table *)rsc_tab_addr; metal_io_init(&device->regions[1], rsc_table, (metal_phys_addr_t *)rsc_table, rsc_size, -1, 0, NULL); rsc_io = metal_device_io_region(device, 1); if (!rsc_io) { LOG_DBG("Failed to get rsc_io region\n"); return -1; } /* setup IPM */ if (!device_is_ready(ipm_handle)) { LOG_DBG("IPM device is not ready\n"); return -1; } ipm_register_callback(ipm_handle, platform_ipm_callback, NULL); status = ipm_set_enabled(ipm_handle, 1); if (status) { LOG_DBG("ipm_set_enabled failed\n"); return -1; } return 0; } static void cleanup_system(void) { ipm_set_enabled(ipm_handle, 0); rpmsg_deinit_vdev(&rvdev); metal_finish(); } struct rpmsg_device * platform_create_rpmsg_vdev(unsigned int vdev_index, unsigned int role, void (*rst_cb)(struct virtio_device *vdev), rpmsg_ns_bind_cb ns_cb) { struct fw_rsc_vdev_vring *vring_rsc; struct virtio_device *vdev; int ret; vdev = rproc_virtio_create_vdev(VIRTIO_DEV_DEVICE, VDEV_ID, rsc_table_to_vdev(rsc_table), rsc_io, NULL, mailbox_notify, NULL); if (!vdev) { LOG_DBG("failed to create vdev\r\n"); return NULL; } /* wait master rpmsg init completion */ rproc_virtio_wait_remote_ready(vdev); vring_rsc = rsc_table_get_vring0(rsc_table); ret = rproc_virtio_init_vring(vdev, 0, vring_rsc->notifyid, (void *)vring_rsc->da, rsc_io, vring_rsc->num, vring_rsc->align); if (ret) { LOG_DBG("failed to init vring 0\r\n"); goto failed; } vring_rsc = rsc_table_get_vring1(rsc_table); ret = rproc_virtio_init_vring(vdev, 1, vring_rsc->notifyid, (void *)vring_rsc->da, rsc_io, vring_rsc->num, vring_rsc->align); if (ret) { LOG_DBG("failed to init vring 1\r\n"); goto failed; } rpmsg_virtio_init_shm_pool(&shpool, NULL, SHM_SIZE); ret = rpmsg_init_vdev(&rvdev, vdev, ns_cb, shm_io, &shpool); if (ret) { LOG_DBG("failed rpmsg_init_vdev\r\n"); goto failed; } return rpmsg_virtio_get_rpmsg_device(&rvdev); failed: rproc_virtio_remove_vdev(vdev); return NULL; } void app_rpmsg_client_sample(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); unsigned int msg_cnt = 0; int ret = 0; k_sem_take(&data_sc_sem, K_FOREVER); printk("\r\nOpenAMP[remote] Linux sample client responder started\r\n"); ret = rpmsg_create_ept(&sc_ept, rpdev, "rpmsg-client-sample", RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, rpmsg_recv_cs_callback, NULL); printk("\r\nOpenAMP[remote] Linux tty ccc7 started\r\n"); while (msg_cnt < 100) { printk("\r\nOpenAMP[remote] Linux tty ccc7.1 started\r\n"); // k_sem_take(&data_sc_sem, K_FOREVER); printk("\r\nOpenAMP[remote] Linux tty ccc7.2 started\r\n"); msg_cnt++; rpmsg_send(&sc_ept, sc_msg.data, sc_msg.len); printk("\r\nOpenAMP[remote] Linux tty ccc8 started\r\n"); } printk("\r\nOpenAMP[remote] Linux tty ccc9 started\r\n"); rpmsg_destroy_ept(&sc_ept); printk("\r\nOpenAMP[remote] Linux tty ccc10 started\r\n"); printk("OpenAMP Linux sample client responder ended\n"); } void app_rpmsg_tty(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); unsigned char tx_buff[512]; int ret = 0; k_sem_take(&data_tty_sem, K_FOREVER); printk("\r\nOpenAMP[remote] Linux tty responder started\r\n"); tty_ept.priv = &tty_msg; ret = rpmsg_create_ept(&tty_ept, rpdev, "rpmsg-openamp-demo-channel", RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, rpmsg_recv_tty_callback, NULL); printk("\r\nOpenAMP[remote] Linux tty ccc1 started\r\n"); while (tty_ept.addr != RPMSG_ADDR_ANY) { printk("\r\nOpenAMP[remote] Linux tty ccc1.1 started\r\n"); // k_sem_take(&data_tty_sem, K_FOREVER); printk("\r\nOpenAMP[remote] Linux tty ccc1.2 started\r\n"); if (tty_msg.len) { snprintf(tx_buff, 13, "TTY 0x%04x: ", tty_ept.addr); memcpy(&tx_buff[12], tty_msg.data, tty_msg.len); rpmsg_send(&tty_ept, tx_buff, tty_msg.len + 13); rpmsg_release_rx_buffer(&tty_ept, tty_msg.data); } printk("\r\nOpenAMP[remote] Linux tty ccc3 started\r\n"); tty_msg.len = 0; tty_msg.data = NULL; } printk("\r\nOpenAMP[remote] Linux tty ccc4 started\r\n"); rpmsg_destroy_ept(&tty_ept); printk("OpenAMP Linux TTY responder ended\n"); } void rpmsg_mng_task(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); unsigned char *msg; unsigned int len; int ret = 0; printk("\r\nOpenAMP[remote] linux responder demo started\r\n"); /* Initialize platform */ ret = platform_init(); if (ret) { LOG_ERR("Failed to initialize platform\n"); ret = -1; goto task_end; printk("\r\nOpenAMP[remote] Linux tty ccc12 started\r\n"); } rpdev = platform_create_rpmsg_vdev(0, VIRTIO_DEV_DEVICE, NULL, new_service_cb); printk("\r\nOpenAMP[remote] Linux tty ccc13 started\r\n"); if (!rpdev) { LOG_ERR("Failed to create rpmsg virtio device\n"); printk("\r\nOpenAMP[remote] Linux tty ccc14 started\r\n"); ret = -1; goto task_end; } /* start the rpmsg clients */ printk("\r\nOpenAMP[remote] Linux tty ccc17 started\r\n"); k_sem_give(&data_sc_sem); printk("\r\nOpenAMP[remote] Linux tty ccc18 started\r\n"); k_sem_give(&data_tty_sem); printk("\r\nOpenAMP[remote] Linux tty ccc19 started\r\n"); while (1) { printk("\r\nOpenAMP[remote] Linux tty ccc20 started\r\n"); receive_message(&msg, &len); printk("\r\nOpenAMP[remote] Linux tty ccc21 started\r\n"); } task_end: cleanup_system(); printk("OpenAMP demo ended\n"); } int main(void) { printk("Starting application threads!\n"); k_thread_create(&thread_mng_data, thread_mng_stack, APP_TASK_STACK_SIZE, (k_thread_entry_t)rpmsg_mng_task, NULL, NULL, NULL, K_PRIO_COOP(8), 0, K_NO_WAIT); k_thread_create(&thread_rp__client_data, thread_rp__client_stack, APP_TASK_STACK_SIZE, (k_thread_entry_t)app_rpmsg_client_sample, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); k_thread_create(&thread_tty_data, thread_tty_stack, APP_TTY_TASK_STACK_SIZE, (k_thread_entry_t)app_rpmsg_tty, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); return 0; }
Logs results here
OpenAMP Linux sample client responder ended OpenAMP[remote] Linux tty responder started OpenAMP[remote] Linux tty ccc1 started OpenAMP[remote] Linux tty ccc1.1 started OpenAMP[remote] Linux tty ccc1.2 started OpenAMP[remote] Linux tty ccc3 started OpenAMP[remote] Linux tty ccc1.1 started OpenAMP[remote] Linux tty ccc1.2 started OpenAMP[remote] Linux tty ccc3 started OpenAMP[remote] Linux tty ccc1.1 started OpenAMP[remote] Linux tty ccc1.2 started OpenAMP[remote] Linux tty ccc3 started OpenAMP[remote] Linux tty ccc1.1 started OpenAMP[remote] Linux tty ccc1.2 started OpenAMP[remote] Linux tty ccc3 started
Seems normal to me, the semaphore tty_sem will only pass when data is received from Linux dev/ttyRPMSG0 to Zephyr.
We used 0x901000 because for some reason 0x1000 bytes were reserved for our Linux (probably necessary for some device or drivers). That was given by my colleague who's responsible for the Linux side.
He said he had an interesting breakthrough last week where he could get dev/ttyrpmsg0 to show up and communication was working, but apparently there were memory addresses issues and mbox ids mismatching between Zephyr and Linux.
I'll know more about it next week.
@jlh-makeen Makes a lot of sense. Thanks.
root@scorpion:/lib/firmware# echo stop > /sys/class/remoteproc/remoteproc0/state && echo -n zephyr_openamp_rsc_table.elf > /sys/class/remoteproc/remoteproc0/firmware && cat /sys/class/remoteproc/remoteproc0/firmware && modprobe rpmsg_client_sample && modprobe imx_rpmsg_tty && echo start > /sys/class/remoteproc/remoteproc0/state
[ 42.027498] remoteproc remoteproc0: stopped remote processor imx-rproc
zephyr_openamp_rsc_table.elf
[ 42.075112] remoteproc remoteproc0: powering up imx-rproc
[ 42.092743] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 661452
[ 42.103307] remoteproc0#vdev0buffer: assigned reserved memory node vdevbuffer@902000
[ 42.115938] virtio_rpmsg_bus virtio0: rpmsg host is online
[ 42.122457] remoteproc0#vdev0buffer: registered virtio0 (type 7)
[ 42.129034] remoteproc remoteproc0: remote processor imx-rproc is now up
root@scorpion:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdevbuffer
Virtual address: caf8b45f
DMA address: 0x00902000
Device address: 0x902000
Length: 0xfe000 Bytes
Carveout memory entry:
Name: vdevvring0
Virtual address: fa50f047
DMA address: 0x00900000
Device address: 0x900000
Length: 0x1000 Bytes
Carveout memory entry:
Name: vdevvring1
Virtual address: 8764090b
DMA address: 0x00901000
Device address: 0x901000
Length: 0x1000 Bytes
Carveout memory entry:
Name: cm4tcmcode
Virtual address: 0f3abb38
DMA address: 0x007f8000
Device address: 0x7f8000
Length: 0x8000 Bytes
Carveout memory entry:
Name: vdev0vring0
Virtual address: 958a03a9
DMA address: 0x8a04f000
Device address: 0x8a04f000
Length: 0x1000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: 35990c3b
DMA address: 0x8a050000
Device address: 0x8a050000
Length: 0x1000 Bytes
root@scorpion:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/resource_table
Entry 0 is of type vdev
ID 7
Notify ID 0
Device features 0x1
Guest features 0x1
Config length 0x0
Status 0x7
Number of vrings 2
Reserved (should be zero) [0][0]
Vring 0
Device Address 0x8a04f000
Alignment 16
Number of buffers 64
Notify ID 0
Physical Address 0x0
Vring 1
Device Address 0x8a050000
Alignment 16
Number of buffers 64
Notify ID 1
Physical Address 0x0
root@scorpion:/lib/firmware# ls /dev/tty*
/dev/tty /dev/tty12 /dev/tty17 /dev/tty21 /dev/tty26 /dev/tty30 /dev/tty35 /dev/tty4 /dev/tty44 /dev/tty49 /dev/tty53 /dev/tty58 /dev/tty62 /dev/ttymxc4
/dev/tty0 /dev/tty13 /dev/tty18 /dev/tty22 /dev/tty27 /dev/tty31 /dev/tty36 /dev/tty40 /dev/tty45 /dev/tty5 /dev/tty54 /dev/tty59 /dev/tty63 /dev/ttymxc6
/dev/tty1 /dev/tty14 /dev/tty19 /dev/tty23 /dev/tty28 /dev/tty32 /dev/tty37 /dev/tty41 /dev/tty46 /dev/tty50 /dev/tty55 /dev/tty6 /dev/tty7
/dev/tty10 /dev/tty15 /dev/tty2 /dev/tty24 /dev/tty29 /dev/tty33 /dev/tty38 /dev/tty42 /dev/tty47 /dev/tty51 /dev/tty56 /dev/tty60 /dev/tty8
/dev/tty11 /dev/tty16 /dev/tty20 /dev/tty25 /dev/tty3 /dev/tty34 /dev/tty39 /dev/tty43 /dev/tty48 /dev/tty52 /dev/tty57 /dev/tty61 /dev/tty9
@jlh-makeen Mistery
When I change vdevbuffer, vdevvring0, vdevvring1, cm4tcmcode, cm4sramcode to vdev0buffer, vdev0vring0, vdev0vring1, cm4tcmcode, cm4sramcode I can`t see vdev0buffer in cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories result.
imx7d-cm4 {
compatible = "fsl,imx7d-cm4";
clocks = <&clks IMX7D_ARM_M4_ROOT_CLK>;
// fsl,auto-boot;
mbox-names = "tx0", "rx0", "rxdb0";
mboxes = <&mu0a 0 1
&mu0a 1 1
&mu0a 3 1>;
// memory-region = <&rpmsg_vrings>, <&cm4tcmcode>, <&cm4sramcode>;
memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&cm4tcmcode>, <&cm4sramcode>;
// <&cm4sramcode>;
fsl,rproc-auto-boot = <1>;
fsl,rproc-fw-name="zephyr_openamp_rsc_table.elf";
syscon = <&src>;
status = "okay";
};
vdev0vring0: vdev0vring0@900000 {
compatible = "shared-dma-pool";
reg = <0x900000 0x1000>;
no-map;
};
vdev0vring1: vdev0vring1@901000 {
compatible = "shared-dma-pool";
reg = <0x901000 0x1000>;
no-map;
};
vdev0buffer: vdev0buffer@902000 {
compatible = "shared-dma-pool";
reg = <0x902000 0xfe000>;
no-map;
};
cm4tcmcode: cm4tcmcode@7f8000 {
compatible = "shared-dma-pool";
reg = <0x007f8000 0x8000>;
no-map;
};
cm4sramcode: cm4sramcode@0x900000 {
compatible = "shared-dma-pool";
reg = <0x00900000 0x40000>;
no-map;
};
root@scorpion:/lib/firmware#
root@scorpion:/lib/firmware# cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
Carveout memory entry:
Name: vdev0vring0
Virtual address: 6899ed74
DMA address: 0x00900000
Device address: 0x900000
Length: 0x1000 Bytes
Carveout memory entry:
Name: vdev0vring1
Virtual address: 7421fba4
DMA address: 0x00901000
Device address: 0x901000
Length: 0x1000 Bytes
Carveout memory entry:
Name: cm4tcmcode
Virtual address: 2beae070
DMA address: 0x007f8000
Device address: 0x7f8000
Length: 0x8000 Bytes
Carveout memory entry:
Name: cm4sramcode
Virtual address: dd673f21
DMA address: 0x00900000
Device address: 0x900000
Length: 0x40000 Bytes
@neuberfran
We have found out that you need to use mbox 0 :
mboxes = <&mu0a 0 0 &mu0a 1 0 &mu0a 3 0>;
This is due to Zephyr using sending notifications to the ipm index 0.
My colleague has been through a lot of debugging and printk'ing in the Linux Rproc/ Virtio to figureout what was going on.
Here are the things we had to change to make it work:
Stay tuned...
@jlh-makeen
For now, I just want vdev0buffer appearing in the result of cat.....carveout_memories command
mbox-names = "tx0", "rx0", "rxdb0";
mboxes = <&mu0a 0 0
&mu0a 1 0
&mu0a 3 0>;
This above still doesn't solve the error above and it only appears if I change the name from vdev0buffer to vdevbuffer.
@jlh-makeen https://lwn.net/Articles/815905/
I can't put 5.16 here. Please ask your colleague to make a patch so I can use rpmsg-tty here
@jlh-makeen https://lwn.net/Articles/815905/
I can't put 5.16 here. Please ask your colleague to make a patch so I can use rpmsg-tty here
I'm not sure it will work if you cannot get a 5.16 or newer kernel.
I'll know more on Thursday.
@neuberfran
I have spent the day with my colleague working on Zephyr/Linux with RPMSG. We got some good news where we finally managed to get Zephyr to get loaded by rproc and rpmsg to show up WITHOUT any kernel modifications !
We have therefore reverted all our patches in the Linux Kernel and only properly defined the correct nodes in Linux and Zephyr to get the system working.
One important note though, Zephyr is not correctly configured to place the boot_vector (aka SP and PC) into the OCRAM_S region.
Therefore if your Zephyr DT is not using the &ocram_s_code as the zephyr,flash node, your M4 core will not boot your application.
See here in the FREERTOS linker script provided by Toradex on the M4 examples for IMX7D: https://github.com/toradex/FreeRTOS-Colibri-iMX7/blob/master/platform/devices/MCIMX7D/linker/gcc/MCIMX7D_M4_tcm.ld#L102
the complete interrupt vector table is placed in the OCRAM_S which represents approx 0x240 bytes.
The rest of the code can be located anywhere in the TCM/OCRAM/OCRAM_S/DDR as per your application needs. The only limitation is that you MUST have at least the first 8 bytes of the rom_start region of the zephyr.elf file placed into the OCRAM_S (address 0x00180000).
The problem is that Zephyr places the rom_start region (containing the SP/PC and vector table) at the start of the ROMABLE_REGION (aka FLASH, aka CODE read only region).
This is incorrect as it prevents the M4 core to boot as per the AN5317 from NXP which clearly states you must load the SP/PC into the OCRAM_S to boot the M4 correctly.
At first we did that by modifying the elf loader of Linux RPROC driver. But that was a hack and not very nice.
But it turns out we can modify the include/zephyr/arch/arm/cortex_m/scripts/linker.ld to place the rom_start region in the OCRAM_S:
...
MEMORY
{
BOOTVECTOR (rx) : ORIGIN = 0x00180000, LENGTH = 32K
FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
#if defined(CONFIG_LINKER_DEVNULL_MEMORY)
DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE
#endif
LINKER_DT_REGIONS()
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = 0xFFFF7FFF, LENGTH = 32K
}
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
#include <zephyr/linker/rel-sections.ld>
/*
* .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
* before text section.
*/
/DISCARD/ :
{
*(.plt)
}
/DISCARD/ :
{
*(.iplt)
}
SECTION_PROLOGUE(rom_start,,)
{
/* Located in generated directory. This file is populated by calling
* zephyr_linker_sources(ROM_START ...). This typically contains the vector
* table and debug information.
*/
#include <snippets-rom-start.ld>
} GROUP_LINK_IN(BOOTVECTOR )
GROUP_START(ROMABLE_REGION)
__rom_region_start = ROM_ADDR;
....
I plan to do this nicely with config flags in order to not disturb other cortex_m devices and keep this configuration selectable.
This will generate a valid elf file that will correctly load into Linux using RPROC and show up the RPMSG if you have correctly used the mu0a and channel 0 as I mentioned before.
Either you use the OCRAM_S as your CODE partitions for zephyr,flash or you need to adjust the linker script to always place the irq vectors in the OCRAM_S. I hope this is clear.
More information and details to come later. I hope this helps you understand the issues :)
@jlh-makeen You said: _"Either you use the OCRAM_S as your CODE partitions for zephyr,flash or you need to adjust the linker script to always place the irq vectors in the OCRAMS. I hope this is clear."
Unfortunately, it is not yet clear. Which region should I map to vdevbuffer, vring0 and vring1?
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
vdev0vring0: vdev0vring0@900000 {
compatible = "shared-dma-pool";
reg = <0x900000 0x1000>;
no-map;
};
vdev0vring1: vdev0vring1@901000 {
compatible = "shared-dma-pool";
reg = <0x901000 0x1000>;
no-map;
};
vdevbuffer: vdevbuffer@902000 {
compatible = "shared-dma-pool";
reg = <0x902000 0xfe000>;
no-map;
};
cm4tcmcode: cm4tcmcode@7f8000 {
compatible = "shared-dma-pool";
reg = <0x007f8000 0x8000>;
no-map;
};
cm4sramcode: cm4sramcode@0x900000 {
compatible = "shared-dma-pool";
reg = <0x00900000 0x40000>;
no-map;
};
};
imx7d-cm4 {
compatible = "fsl,imx7d-cm4";
clocks = <&clks IMX7D_ARM_M4_ROOT_CLK>;
mbox-names = "tx", "rx", "rxdb";
mboxes = <&mu0a 0 0
&mu0a 1 0
&mu0a 3 0>;
memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&cm4tcmcode>, <&cm4sramcode>;
fsl,rproc-auto-boot = <1>;
fsl,rproc-fw-name="zephyr_openamp_rsc_table.elf";
syscon = <&src>;
status = "okay";
};
@neuberfran Please first try to modify the Zephyr Linker script instead like I mentionned previously, it is important that the rproc elf loader is copying the boot vector into OCRAM_S. Don't change anything else.
@jlh-makeen Pls, give-me your main.c from openamp_rsc_table. I think there are differences between your main.c and mine. I want to keep them both the same.
@jlh-makeen Pls, give-me your main.c from openamp_rsc_table. I think there are differences between your main.c and mine. I want to keep them both the same.
You can run the default openamp_rsc_table sample without modifications.
It is only necessary to provide the Zephyr ipc and shm nodes with the same setting as your Linux side, I advise that you use DDR for the shared memory vrings/vdevbuffer and zephyr side shm, in order to have symetric setup in zephyr/linux (the addresses will be the same).
When the openamp_rsc_table sample starts up, you should see rpmsg virtio bus ns-announcements, even if you don't have tty-rpmsg driver from Linux 5.16.
If you have that, you'll be ready for rpmsg :)
-rom-start.ld
I need change my /home/neuberfran/zephyrproject/zephyr/include/zephyr/arch/arm/cortex_m/scripts/linker.ld from this:
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Cortex-M platforms.
*/
#include <zephyr/linker/sections.h>
#include <zephyr/devicetree.h>
#include <zephyr/linker/devicetree_regions.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>
/* physical address of RAM */
#ifdef CONFIG_XIP
#define ROMABLE_REGION FLASH
#else
#define ROMABLE_REGION RAM
#endif
#define RAMABLE_REGION RAM
#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0)
#define ROM_ADDR RAM_ADDR
#else
#define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
#endif
#if CONFIG_FLASH_LOAD_SIZE > 0
#define ROM_SIZE CONFIG_FLASH_LOAD_SIZE
#else
#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET)
#endif
#if defined(CONFIG_XIP)
#if defined(CONFIG_IS_BOOTLOADER)
#define RAM_SIZE (CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR (CONFIG_SRAM_BASE_ADDRESS + \
(CONFIG_SRAM_SIZE * 1K - RAM_SIZE))
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K - CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
#if defined(CONFIG_CUSTOM_SECTION_ALIGN)
_region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE;
#else
/* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
* to make linker section alignment comply with MPU granularity.
*/
#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
#else
/* If building without MPU support, use default 4-byte alignment. */
_region_min_align = 4;
#endif
#endif
#if !defined(CONFIG_CUSTOM_SECTION_ALIGN) && defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align); \
. = ALIGN( 1 << LOG2CEIL(region_size))
#else
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align)
#endif
MEMORY
{
FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
LINKER_DT_REGIONS()
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
}
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
#include <zephyr/linker/rel-sections.ld>
/*
* .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
* before text section.
*/
/DISCARD/ :
{
*(.plt)
}
/DISCARD/ :
{
*(.iplt)
}
GROUP_START(ROMABLE_REGION)
__rom_region_start = ROM_ADDR;
SECTION_PROLOGUE(rom_start,,)
{
/* Located in generated directory. This file is populated by calling
* zephyr_linker_sources(ROM_START ...). This typically contains the vector
* table and debug information.
*/
#include <snippets-rom-start.ld>
} GROUP_LINK_IN(ROMABLE_REGION)
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_relocate.ld>
#endif /* CONFIG_CODE_DATA_RELOCATION */
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
{
__text_region_start = .;
#include <zephyr/linker/kobject-text.ld>
*(.text)
*(".text.*")
*(".TEXT.*")
*(.gnu.linkonce.t.*)
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* after .gnu.linkonce.t.*
*/
*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
. = ALIGN(4);
} GROUP_LINK_IN(ROMABLE_REGION)
__text_region_end = .;
#if defined (CONFIG_CPP)
SECTION_PROLOGUE(.ARM.extab,,)
{
/*
* .ARM.extab section containing exception unwinding information.
*/
*(.ARM.extab* .gnu.linkonce.armextab.*)
} GROUP_LINK_IN(ROMABLE_REGION)
#endif
SECTION_PROLOGUE(.ARM.exidx,,)
{
/*
* This section, related to stack and exception unwinding, is placed
* explicitly to prevent it from being shared between multiple regions.
* It must be defined for gcc to support 64-bit math and avoid
* section overlap.
*/
__exidx_start = .;
#if defined (__GCC_LINKER_CMD__)
*(.ARM.exidx* gnu.linkonce.armexidx.*)
#endif
__exidx_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
__rodata_region_start = .;
#include <zephyr/linker/common-rom.ld>
#include <zephyr/linker/thread-local-storage.ld>
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
{
*(.rodata)
*(".rodata.*")
*(.gnu.linkonce.r.*)
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#include <zephyr/linker/kobject-rom.ld>
/*
* For XIP images, in order to avoid the situation when __data_rom_start
* is 32-bit aligned, but the actual data is placed right after rodata
* section, which may not end exactly at 32-bit border, pad rodata
* section, so __data_rom_start points at data and it is 32-bit aligned.
*
* On non-XIP images this may enlarge image size up to 3 bytes. This
* generally is not an issue, since modern ROM and FLASH memory is
* usually 4k aligned.
*/
. = ALIGN(4);
} GROUP_LINK_IN(ROMABLE_REGION)
#include <zephyr/linker/cplusplus-rom.ld>
#if defined(CONFIG_BUILD_ALIGN_LMA)
/*
* Include a padding section here to make sure that the LMA address
* of the sections in the RAMABLE_REGION are aligned with those
* section's VMA alignment requirements.
*/
SECTION_PROLOGUE(padding_section,,)
{
__rodata_region_end = .;
MPU_ALIGN(__rodata_region_end - ADDR(rom_start));
} GROUP_LINK_IN(ROMABLE_REGION)
#else
__rodata_region_end = .;
MPU_ALIGN(__rodata_region_end - ADDR(rom_start));
#endif
__rom_region_end = __rom_region_start + . - ADDR(rom_start);
GROUP_END(ROMABLE_REGION)
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* before data section.
*/
/DISCARD/ : {
*(.got.plt)
*(.igot.plt)
*(.got)
*(.igot)
}
GROUP_START(RAMABLE_REGION)
. = RAM_ADDR;
/* Align the start of image RAM with the
* minimum granularity required by MPU.
*/
. = ALIGN(_region_min_align);
_image_ram_start = .;
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>
#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN
#include <app_smem.ld>
_app_smem_size = _app_smem_end - _app_smem_start;
_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
/*
* For performance, BSS section is assumed to be 4 byte aligned and
* a multiple of 4 bytes
*/
. = ALIGN(4);
__bss_start = .;
__kernel_ram_start = .;
*(.bss)
*(".bss.*")
*(COMMON)
*(".kernel_bss.*")
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif
/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
*/
__bss_end = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
#include <zephyr/linker/common-noinit.ld>
#endif /* CONFIG_USERSPACE */
GROUP_START(DATA_REGION)
SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
{
__data_region_start = .;
__data_start = .;
*(.data)
*(".data.*")
*(".kernel.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_data_relocate.ld>
#endif
__data_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
__data_size = __data_end - __data_start;
__data_load_start = LOADADDR(_DATA_SECTION_NAME);
__data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
#include <zephyr/linker/common-ram.ld>
#include <zephyr/linker/kobject-data.ld>
#include <zephyr/linker/cplusplus-ram.ld>
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-data-sections.ld>
__data_region_end = .;
#ifndef CONFIG_USERSPACE
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
/*
* For performance, BSS section is assumed to be 4 byte aligned and
* a multiple of 4 bytes
*/
. = ALIGN(4);
__bss_start = .;
__kernel_ram_start = .;
*(.bss)
*(".bss.*")
*(COMMON)
*(".kernel_bss.*")
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif
/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
*/
__bss_end = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
{
/*
* This section is used for non-initialized objects that
* will not be cleared during the boot process.
*/
*(.noinit)
*(".noinit.*")
*(".kernel_noinit.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>
} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
#endif /* CONFIG_USERSPACE */
/* Define linker symbols */
__kernel_ram_end = RAM_ADDR + RAM_SIZE;
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
GROUP_START(ITCM)
SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(4))
{
__itcm_start = .;
*(.itcm)
*(".itcm.*")
__itcm_end = .;
} GROUP_LINK_IN(ITCM AT> ROMABLE_REGION)
__itcm_size = __itcm_end - __itcm_start;
__itcm_load_start = LOADADDR(_ITCM_SECTION_NAME);
GROUP_END(ITCM)
#endif
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
GROUP_START(DTCM)
SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
{
__dtcm_start = .;
__dtcm_bss_start = .;
*(.dtcm_bss)
*(".dtcm_bss.*")
__dtcm_bss_end = .;
} GROUP_LINK_IN(DTCM)
SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(4))
{
__dtcm_noinit_start = .;
*(.dtcm_noinit)
*(".dtcm_noinit.*")
__dtcm_noinit_end = .;
} GROUP_LINK_IN(DTCM)
SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(4))
{
__dtcm_data_start = .;
*(.dtcm_data)
*(".dtcm_data.*")
__dtcm_data_end = .;
} GROUP_LINK_IN(DTCM AT> ROMABLE_REGION)
__dtcm_end = .;
__dtcm_data_load_start = LOADADDR(_DTCM_DATA_SECTION_NAME);
GROUP_END(DTCM)
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>
#include <zephyr/linker/ram-end.ld>
GROUP_END(RAMABLE_REGION)
#include <zephyr/linker/debug-sections.ld>
/DISCARD/ : { *(.note.GNU-stack) }
SECTION_PROLOGUE(.ARM.attributes, 0,)
{
KEEP(*(.ARM.attributes))
KEEP(*(.gnu.attributes))
}
/* Sections generated from 'zephyr,memory-region' nodes */
LINKER_DT_SECTIONS()
/* Must be last in romable region */
SECTION_PROLOGUE(.last_section,,)
{
#ifdef CONFIG_LINKER_LAST_SECTION_ID
/* Fill last section with a word to ensure location counter and actual rom
* region data usage match. */
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
#endif
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
* calculate this value here. */
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
}
to??????????
As I explained before to this:
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Cortex-M platforms.
*/
#include <zephyr/linker/sections.h>
#include <zephyr/devicetree.h>
#include <zephyr/linker/devicetree_regions.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>
/* physical address of RAM */
#ifdef CONFIG_XIP
#define ROMABLE_REGION FLASH
#else
#define ROMABLE_REGION RAM
#endif
#define RAMABLE_REGION RAM
#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0)
#define ROM_ADDR RAM_ADDR
#else
#define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
#endif
#if CONFIG_FLASH_LOAD_SIZE > 0
#define ROM_SIZE CONFIG_FLASH_LOAD_SIZE
#else
#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET)
#endif
#if defined(CONFIG_XIP)
#if defined(CONFIG_IS_BOOTLOADER)
#define RAM_SIZE (CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR (CONFIG_SRAM_BASE_ADDRESS + \
(CONFIG_SRAM_SIZE * 1K - RAM_SIZE))
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
#else
#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K - CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif
#if defined(CONFIG_CUSTOM_SECTION_ALIGN)
_region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE;
#else
/* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
* to make linker section alignment comply with MPU granularity.
*/
#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
#else
/* If building without MPU support, use default 4-byte alignment. */
_region_min_align = 4;
#endif
#endif
#if !defined(CONFIG_CUSTOM_SECTION_ALIGN) && defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align); \
. = ALIGN( 1 << LOG2CEIL(region_size))
#else
#define MPU_ALIGN(region_size) \
. = ALIGN(_region_min_align)
#endif
MEMORY
{
BOOTVECTOR (rx) : ORIGIN = 0x00180000, LENGTH = 32K
FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
LINKER_DT_REGIONS()
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
}
ENTRY(CONFIG_KERNEL_ENTRY)
SECTIONS
{
#include <zephyr/linker/rel-sections.ld>
/*
* .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
* before text section.
*/
/DISCARD/ :
{
*(.plt)
}
/DISCARD/ :
{
*(.iplt)
}
GROUP_START(ROMABLE_REGION)
__rom_region_start = ROM_ADDR;
SECTION_PROLOGUE(rom_start,,)
{
/* Located in generated directory. This file is populated by calling
* zephyr_linker_sources(ROM_START ...). This typically contains the vector
* table and debug information.
*/
#include <snippets-rom-start.ld>
} GROUP_LINK_IN(BOOTVECTOR)
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_relocate.ld>
#endif /* CONFIG_CODE_DATA_RELOCATION */
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
{
__text_region_start = .;
#include <zephyr/linker/kobject-text.ld>
*(.text)
*(".text.*")
*(".TEXT.*")
*(.gnu.linkonce.t.*)
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* after .gnu.linkonce.t.*
*/
*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
. = ALIGN(4);
} GROUP_LINK_IN(ROMABLE_REGION)
__text_region_end = .;
#if defined (CONFIG_CPP)
SECTION_PROLOGUE(.ARM.extab,,)
{
/*
* .ARM.extab section containing exception unwinding information.
*/
*(.ARM.extab* .gnu.linkonce.armextab.*)
} GROUP_LINK_IN(ROMABLE_REGION)
#endif
SECTION_PROLOGUE(.ARM.exidx,,)
{
/*
* This section, related to stack and exception unwinding, is placed
* explicitly to prevent it from being shared between multiple regions.
* It must be defined for gcc to support 64-bit math and avoid
* section overlap.
*/
__exidx_start = .;
#if defined (__GCC_LINKER_CMD__)
*(.ARM.exidx* gnu.linkonce.armexidx.*)
#endif
__exidx_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
__rodata_region_start = .;
#include <zephyr/linker/common-rom.ld>
#include <zephyr/linker/thread-local-storage.ld>
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
{
*(.rodata)
*(".rodata.*")
*(.gnu.linkonce.r.*)
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rodata.ld>
#include <zephyr/linker/kobject-rom.ld>
/*
* For XIP images, in order to avoid the situation when __data_rom_start
* is 32-bit aligned, but the actual data is placed right after rodata
* section, which may not end exactly at 32-bit border, pad rodata
* section, so __data_rom_start points at data and it is 32-bit aligned.
*
* On non-XIP images this may enlarge image size up to 3 bytes. This
* generally is not an issue, since modern ROM and FLASH memory is
* usually 4k aligned.
*/
. = ALIGN(4);
} GROUP_LINK_IN(ROMABLE_REGION)
#include <zephyr/linker/cplusplus-rom.ld>
#if defined(CONFIG_BUILD_ALIGN_LMA)
/*
* Include a padding section here to make sure that the LMA address
* of the sections in the RAMABLE_REGION are aligned with those
* section's VMA alignment requirements.
*/
SECTION_PROLOGUE(padding_section,,)
{
__rodata_region_end = .;
MPU_ALIGN(__rodata_region_end - ADDR(rom_start));
} GROUP_LINK_IN(ROMABLE_REGION)
#else
__rodata_region_end = .;
MPU_ALIGN(__rodata_region_end - ADDR(rom_start));
#endif
__rom_region_end = __rom_region_start + . - ADDR(rom_start);
GROUP_END(ROMABLE_REGION)
/*
* These are here according to 'arm-zephyr-elf-ld --verbose',
* before data section.
*/
/DISCARD/ : {
*(.got.plt)
*(.igot.plt)
*(.got)
*(.igot)
}
GROUP_START(RAMABLE_REGION)
. = RAM_ADDR;
/* Align the start of image RAM with the
* minimum granularity required by MPU.
*/
. = ALIGN(_region_min_align);
_image_ram_start = .;
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-ram-sections.ld>
#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN
#include <app_smem.ld>
_app_smem_size = _app_smem_end - _app_smem_start;
_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
/*
* For performance, BSS section is assumed to be 4 byte aligned and
* a multiple of 4 bytes
*/
. = ALIGN(4);
__bss_start = .;
__kernel_ram_start = .;
*(.bss)
*(".bss.*")
*(COMMON)
*(".kernel_bss.*")
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif
/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
*/
__bss_end = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
#include <zephyr/linker/common-noinit.ld>
#endif /* CONFIG_USERSPACE */
GROUP_START(DATA_REGION)
SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
{
__data_region_start = .;
__data_start = .;
*(.data)
*(".data.*")
*(".kernel.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_data_relocate.ld>
#endif
__data_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
__data_size = __data_end - __data_start;
__data_load_start = LOADADDR(_DATA_SECTION_NAME);
__data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
#include <zephyr/linker/common-ram.ld>
#include <zephyr/linker/kobject-data.ld>
#include <zephyr/linker/cplusplus-ram.ld>
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-data-sections.ld>
__data_region_end = .;
#ifndef CONFIG_USERSPACE
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
{
/*
* For performance, BSS section is assumed to be 4 byte aligned and
* a multiple of 4 bytes
*/
. = ALIGN(4);
__bss_start = .;
__kernel_ram_start = .;
*(.bss)
*(".bss.*")
*(COMMON)
*(".kernel_bss.*")
#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif
/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
*/
__bss_end = ALIGN(4);
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
{
/*
* This section is used for non-initialized objects that
* will not be cleared during the boot process.
*/
*(.noinit)
*(".noinit.*")
*(".kernel_noinit.*")
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-noinit.ld>
} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
#endif /* CONFIG_USERSPACE */
/* Define linker symbols */
__kernel_ram_end = RAM_ADDR + RAM_SIZE;
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
GROUP_START(ITCM)
SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(4))
{
__itcm_start = .;
*(.itcm)
*(".itcm.*")
__itcm_end = .;
} GROUP_LINK_IN(ITCM AT> ROMABLE_REGION)
__itcm_size = __itcm_end - __itcm_start;
__itcm_load_start = LOADADDR(_ITCM_SECTION_NAME);
GROUP_END(ITCM)
#endif
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
GROUP_START(DTCM)
SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
{
__dtcm_start = .;
__dtcm_bss_start = .;
*(.dtcm_bss)
*(".dtcm_bss.*")
__dtcm_bss_end = .;
} GROUP_LINK_IN(DTCM)
SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(4))
{
__dtcm_noinit_start = .;
*(.dtcm_noinit)
*(".dtcm_noinit.*")
__dtcm_noinit_end = .;
} GROUP_LINK_IN(DTCM)
SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(4))
{
__dtcm_data_start = .;
*(.dtcm_data)
*(".dtcm_data.*")
__dtcm_data_end = .;
} GROUP_LINK_IN(DTCM AT> ROMABLE_REGION)
__dtcm_end = .;
__dtcm_data_load_start = LOADADDR(_DTCM_DATA_SECTION_NAME);
GROUP_END(DTCM)
#endif
/* Located in generated directory. This file is populated by the
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-sections.ld>
#include <zephyr/linker/ram-end.ld>
GROUP_END(RAMABLE_REGION)
#include <zephyr/linker/debug-sections.ld>
/DISCARD/ : { *(.note.GNU-stack) }
SECTION_PROLOGUE(.ARM.attributes, 0,)
{
KEEP(*(.ARM.attributes))
KEEP(*(.gnu.attributes))
}
/* Sections generated from 'zephyr,memory-region' nodes */
LINKER_DT_SECTIONS()
/* Must be last in romable region */
SECTION_PROLOGUE(.last_section,,)
{
#ifdef CONFIG_LINKER_LAST_SECTION_ID
/* Fill last section with a word to ensure location counter and actual rom
* region data usage match. */
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
#endif
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
* calculate this value here. */
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
}
@jlh-makeen Unfortunately, it hasn't been resolved yet. The *.bin file generated after the changes did not fit in the Uboot partition (I had to remove it to load Linux). According to the commands in the photo, I still have virtio0 in the directories, but I still don't have /dev/ttyRPMSG
pwd
/home/neuberfran/zephyrproject/zephyr/build/openamp_rsc_table/zephyr
neuberfran@ubuntu2204:~/zephyrproject/zephyr/build/openamp_rsc_table/zephyr$ ls -lha -S
total 515M
-rwxrwxr-x 1 neuberfran neuberfran 511M abr 12 12:42 zephyr_openamp_rsc_table.bin
-rw-rw-r-- 1 neuberfran neuberfran 655K abr 12 12:42 edt.pickle
-rwxrwxr-x 1 neuberfran neuberfran 647K abr 12 12:42 zephyr_pre0.elf
-rwxrwxr-x 1 neuberfran neuberfran 647K abr 12 12:42 zephyr_openamp_rsc_table.elf
-rw-rw-r-- 1 neuberfran neuberfran 412K abr 12 12:42 libzephyr.a
-rw-rw-r-- 1 neuberfran neuberfran 319K abr 12 12:42 zephyr_pre0.map
-rw-rw-r-- 1 neuberfran neuberfran 318K abr 12 12:42 zephyr_final.map
-rw-rw-r-- 1 neuberfran neuberfran 318K abr 12 12:42 zephyr_openamp_rsc_table.map
-rw-rw-r-- 1 neuberfran neuberfran 282K abr 12 12:42 dts.cmake
-rw-rw-r-- 1 neuberfran neuberfran 188K abr 12 12:42 zephyr.dts.pre
-rw-rw-r-- 1 neuberfran neuberfran 42K abr 12 12:42 zephyr.dts
-rw-rw-r-- 1 neuberfran neuberfran 39K abr 12 12:42 .config
-rw-rw-r-- 1 neuberfran neuberfran 14K abr 12 12:42 cmake_install.cmake
-rw-rw-r-- 1 neuberfran neuberfran 13K abr 12 12:42 linker_zephyr_pre0.cmd
-rw-rw-r-- 1 neuberfran neuberfran 13K abr 12 12:42 linker.cmd
-rw-rw-r-- 1 neuberfran neuberfran 11K abr 12 12:42 isr_tables.c
-rw-rw-r-- 1 neuberfran neuberfran 6,0K abr 12 12:42 linker_zephyr_pre0.cmd.dep
-rw-rw-r-- 1 neuberfran neuberfran 6,0K abr 12 12:42 linker.cmd.dep
-rw-rw-r-- 1 neuberfran neuberfran 4,7K abr 12 12:42 zephyr_openamp_rsc_table.stat
drwxrwxr-x 14 neuberfran neuberfran 4,0K abr 12 12:42 .
drwxrwxr-x 7 neuberfran neuberfran 4,0K abr 12 12:42 ..
drwxrwxr-x 5 neuberfran neuberfran 4,0K abr 12 12:42 arch
drwxrwxr-x 3 neuberfran neuberfran 4,0K abr 12 12:42 boards
drwxrwxr-x 5 neuberfran neuberfran 4,0K abr 12 12:42 cmake
drwxrwxr-x 6 neuberfran neuberfran 4,0K abr 12 12:42 CMakeFiles
drwxrwxr-x 15 neuberfran neuberfran 4,0K abr 12 12:42 drivers
drwxrwxr-x 3 neuberfran neuberfran 4,0K abr 12 12:42 include
drwxrwxr-x 3 neuberfran neuberfran 4,0K abr 12 12:42 kconfig
drwxrwxr-x 3 neuberfran neuberfran 4,0K abr 12 12:42 kernel
drwxrwxr-x 9 neuberfran neuberfran 4,0K abr 12 12:42 lib
drwxrwxr-x 3 neuberfran neuberfran 4,0K abr 12 12:42 misc
drwxrwxr-x 4 neuberfran neuberfran 4,0K abr 12 12:42 soc
drwxrwxr-x 22 neuberfran neuberfran 4,0K abr 12 12:42 subsys
-rw-rw-r-- 1 neuberfran neuberfran 922 abr 12 12:42 zephyr.dts.d
-rw-rw-r-- 1 neuberfran neuberfran 801 abr 12 12:42 snippets_generated.cmake
-rw-rw-r-- 1 neuberfran neuberfran 110 abr 12 12:42 .config.sysbuild
-rw-rw-r-- 1 neuberfran neuberfran 96 abr 12 12:42 .cmake.dotconfig.checksum
-rwxrwxr-x 1 neuberfran neuberfran 40 abr 12 12:42 isrList.bin
@jlh-makeen In portuguese to english novo=new and antigo=old. VsCode only noticed 2 changes
Hi,
https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/subsys/ipc/openamp_rsc_table#id6
I stay trying this since last month in my imx7d-pico (m4 side) Zephyr upstream board is pico_pi_m4 using mailbox=mub
I can run Remoteproc and zephyr on this device but without resource table, vrings and RPMsg: https://www.youtube.com/watch?v=NFyEJXIpq4E
Now I stay trying openamp_rsc_table based on this link below: https://github.com/zephyrproject-rtos/zephyr/pull/60455
I can go up and run everything but the channel and /dev/ttyRPMSG are not created
cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories
cat /sys/kernel/debug/remoteproc/remoteproc0/resource_table
pico_pi_m4.overlay
In linux Yocto A7 Side imx7d-pico-pi-qca-m4.dts (file):
Why I can`t see vdev0buffer in result of the cat /sys/kernel/debug/remoteproc/remoteproc0/carveout_memories And cat /sys/kernel/debug/remoteproc/remoteproc0/resource_table commands?
Why when I change MAX_RPMSG_NUM_BUFS and MAX_RPMSG_BUF_SIZE from 512 to 256 in virtio_rpmsg_bus.c (file in rpmsg/drivers in my linux kernel), nothing change in Number of buffers 8 in my resource_table?
Edited:
Change CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF=8 to CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF=512 in prj.conf. But not solved.