PRU example: build and run RPMsg program on PRU_1


The objective of this example is to build and run an RPMsg program which will run a program on the PRU which will echo a message sent from the ARM so the message is received by the ARM.

This example will not demonstrate new debugging techniques but it does create a multi-processor example that will be debugged in the next example.

This example performs most of the target interaction through the use of a Terminal view in Code Composer. Since Code Composer is not able to make a SSH Terminal connection directly to the target, the target communications is performed by creating a Local Window on the host and then using ssh/scp commands within that window. The target interactions would probably be easier if a direct console connection were used instead but it seems useful to know how to do everything within Code Composer.


Create and build the PRU program

  • Start a new workspace
  • Create a new CCS project
    • Processor is AM62x
    • Select the PRU tab
    • Name the project: rpmsg_echo
    • Empty Project
    • Finish
  • Add source file
    • Project->Add Files...
    • Browse to location below and Add all files except Makefile. Copy to workspace
  • Modify main.c
    • Change CHAN_NAME to rpmsg-pru. Before
      #define CHAN_NAME            "rpmsg-client-sample" 
      //#define CHAN_NAME            "rpmsg-pru" 

      //#define CHAN_NAME            "rpmsg-client-sample" 
      #define CHAN_NAME            "rpmsg-pru" 
  • Modify Project Properties (Project->Properties)
    • Compiler Include Paths (Project->Properties->PRU Compiler->Include Options)
      • Delete ${CCS_BASE_ROOT}/pru/include
      • Add ~/ti-processor-sdk-linux-am62xx-evm-
      • Add ~/ti-processor-sdk-linux-am62xx-evm-
    • Linker Heap and Stack sizes (Project->Properties->PRU Linker->Basic Options)
      • Heap size of 1024
      • Stack size of 1024
    • Linker Libraries (Project->Properties->PRU Linker->File Search Path)
      • In Include library file or command file as input:
        • Add ~/ti-processor-sdk-linux-am62xx-evm-
    • Apply and close
  • Build the project

Copy PRU program to target and start

  • Copy to target, fix up /lib/firmware
    • Open a Terminal View on the Local Target
      cd <workspace_file>/rpmsg_pru/Debug
      ssh am62x mkdir -p /lib/firmware/pru_demos
      scp rpmsg_pru.out am62x:/lib/firmware/pru_demos
      ssh am62x ln -sf /lib/firmware/pru_demos/rpmsg_pru.out /lib/firmware/am62x-pru1-fw
  • Verify whether the rpmsg_pru kernel module is loaded
    ssh am62x lsmod | grep rpm
    • If the output does not show rpmsg_pru, then load that module.
      ssh am62x /sbin/insmod /lib/modules/`ssh am62x uname -r`/kernel/drivers/rpmsg/rpmsg_pru.ko
    • Verify whether the rpmsg_pru kernel module is loaded
      ssh am62x lsmod | grep rpm
      • Should see rpmsg_pru
  • Stop and start PRU_1
    ssh am62x "echo stop > /sys/class/remoteproc/remoteproc3/state" 
    ssh am62x "echo start > /sys/class/remoteproc/remoteproc3/state" 
    • If PRU_1 is already stopped, then the stop command may produce an error like:
      sh: line 0: echo: write error: Invalid argument
    • After the start, you should see messages like this on the console
      [  167.824111] remoteproc remoteproc3: powering up
      [  167.839411] remoteproc remoteproc3: Booting fw image am62x-pru1-fw, size 121020
      [  167.872553] virtio_rpmsg_bus virtio2: rpmsg host is online
      [  167.873267] virtio_rpmsg_bus virtio2: creating channel rpmsg-pru addr 0x1f
      [  167.880232]  remoteproc3#vdev0buffer: registered virtio2 (type 7)
      [  167.886750] rpmsg_pru virtio2.rpmsg-pru.-1.31: new rpmsg_pru device: /dev/rpmsg_pru31
      [  167.892307] remoteproc remoteproc3: remote processor is now up
    • These messages could also be seen in the Terminal View by using:
      ssh am62x dmesg | tail -10

Manually send messages to the PRU

  • Manually send messages to the PRU
    ssh am62x "echo test_message1 >/dev/rpmsg_pru31" 
    ssh am62x "echo test_message2 >/dev/rpmsg_pru31" 
  • Manually read the messages sent back from the PRU
    ssh am62x cat /dev/rpmsg_pru31
    • You will need to hit ctrl-C to break out of the cat command.

Create an ARM program to send and receive messages from the PRU

  • Create a new C/C++ project
    • C Managed Build, Next
    • Project Name: rpmsg_arm
    • Empty Project
    • Cross GCC
    • Next
    • Leave Debug and Release options.
    • Next
    • Cross compiler prefix: aarch64-none-linux-gnu-
    • Cross Compiler path: Browse to:
    • Finish
  • Add source file
    • Select the rpmsg_arm project->right-mouse->Add Files...
    • Browse to
    • Select the rpmsg_pru_user_space_echo.c file. Copy file to workspace
  • Turn off buffering for stdout. Without this, the output lines will not appear right away when using gdbserver.
    • Add the call to setvbuf as shown below:
      int main(void)
          struct pollfd pollfds[1];
          int i;
          int result = 0;
          setvbuf (stdout, NULL, _IONBF, 0);
  • Build the project
    • Project->Build All
  • Copy program to target
    • In Terminal window
      cd <workspace_directory>/rpmsg_arm/Debug/
      scp rpmsg_arm am62x:.
  • Run on target
    ssh am62x ./rpmsg_arm
    • The program sends and receives a message to and from the PRU. This is done 100 times and the messages are printed to the terminal.


This example has built a program for PRU_1 which receives messages from the ARM and then echoes the message back to the sender. A program for the ARM has also been built which sends 100 messages to PRU_1, reads the responses, and prints the progress to stdout.

This example uses multiple projects within one workspace where the different projects are for different processors.

Go to top
Add picture from clipboard (Maximum size: 1 GB)