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.

TMDSIDK574: PRU not started when linux boots

Part Number: TMDSIDK574

Hi,

We're developing our own PRU firmware and want it to be loaded and booted when linux boots.

We build our own yocto based on linux kernel 5.20.

In the logs I get:

[    3.321170] pru-rproc 4b234000.pru: PRU rproc node /ocp/target-module@4b226000/pruss@0/pru@34000 probed successfully
[    3.337707] pru-rproc 4b238000.pru: PRU rproc node /ocp/target-module@4b226000/pruss@0/pru@38000 probed successfully
[    3.354255] pru-rproc 4b2b4000.pru: PRU rproc node /ocp/target-module@4b2a6000/pruss@0/pru@34000 probed successfully
[    3.370772] pru-rproc 4b2b8000.pru: PRU rproc node /ocp/target-module@4b2a6000/pruss@0/pru@38000 probed successfully

All the /sys/class/remoteproc/remoteprocX/state that are PRU have state offline.

In the source of pru_rproc I read a comment:

        /*
	 * rproc_add will auto-boot the processor normally, but this is
	 * not desired with PRU client driven boot-flow methodology. A PRU
	 * application/client driver will boot the corresponding PRU
	 * remote-processor as part of its state machine either through
	 * the remoteproc sysfs interface or through the equivalent kernel API
	 */

This explains why IPU and DSP are started at boot, but not the PRU.
Is there some example where PRU application starts the PRU? All I've seen in the examples are echo start > /sys/class/remoteproc/remoteprocX/state.

A good start for us would be to use the rpmsg_client_sample code, but that one does not start the PRU.

A little hint would be much appreciated!



  • Hi Fredrik,

    The TI Linux SDK for the AM57xx does include PRU firmware that is loaded at boot.  Specifically in the case of the AM57x IDK, we load firmware that implements two additional 100Mbit Ethernet ports (drivers/net/ethernet/ti/prueth.c).  In this case, when the device is probed, the firmware is loaded by the kernel module.

    On the AM57xx GP EVM, we also have a more simple example where we simply specify the PRU firmware in dra7.dtsi, and you start up the firmware from the command line.

    Here is an example running the message echo example on an AM57xx GP EVM:

    # Let's get a listing of the PRU -> remoteproc mapping:


    root@am57xx-evm:~# dmesg | grep -i pru [ 11.439728] remoteproc remoteproc4: 4b234000.pru is available [ 11.468247] pru-rproc 4b234000.pru: PRU rproc node pru@4b234000 probed successfully [ 11.494282] remoteproc remoteproc5: 4b238000.pru is available [ 11.515003] pru-rproc 4b238000.pru: PRU rproc node pru@4b238000 probed successfully [ 11.550235] remoteproc remoteproc6: 4b2b4000.pru is available [ 11.570449] pru-rproc 4b2b4000.pru: PRU rproc node pru@4b2b4000 probed successfully [ 11.593731] remoteproc remoteproc7: 4b2b8000.pru is available [ 11.607475] pru-rproc 4b2b8000.pru: PRU rproc node pru@4b2b8000 probed successfully [ 111.341894] remoteproc remoteproc4: powering up 4b234000.pru [ 111.357269] remoteproc remoteproc4: Booting fw image am57xx-pru1_0-fw, size 77812 [ 111.365674] pruss 4b200000.pruss: configured system_events[63-0] = 00000000,00030000 [ 111.373560] pruss 4b200000.pruss: configured intr_channels = 0x00000005 host_intr = 0x00000005 [ 111.382857] virtio_rpmsg_bus virtio4: creating channel rpmsg-pru addr 0x1e [ 111.405412] remoteproc remoteproc4: remote processor 4b234000.pru is now up [ 111.419317] rpmsg_pru virtio4.rpmsg-pru.-1.30: new rpmsg_pru device: /dev/rpmsg_pru30 [ 363.952649] pruss 4b200000.pruss: unconfigured system_events[63-0] = 00000000,00030000 [ 363.960617] pruss 4b200000.pruss: unconfigured host_intr = 0x00000005 [ 363.967493] remoteproc remoteproc4: stopped remote processor 4b234000.pru


    # Next, we will start up the first core of PRU0 mapped to remoteproc4: root@am57xx-evm:~# echo 'start' > /sys/class/remoteproc/remoteproc4/state [ 814.411893] remoteproc remoteproc4: powering up 4b234000.pru [ 814.417743] remoteproc remoteproc4: Booting fw image am57xx-pru1_0-fw, size 77812 # Firmware loaded here from dts property [ 814.427287] pruss 4b200000.pruss: configured system_events[63-0] = 00000000,00030000 [ 814.435127] pruss 4b200000.pruss: configured intr_channels = 0x00000005 host_intr = 0x00000005 [ 814.444277] virtio_rpmsg_bus virtio4: rpmsg host is online [ 814.444307] virtio_rpmsg_bus virtio4: creating channel rpmsg-pru addr 0x1e [ 814.457143] rpmsg_pru virtio4.rpmsg-pru.-1.30: new rpmsg_pru device: /dev/rpmsg_pru30 [ 814.460155] remoteproc remoteproc4: registered virtio4 (type 7) [ 814.472009] remoteproc remoteproc4: remote processor 4b234000.pru is now up


    # the PRU firmware implements a simple echo client that the PRU will receive, and send back to /dev/rpmsg_pru30: root@am57xx-evm:~# echo 42 > /dev/rpmsg_pru30


    # get the echo'd value from the PRU: root@am57xx-evm:~# cat /dev/rpmsg_pru30 42 ^C root@am57xx-evm:~#

    Now, in your case, you will likely be missing things because not all pieces are mainlined (yet).  To get full remoteproc + rpmsg support with the PRU, it will be required to use a TI kernel.  Our currently released kernel is 4.19.94, and will releasing 5.4.y next quarter.

    Regards,
    Mike

  • Hi and thank you for good advice.

    I managed to extract the relevant parts of prueth.c and came up with the following solution:

    Create a new entry in the .dst:

    my_device {
            compatible = "my_device";
            prus = <&pru1_0>;
    };

    And create a "minimal plaform device" kernel module:

    ...

    static const struct of_device_id my_of_match[] = {
            { .compatible = "my_device" },
            {},
    };
    MODULE_DEVICE_TABLE(of, my_of_match);

    static int my_device_probe(struct platform_device *pdev) {
            int ret;
            struct rproc *pru;
            struct device_node *np;

            np = pdev->dev.of_node;
            pru = pru_rproc_get(np, 0);
            rproc_boot(pru);

            return 0;
    }
    ...

    As soon as i run insmod my_device.ko:

    [  338.713965] remoteproc remoteproc0: powering up 4b234000.pru
    [  338.729980] remoteproc remoteproc0: Booting fw image my_pru_fw, size 84308
    [  338.737335] pru-rproc 4b234000.pru: configured system_events[63-0] = 00000000,00030000
    [  338.745401] pru-rproc 4b234000.pru: configured intr_channels = 0x00000005 host_intr = 0x00000005
    [  338.755117] virtio_rpmsg_bus virtio0: rpmsg host is online
    [  338.755148] virtio_rpmsg_bus virtio0: creating channel rpmsg-pru addr 0x1e
    [  338.761242]  remoteproc0#vdev0buffer: registered virtio0 (type 7)
    [  338.773709] rpmsg_pru virtio0.rpmsg-pru.-1.30: new rpmsg_pru device: /dev/rpmsg_pru30
    [  338.773924] remoteproc remoteproc0: remote processor 4b234000.pru is now up

    It's a little cumbersome that I had to write a kernel module just to boot the pru core. But I guess that's what's being mainlined in q3.

    Now if I make the kernel module load at boot, the pru should start with linux boot as well, and mission accomplished.