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.

AM4376: Device tree settings to access PRUs

Part Number: AM4376
Other Parts Discussed in Thread: AM4372,

Hi,

We are trying to access the PRUs from the ARM running Linux. The kernel is the linux-ti kernel 5.10 with RT patches. Do we need to add anything to the device tree for the Linux PRU drivers to be able to access the PRUs?

The drivers are built and appear to be included. We can start and stop the PRUs with

echo "start" > /sys/class/remoteproc/remoteproc1/state

but not see the PRUs under /dev/rpmsg*.

Best regards,

Jonathan

  • Hi,

    Did now read in the TI documentation that kernels later than 5.4 do not have support for remoteproc and RPMsg to communicate with PRUs. How should we communicate with PRUs and use them if we have a later kernel than that?

    "Linux RPMsg communication with PRU cores is supported up through TI’s Linux kernel 5.4 releases (Linux Processor SDK 7.x). Linux RPMsg communication with PRU cores was not implemented on Linux Processor SDK 8.0."

    https://software-dl.ti.com/processor-sdk-linux/esd/AM65X/08_00_00_04/exports/docs/linux/Foundational_Components/PRU-ICSS/RPMsg_Quick_Start_Guide.html

  • Hello Jonathan,

    We did not support PRU RPMsg for two software releases: SDK 8.0, and SDK 8.1. We added back PRU RPMsg support in SDK 8.2. Since AM437x SDK releases were 7.3 and 8.2, PRU RPMsg is supported on AM437x for all TI Linux SDK releases.

    You will see that that line is only in the SDK docs for AM65x and AM64x SDK 8.0 and SDK 8.1 releases. For AM437x SDK 8.2, we removed it: https://software-dl.ti.com/processor-sdk-linux/esd/AM437X/08_02_00_24/exports/docs/linux/Foundational_Components/PRU-ICSS/RPMsg_Quick_Start_Guide.html

    Are you following that documentation and RPMsg is not working? If so, please provide additional information.

    Regards,

    Nick

  • Also, what do you mean by "access"? RPMsg can be used to send 512 byte packets between cores. So if that is what you are looking for, RPMsg is a good solution.

    However, if your intent is for something different, like allowing Linux userspace to directly read a section of PRU memory, then we would need to have additional discussion.

    Regards,

    Nick

  • Thank you for the reply! 512 byte packets would be perfect for us. Since we have kernel 5.10 which is included in SDK 8.2 then it should work.

    Then we are back to the original question of the dts and getting the /dev/rpmsg devices to appear.

    Our dts includes am4372.dtsi. That file does not mention rpmsg, however the PRUs are defined. Do we need to do anything than including that file to make the PRUs rpmsg interface appear under /dev/, for example updating status to "okay" for some module?

  • Hello Jonathan,

    1) devicetree: think of the devicetree files as board-level files, or processor-level files. am4372.dtsi is a processor level file - it's job is to define all the circuits and peripherals inside the AM437x processor. So you won't see software constructs in this file. in almost all situations, you do NOT want to modify this file, you want to modify the board-level .dts file instead... except if you need to change the RPMsg interrupt settings.

    Go to the PRU core definitions (pru1_0, pru1_1, etc). See that "interrupts" and "interrupt-names" entry there? That configures the PRU interrupt controller (INTC) for the interrupts going to the Linux cores. You will find the other INTC settings for interrupts going to the PRU cores in the PRU firmware's intc_map files: https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am437x/PRU_RPMsg_Echo_Interrupt0_0. The PRU firmware needs to know what settings to use to interrupt the Linux core - e.g., https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am437x/PRU_RPMsg_Echo_Interrupt0_0/main.c variable TO_ARM_CORE.

    For more information on INTC settings, reference https://software-dl.ti.com/processor-sdk-linux/esd/AM437X/08_02_00_24/exports/docs/common/PRU-ICSS/INTC_Configuration.html

    2) Did you make sure to use the RPMsg example project as described in the RPMsg quick start guide? https://software-dl.ti.com/processor-sdk-linux/esd/AM437X/08_02_00_24/exports/docs/linux/Foundational_Components/PRU-ICSS/RPMsg_Quick_Start_Guide.html#rebuilding-the-pru-firmwares-from-source

    The RPMsg libraries can be kinda heavy, so PRU projects that do not use them might not include them in the firmware's makefile.

    Regards,

    Nick

  • Hi,

    We have tested all we could think of and still not been able to get the rpmsg devices to appear under /dev/. Tried to summarize what we have tested below. Any pointers to what might be wrong is very much appreciated!

    A long time ago on the 4.9 kernel a colleague had tried the ethernet pru, so that was still enabled in the defconfig. I removed CONFIG_TI_PRUETH from defconfig using menuconfig, built a new image and tested. The behavior was the same as before. Is there something else that could be leftover from old PRUETH tests that need removal?

    Before we removed the CONFIG_TI_PRUETH from defconfig (using menuconfig) we tried the following.

    We have tried the example projects:

    PRU_RPMsg_Echo_Interrupt0_0
    PRU_RPMsg_Echo_Interrupt0_1
    PRU_RPMsg_Echo_Interrupt1_0
    PRU_RPMsg_Echo_Interrupt1_1

    The TO_ARM_CORE variables matches the dtsi interrupts first value.

    The Remoteproc and Rpmsg drivers have been enabled with menuconfig, and we have tested both m and y as options. The kernel is the TI with RT patch: 5.10.145-rt74.

    We have tested insmod /lib/modules/5.10.145-rt74-gfe20c3f42e/kernel/drivers/rpmsg/rpmsg_pru.ko on target, no luck.

    We have also tried enable the PRUs by setting the status to okay in our dts:

    &pruss1 {
           status = "okay";
    };

    &pru1_0 {
           status = "okay";
    };

    &pru1_1 {
           status = "okay";
    };

    &pruss1_intc {
           status = "okay";
    };

    &pruss0 {
           status = "okay";
    };

    &pru0_0 {
           status = "okay";
    };

    &pru0_1 {
           status = "okay";
    };

    &pruss0_intc {
           status = "okay";
    };

    This is what we see when we attempt to load:

    root@our-name:/lib/firmware/test-pru# cp PRU_RPMsg_Echo_Interrupt0_0.out ../am437x-pru1_0-fw
    root@our-name:/lib/firmware/test-pru# echo start > /sys/class/remoteproc/remoteproc1/state
    root@our-name:/lib/firmware/test-pru# dmesg
    [    0.000000] Booting Linux on physical CPU 0x0
    [    0.000000] Linux version 5.10.145-rt74-gfe20c3f42e (oe-user@oe-host) (arm-epf-linux-gnueabi-gcc (GCC) 11.3.0, GNU ld (GNU Binutils) 2.38.20220708) #1 PREEMPT_RT Fri2
    [    0.000000] CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c53c7d                                                                                          
    [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache

    ...

    [  880.555532] remoteproc remoteproc1: powering up 54434000.pru
    [  880.556073] remoteproc remoteproc1: Booting fw image am437x-pru1_0-fw, size 76200                                                                                     
    [  880.560108] virtio_rpmsg_bus virtio0: rpmsg host is online                                                                                                            
    [  880.560267]  remoteproc1#vdev0buffer: registered virtio0 (type 7)                                                                                                     
    [  880.560283] remoteproc remoteproc1: remote processor 54434000.pru is now up
    root@our-name:/lib/firmware/test-pru# ls /dev/ | grep pru

    As you can see there is no mention about /dev/rpmsg_pru* or ti-pruss in the dmesg output, but the remoteproc message indicates it is up.

    1. Do we need to modify our dts to enable the PRUs or just include am4372.dtsi? In that case do you have an example dts for this SoC?

    2. In the SDK there are 4 PRU_RPMsg_Echo_Interrupt projects. In the /sys/class/remoteproc/ directory there are 5 sub-directories remoteproc0 to 5. I thought the am4376 had two PRUs according to the datasheet. Which project should be loaded to which PRU?

    Any other pointers would be much appreciated!

    Best regards,

    Jonathan

  • Hello Jonathan,

    1) What board are you using? The board-level devicetree file decides whether PRU Ethernet firmware is loaded into the PRU cores, or whether general purpose PRU firmware will be loaded into the PRU cores.

    Let's take the AM437x IDK as an example (am437x-idk-evm.dts). Notice that pruss1-eth is defined, and there all all those mdio, emac, etc entries for PRU? That means with the out-of-the-box settings, AM437x IDK will load the PRU Ethernet firmware onto the PRUs and try to start the Linux driver. Also, since a Linux driver starts the PRUs, you will not have permission to halt the PRU cores to load different PRU firmware into them.

    If that is the case, you will need to modify the am437x-idk-evm.dts file to remove all that PRU Ethernet stuff, rebuild the am437x-idk-evm.dtb file, and put the new dtb file in the AM437x EVM's Linux filesystem's /boot/ directory (NOT the boot partition, that's different. On an SD card, the filesystem is in the root partition).

    See am437x-gp-evm.dts and am437x-sk-evm.dts for examples of boards where the PRU cores are enabled by default in the processor-level devicetree files, and then not modified in the board-level dts file.

    2) here are useful command line debugging commands 

    Which remoteprocX device is which?
    
    # head /sys/class/remoteproc/remoteproc*/name
    
    Let's say we're looking at remoteproc0
    is remoteproc0 running? If so, what firmware is it running?
    
    # cat /sys/class/remoteproc/remoteproc0/state
    # cat /sys/class/remoteproc/remoteproc0/firmware
    
    what if I want to stop and start the PRU core?
    (assuming that the core was NOT loaded by PRU Ethernet driver)
    
    # echo stop > /sys/class/remoteproc/remoteproc0/state
    # echo start > /sys/class/remoteproc/remoteproc0/state

    Note that the Linux RemoteProc driver looks for a firmware binary (or a link to a firmware binary) in the /lib/firmware directory, with the name "firmware-name" specified in the am4372.dtsi processor-level device tree file. e.g., PRU1_0 looks for /lib/firmware/am437x-pru1_0-fw, etc

    Regards,

    Nick

  • Hi,

    Thank you for all the help!

    We finally realized that it was a simple error when we renamed the .out files to the names specified in the am4372.dtsi file. The binaries got mixed up, which resulted in successful loading of the PRU but the rpmsg devices did not show up.

    Best regards,

    Jonathan

  • Thanks for posting your solution Jonathan! Glad it worked out. If you have followup questions, feel free to create a new e2e thread.

    Regards,

    Nick