This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] AM62x & AM64x: How to enable PRU RPMsg on Processor SDK Linux 11.0

Part Number: PROCESSOR-SDK-AM62XPROCESSOR-SDK-AM64X

In Linux kernel 6.12, we remove the separate PRU RPMsg (RPMessage) driver, and use the generic RPMsg driver instead. However, the changes were not complete in time for Linux SDK 11.0. This means that PRU RPMsg does not work out-of-the-box in AM62x Linux SDK 11.0 and AM64x Linux SDK 11.0. Please follow these steps to enable PRU RPMsg on these SDK releases.

All changes will be integrated for AM62x Linux SDK 11.1 and AM64x Linux SDK 11.1.

How to run the out-of-the-box PRU Demo? 

Steps to run the out-of-the-box PRU demo are different than the documentation for prior SDK releases. Until the RPMsg Quick Start Guide has been updated, please refer to the reply further down in this FAQ.

Error outputs 

If you try to load firmware with PRU RPMsg without following the below steps, the firmware load may fail like this:

// find which PRU core you want to connect to
// remoteprocX association can change each boot, so use the name to determine
// which core is which
root@am64xx-evm:~# head /sys/class/remoteproc/remoteproc*/name
==> /sys/class/remoteproc/remoteproc0/name <==
78000000.r5f
...
==> /sys/class/remoteproc/remoteproc9/name <==
30034000.pru

// now let's check which firmware will get loaded by default
root@am64xx-evm:~# cat /sys/class/remoteproc/remoteproc9/firmware
am64x-pru0_0-fw

root@am64xx-evm:~# ls -al /lib/firmware/
...
lrwxrwxrwx  1 root root      53 Mar  9  2018 am64x-pru0_0-fw -> /usr/lib/firmware/pru/PRU_RPMsg_Echo_Interrupt0_0.out

// now let's try to load the RPMsg Echo firmware
root@am64xx-evm:~# echo start > /sys/class/remoteproc/remoteproc9/state
[258582.547936] remoteproc remoteproc9: powering up 30034000.pru
[258582.553702] remoteproc remoteproc9: Booting fw image am64x-pru0_0-fw, size 118672
[258582.556543] rproc-virtio rproc-virtio.5.auto: .kick method not defined for 30034000.pru
[258582.556576] remoteproc remoteproc9: failed to probe subdevices for 30034000.pru: -22
[258582.556930] remoteproc remoteproc9: Boot failed: -22
-sh: echo: write error: Invalid argument

  • Step 1: Patch the Linux kernel driver 

    a) Apply kernel driver patch "remoteproc: pru: Add support for virtio rpmsg stack":
    https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/patch/?id=f21a9eb2166ca69563deb32980fde16800c7e77a

    b) rebuild the kernel image & kernel modules, as described in sections
    Preparing to Build
    Configuring the Kernel
    Compiling the Sources
    https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/latest/exports/docs/linux/Foundational_Components_Kernel_Users_Guide.html 

    c) install the kernel image & kernel modules, as described in section
    Installing the Kernel
    https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/latest/exports/docs/linux/Foundational_Components_Kernel_Users_Guide.html#installing-the-kernel

  • Step 2: Update the PRU firmware 

    The generic Linux RPMsg driver uses a different channel name (rpmsg-raw) than the previous PRU RPMsg driver (rpmsg-pru). Update the PRU firmware to use rpmsg-raw.

    The latest PRU Software Support Package (PSSP) can be downloaded from here:
    https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/

    PSSP v6.5.0 will update all firmware to use rpmsg-raw.

    If PSSP v6.5.0 is not released at the time you are reading this FAQ, you can update your PRU firmware like this:

    diff --git a/examples/am64x/PRU_RPMsg_Echo_Interrupt0/main.c b/examples/am64x/PRU_RPMsg_Echo_Interrupt0/main.c
    index f467eed..a8ee63a 100644
    --- a/examples/am64x/PRU_RPMsg_Echo_Interrupt0/main.c
    +++ b/examples/am64x/PRU_RPMsg_Echo_Interrupt0/main.c
    @@ -55,7 +55,7 @@ volatile register uint32_t __R31;
    * Using the name 'rpmsg-pru' will probe the rpmsg_pru driver found
    * at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c
    */
    -#define CHAN_NAME "rpmsg-pru"
    +#define CHAN_NAME "rpmsg-raw"
    #ifndef CHAN_PORT
    #error "CHAN_PORT not defined, must be passed using the compiler CFLAGS"
    #endif

  • Step 3: Run the PRU RPMsg Echo example 

    Copy the updated firmware into the EVM filesystem 

    For example,

    AM62x example
    
    // remove or rename the firmware from before PSSP v6.5.0
    root@am62xx-evm:~# ls -al /lib/firmware/
    ...
    lrwxrwxrwx  1 root root      51 Mar  9  2018 am62x-pru0-fw -> /usr/lib/firmware/pru/PRU_RPMsg_Echo_Interrupt0.out
    lrwxrwxrwx  1 root root      51 Mar  9  2018 am62x-pru1-fw -> /usr/lib/firmware/pru/PRU_RPMsg_Echo_Interrupt1.out
    
    root@am62xx-evm:~# cd /usr/lib/firmware/pru/
    root@am62xx-evm:/usr/lib/firmware/pru# ls
    PRU_Halt.out  PRU_RPMsg_Echo_Interrupt0.out  PRU_RPMsg_Echo_Interrupt1.out
    root@am62xx-evm:/usr/lib/firmware/pru# mv PRU_RPMsg_Echo_Interrupt0.out PRU_RPMsg_Echo_Interrupt0.out.v6_4_0
    root@am62xx-evm:/usr/lib/firmware/pru# mv PRU_RPMsg_Echo_Interrupt1.out PRU_RPMsg_Echo_Interrupt1.out.v6_4_0
    
    // then copy the updated firmware into this location

    Figure out which PRU core is associated with which remoteprocX instance 

    // find which PRU core you want to connect to
    // remoteprocX association can change each boot, so use the name to determine
    // which core is which
    root@am62xx-evm:/sys/devices# head /sys/class/remoteproc/remoteproc*/name
    ...
    ==> /sys/class/remoteproc/remoteproc2/name <==
    30074000.pru
    
    ==> /sys/class/remoteproc/remoteproc3/name <==
    30078000.pru
    
    
    // now let's verify that we will load the updated firmware
    root@am62xx-evm:/sys/devices# cat /sys/class/remoteproc/remoteproc3/firmware
    am62x-pru1-fw
    
    root@am62xx-evm:/sys/devices# ls -al /lib/firmware
    ...
    lrwxrwxrwx  1 root root      51 Mar  9  2018 am62x-pru0-fw -> /usr/lib/firmware/pru/PRU_RPMsg_Echo_Interrupt0.out
    lrwxrwxrwx  1 root root      51 Mar  9  2018 am62x-pru1-fw -> /usr/lib/firmware/pru/PRU_RPMsg_Echo_Interrupt1.out

    Boot the PRU core & determine the associated /dev/rpmsgY instance 

    The simplest way to find the association between PRU core and associated /dev/rpmsgY instance is to check the /dev/ folder before and after initializing the PRU core. The /dev/rpmsgY instance that appears after the PRU core is initialized is associated with that core.

    Note that the same core might have different numbers for remoteprocX and /dev/rpmsgY.

    // the existing rpmsgY instances are associated with remote cores that Linux has
    // already initialized or attached to
    
    root@am62xx-evm:~# ls /dev/
    ...
    remoteproc0
    remoteproc1
    remoteproc2
    remoteproc3
    rfkill
    rpmsg0
    rpmsg1
    rpmsg_ctrl0
    rpmsg_ctrl1
    
    root@am62xx-evm:~# echo start > /sys/class/remoteproc/remoteproc3/state
    [  569.960588] remoteproc remoteproc3: powering up 30078000.pru
    [  569.965107] remoteproc remoteproc3: Booting fw image am62x-pru1-fw, size 80152
    root@am62xx-evm:~# [  569.977230] virtio_rpmsg_bus virtio2: rpmsg host is online
    [  569.977263] virtio_rpmsg_bus virtio2: creating channel rpmsg-raw addr 0x1f
    [  569.977292] rproc-virtio rproc-virtio.5.auto: registered virtio2 (type 7)
    [  569.977302] remoteproc remoteproc3: remote processor 30078000.pru is now up
    
    // use /dev/rpmsg2 to communicate with this PRU core
    root@am62xx-evm:~# ls /dev/
    ...
    remoteproc0
    remoteproc1
    remoteproc2
    remoteproc3
    rfkill
    rpmsg0
    rpmsg1
    rpmsg2
    rpmsg_ctrl0
    rpmsg_ctrl1
    rpmsg_ctrl2

    We can double-check this association by searching for the rpmsgY instance under /sys/devices:

    root@am62xx-evm:~# cd /sys/devices
    root@am62xx-evm:/sys/devices# find -name "rpmsg2"
    ./platform/bus@f0000/30040000.pruss/30078000.pru/remoteproc/remoteproc3/rproc-virtio.5.auto/virtio2/virtio2.rpmsg-raw.-1.31/rpmsg/rpmsg2
    
    // this verifies that rpmsg2 is associated with 30078000.pru & remoteproc3

    Run the echo test 

    root@am62xx-evm:/sys/devices# cd ~
    root@am62xx-evm:~# echo "pru1 echo test" > /dev/rpmsg2
    root@am62xx-evm:~# cat /dev/rpmsg2
    pru1 echo test
    ^C