Project

General

Profile

PRU example: build and run RPMsg program on PRU_1

Objective

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.

Steps

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
    • Information on TI_SDK_download_and_installation is found by clicking the link.
      ~/ti-processor-sdk-linux-am62xx-evm-10.01.10.04/example-applications/pru-icss-6.3.0/labs/Hands_on_Labs/lab_5/solution/am62x/PRU_RPMsg_Echo_Interrupt1
      
  • Modify main.c
    • Change CHAN_NAME to rpmsg-pru.
      -#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)
    • In the Linked Resources window: Resource->Linked Resourcse
      • Add New Path Variable: Name: PRU_SSP, Path: ~/ti-processor-sdk-linux-am62xx-evm-10.01.10.04/example-applications/pru-icss-6.1.0
    • Compiler Include Paths (Project->Properties->PRU Compiler->Include Options)
      • Remove ${CCS_BASE_ROOT}/pru/include
      • Add ${PRU_SSP}/include
      • Add ${PRU_SSP}/include/am62x
    • 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 ${PRU_SSP}/lib/rpmsg_lib.lib
    • 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_echo/Debug
      ssh am62x mkdir -p /lib/firmware/pru_demos
      scp rpmsg_echo.out am62x:/lib/firmware/pru_demos
      ssh am62x ln -sf /lib/firmware/pru_demos/rpmsg_echo.out /lib/firmware/am62x-pru0-fw
      
  • Verify whether the rpmsg_echo kernel module is loaded
    ssh am62x ls -l /lib/firmware
    lrwxrwxrwx 1 root root      38 Feb 18 20:32 am62x-pru0-fw -> /lib/firmware/pru_rpmsg/rpmsg_echo.out
    
  • Stop and start PRU_1
    ssh am62x "echo stop > /sys/class/remoteproc/remoteproc2/state" 
    ssh am62x "echo start > /sys/class/remoteproc/remoteproc2/state" 
    
    • If PRU_0 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 remoteproc2: powering up 30078000.pru
      [  167.839411] remoteproc remoteproc2: 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]  remoteproc2#vdev0buffer: registered virtio2 (type 7)
      [  167.886750] rpmsg_pru virtio2.rpmsg-pru.-1.31: new rpmsg_pru device: /dev/rpmsg_pru31
      [  167.892307] remoteproc remoteproc2: remote processor 30078000.pru 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
    test_message1
    test_message2
    
    • 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:
      /home/tools/mitysom-62x/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/bin
      
    • Finish
  • Add source file
    • Select the rpmsg_arm project->right-mouse->Add Files...
    • Browse to
      ~/ti-processor-sdk-linux-am62xx-evm-10.01.10.04/example-applications/pru-icss-6.3.0/liba/Hands_on_Labs/lab_5
      
    • 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
    ssh am62x cat /dev/rpmsg_pru31
    
    • 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.
    • Output should look like the following:
      First command:
      Opened /dev/rpmsg_pru31, sending 100 messages
      
      Message 0: Sent to PRU
      Message 1: Sent to PRU
      Message 2: Sent to PRU
      Message 3: Sent to PRU
      ...
      
      Second Command:
      hello world!hello world!hello world!hello world!hello world! ...
      ...
      

Summary

This example has built a program for PRU_0 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_0, 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.