- Table of contents
- AM62x M4 RPMsg echo to Arm/Linux
AM62x M4 RPMsg echo to Arm/Linux¶
Objectives:¶
- Build and run an M4 program which will echo any RPMsg message it receives back to the sender.
- Build and run an ARM/Linux user program which will send a number of messages to the M4 and receive the messages echoed back.
- Run both of these programs in debuggers.
References¶
- https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/10_01_10_04/exports/docs/linux/Foundational_Components_IPC62x.html#rpmsg-examples
- https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/10_01_10_04/exports/docs/linux/Foundational_Components_IPC62x.html#booting-remote-cores-from-linux-console
- https://dev.ti.com/tirex/explore/content/am62x_academy_9_01_00_00_v1/_build_am62x_academy_9_01_00_00_v1/source/multicore/multicore-dev/ipc-rpmsg.html#building-the-linux-userspace-rpmsg-example
Prerequisites¶
- Code Composer installed
- M4 sdk installed
- ti-processor-sdk installed (TI_SDK_download_and_installation)
- Name the target am62x as described in: Ssh_target_naming_and_port_forwarding
- * Create a project directory on your device
root@mitysom-am62px:~# mkdir /lib/firmware/mcu_rpmsg
Step 1: Building the M4 program¶
- Navigate to toolbar>View>Project Explorer
- In the project explorer window go to import projects.
- Hit the drop down arrow for the "Code Composer Studio" Folder and click "CCS Projects"
- Click the browse button and open the following folder <MCU_PLUS_SDK_INSTALL_DIR>/ti/mcu_plus_sdk_am62x_10_01_00_33/examples/drivers/ipc/ipc_rpmsg_echo_linux/am62x-sk/m4fss0-0_freertos/ti-arm-clang
- Right Click the opened project and select "Build Project"
- Hit the drop down arrow for the "Code Composer Studio" Folder and click "CCS Projects"
- In the project explorer window go to import projects.
- Create new target configuration at toolbar>View>Target Configuration.
- Right Click on "User Defined" and select "New Target Configuration"
- Name the file {som name}_XDS2XX.ccxml.
- Under the "General Setup" section, next to "Connection" open the drop-down arrow and select "Texas Instruments XDS2xx USB Debug Probe"
- Under the "General Setup" section, next to "Board or Device" scroll and select AM62.
- Click the "Save" button under the "Save Configuration" section.
- Name the file {som name}_XDS2XX.ccxml.
- Right click on target configuration you just made and select "Launch Selected Configuration"
- Right Click on "User Defined" and select "New Target Configuration"
- In the debug window right click on "Texas Instruments XDS2xx USB Debug Probe_0/BLAZAR_Cortex_M4F_0(Disconnected:Unkown) and select "Connect Target"
- In the debug toolbar navigate to the CPU reset drop-down arrow and select CPU Reset
- Navigate to toolbar>Run>Load>Load Program and select "Browse project..."
- Select the following file ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freetos_ti-arm-clang/debug/ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freetos_ti-arm-clang.out
- The program is now paused and must be resumed. Go to toolbar>Run>Resume
- You should now see the following output to the CCS and MCU Console
- Navigate to toolbar>Run>Load>Load Program and select "Browse project..."
- In the debug toolbar navigate to the CPU reset drop-down arrow and select CPU Reset
MCU Console
[IPC RPMSG ECHO] Version: REL.MCUSDK.K3.10.00.00.05 (Jul 11 2024 03:09:17): [IPC RPMSG ECHO] Remote Core waiting for messages at end point 13 ... !!! [IPC RPMSG ECHO] Remote Core waiting for messages at end point 14 ... !!! [IPC RPMSG ECHO] Version: REL.MCUSDK.K3.10.01.00.33 (Feb 17 2025 09:52:59):
Step 2: Use remoteproc to start the program on the target¶
- Copy the debug version to the mcu_rpmsg folder
$ cd <WORKSPACE_DIR>/ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freertos_ti-arm-clang/Debug $ scp ipc_rpmsg_echo_linux.mcu-m4f0_0.strip.out root@<IP_ADDRESS>:/lib/firmware/mcu_rpmsg
- link /lib/firmware/am62x-mcu-m4f0_0-fw to the release version
root@mitysom-am62x:~# ln -sf /lib/firmware/mcu_rpmsg/ipc_rpmsg_echo_linux.mcu-m4f0_0.strip.out /lib/firmware/am62-mcu-m4f0_0-fw
- Toggle the m4 remote processor
root@mitysom-am62x:~# echo stop >/sys/class/remoteproc/remoteproc0/state [85761.244261] remoteproc remoteproc0: stopped remote processor 5000000.m4fss root@mitysom-am62x:~# echo start >/sys/class/remoteproc/remoteproc0/state [85776.450011] remoteproc remoteproc0: powering up 5000000.m4fss [85776.456996] remoteproc remoteproc0: Booting fw image am62-mcu-m4f0_0-fw, size 119820 [85776.466410] remoteproc0#vdev0buffer: assigned reserved memory node m4f-dma-memory@9cb00000 [85776.475484] virtio_rpmsg_bus virtio0: rpmsg host is online [85776.482169] remoteproc0#vdev0buffer: registered virtio0 (type 7) [85776.488394] remoteproc remoteproc0: remote processor 5000000.m4fss is now up
- On the M4 UART, you should see output like:
[IPC RPMSG ECHO] Version: REL.MCUSDK.K3.10.01.00.33 (Feb 17 2025 09:52:59): [IPC RPMSG ECHO] Remote Core waiting for messages at end point 13 ... !!! [IPC RPMSG ECHO] Remote Core waiting for messages at end point 14 ... !!!
At this point, the M4 program is running and waiting for the Arm/Linux to send it messages.
Step 3: Building the Arm/Linux user program¶
- Download the example TI git repository.
$ mkdir rpmsg $ cd rpmsg $ git clone https://git.ti.com/cgit/rpmsg/ti-rpmsg-char
- Setup the ARM Toolchain
- Download the necessary infrastructure tools
$ sudo apt install autotools-dev autoconf automake libtool
- Build the example
$ cd ti-rpmsg-char $ autoreconf -i #ignore all warnings $ mkdir outputs $ ./configure --host=aarch64-none-linux-gnu --prefix=$PWD/outputs/ $ make $ make install $ make -C examples $ make -C examples install $ scp examples/rpmsg_char_simple root@<IP_ADDRESS>:mcu_rpmsg
- Boot remote core from linux kernel
root@mitysom-am62x:~# cd /lib/firmware/mcu_rpmsg root@mitysom-am62x:~/lib/firmware/mcu_rpmsg# echo stop > /sys/class/remoteproc/remoteproc0/state root@mitysom-am62x:~/lib/firmware/mcu_rpmsg# echo start > /sys/class/remoteproc/remoteproc0/state
- Check that the /lib/firmware has the proper symbolic link
root@mitysom-am62x:/lib/firmware/mcu_rpmsg# ls -l /lib/firmware/ total 25308 -rw-r--r-- 1 root root 2040 Mar 9 2018 LICENCE.ibt_firmware -rw-r--r-- 1 root root 2046 Mar 9 2018 LICENCE.iwlwifi_firmware lrwxrwxrwx 1 root root 65 Feb 17 15:54 am62-mcu-m4f0_0-fw -> /lib/firmware/mcu_rpmsg/ipc_rpmsg_echo_linux.mcu-m4f0_0.strip.out lrwxrwxrwx 1 root root 79 Mar 9 2018 am62-mcu-m4f0_0-fw-sec -> /usr/lib/firmware/ti-ipc/am62xx/ipc_echo_test_mcu2_0_release_strip.xer5f.signed
- Run the example program
root@mitysom-am62x:/lib/firmware/mcu_rpmsg# rpmsg_char_simple -r 9 -n 9 Created endpt device rpmsg-char-9-1152, fd = 4 port = 1025 Exchanging 9 messages with rpmsg device rpmsg-char-9-1152 on rproc id 9 ... Sending message #0: hello there 0! Received message #0: round trip delay(usecs) = 200406 hello there 0! Sending message #1: hello there 1! Received message #1: round trip delay(usecs) = 138664 hello there 1! Sending message #2: hello there 2! Received message #2: round trip delay(usecs) = 56282 hello there 2! Sending message #3: hello there 3! Received message #3: round trip delay(usecs) = 50497 hello there 3! Sending message #4: hello there 4! Received message #4: round trip delay(usecs) = 55091 hello there 4! Sending message #5: hello there 5! Received message #5: round trip delay(usecs) = 52287 hello there 5! Sending message #6: hello there 6! Received message #6: round trip delay(usecs) = 54886 hello there 6! Sending message #7: hello there 7! Received message #7: round trip delay(usecs) = 47852 hello there 7! Sending message #8: hello there 8! Received message #8: round trip delay(usecs) = 51717 hello there 8! Communicated 9 messages successfully on rpmsg-char-9-1152 TEST STATUS: PASSED
Note: If running the example program fails try stopping and starting the remoteproc again.
Running in Debugger¶
- Open ipc_rpmsg_echo.c
- In the function ipc_rpmsg_echo_main(), change the initial code to look like:
Initial Code
void ipc_rpmsg_echo_main(void *args) { int32_t status; DebugP_log("[IPC RPMSG ECHO] Version: %s (%s %s): \r\n", IPC_FW_VERSION, __DATE__, __TIME__);
Modified Code
void ipc_rpmsg_echo_main(void *args) { int32_t status; int max_wait_time = 180; DebugP_log("[IPC RPMSG ECHO] Version: %s (%s %s): \r\n", IPC_FW_VERSION, __DATE__, __TIME__); DebugP_log("Starting to wait for debugger attach. %d seconds\r\n", max_wait_time); for (int ii = 0; ii < max_wait_time; ++ii) { if ((ii % 5) == 0) { DebugP_log("%3d secs: Waiting for debugger attach\r\n", ii); } ClockP_sleep(1); } DebugP_log("Done waiting for debugger attach. Moving on...\r\n");
- Rerun through "Step 2: Use remoteproc to start the program on the target" to copy the debug release and link it to your remote processor
- Your output should look like the following:
[IPC RPMSG ECHO] Version: REL.MCUSDK.K3.10.01.00.33+ (Feb 17 2025 13:48:55): Starting to wait for debugger attach. 180 seconds 0 secs: Waiting for debugger attach ... 175 secs: Waiting for debugger attach Done waiting for debugger attach. Moving on...
- Your output should look like the following:
- Rerun through "Step 1: Building the M4 program" to run the program via Jtag.
- In ipc_rpmsg_echo_main() put a breakpoint on the line
ClockP_sleep(1):
- Resuming the target 5 times will show the new time in seconds that the program has been waiting for the debugger to attach in the mcu uart terminal.
Summary¶
This page has demonstrated how to:
- Build and run an M4 program which will echo any RPMsg message it receives back to the sender.
- Build and run an ARM/Linux user program which will send a number of messages to the M4 and receive the messages echoed back.
- Debug and run an M4 program.
Go to top