How do I create a Connext DDS application with RTI Code Generator and build it on my embedded target with an Arm CPU?

This article describes the procedure to build and run Code Generator (rtiddsgen) examples directly on an embedded target. We will use a Raspberry Pi for this example, but the procedure is similar for other embedded targets. 

In order to build directly on the target, the target must include a native compiler and associated tools and libraries (i.e., Raspbian, Ubuntu, etc.);  real-time target operating systems, such as VxWorks, do not typically contain the required target native compiler and tools.    

If you prefer to cross-compile, or if your target system does not contain native build tools, you can use the cross-compiling method as described in this article:  HOWTO Run RTI Connext DDS on Raspberry Pi.

To get started with generating and compiling rtiddsgen examples directly on-board, follow the steps below:

  1. Install ARM target package on the host

The purpose of this step is to bundle the target-specific tools so they can be copied and extracted onto the target.

Begin by installing the desired ARM target, e.g., rti_connext_dds-X.Y.Z-<pro>-target-<ARM architecture><compiler version>.rtipkg, on top of a standard i86/x64 RTI Connext DDS host installation (e.g., rti_connext_dds-6.1.2-pro-host-x64linux.run). 

For the Raspberry Pi target example, the following target package was used:  rti_connext_dds-6.1.2-pro-target-armv8Linux4gcc7.3.0.rtipkg

  1. Create a deployment tarball  

Use the attached create_rpi_deployment.sh script to copy the required host and target files to the Raspberry Pi target.

The script creates a tarball that contains all the files required to generate and compile Connext DDS applications and run Connext DDS utilities and services on the target (e.g., rtiddsping, rtiroutingservice). 

The create_rpi_deployment.sh script takes two arguments -- NDDSHOME and the target architecture.   The NDDSHOME argument can be specified via a full-path reference to the extracted deployment location or it can be picked up as an environmental variable.    The NDDSHOME environmental variable can be set manually or as part of the Connext helper scripts.

Setting NDDSHOME manually:
    export  NDDSHOME=/home/user/rti_connext-dds_6.1.2

Setting NDDSHOME via helper script:
    source /home/user/rti_connext_dds-6.1.2/resource/scripts/rtisetenv_armv8Linux4gcc7.3.0.bash

Now invoke the create_rpi_deployment script with the configured $NDDSHOME environment variable and target architecture:

$ ./create_rpi_deployment.sh $NDDSHOME armv8Linux4gcc7.3.0
     RPi libraries found. 
     Copying RPi files from: /opt/RTI/rti_connext_dds-6.1.2 ... 
     Tar'ing up folder...
     Done.
     $ ls -lag rti*.tar.gz
     -rw-rw-r--. 1 irwin 190262197 Feb 25 12:05 rti_connext_dds-rpi_202002251205.tar.gz    
  1. Copy the resultant deployment tarball onto the target

This step depends on target accessibility (e.g., ftp, nfs).

The remaining steps are performed on the target.

  1. Extract  the contents of the deployment tarball into a convenient location

The deployment tarball consists of a rti_connext_dds-rpi  directory tree.

For example:

tar xvfz rti_connext_dds-rpi_202205061018.tar.gz

The  rti_connext_dds-rpi tree contains the target-specific tools to build and run Connext DDS applications directly on the target.

  1. Install Java on target if needed and set  the JREHOME environmental variable

The rtiddsgen code generator requires a JRE, so install one if not already installed.

Once installed,  set the JREHOME environmental variable to your Java JRE installation.

For example:

% which java
  /usr/bin/java
% ls -lag /usr/bin/java
  lrwxrwxrwx 1 root 22 Jul  9  2019 /usr/bin/java -> /etc/alternatives/java
% ls -lag /etc/alternatives/java
  lrwxrwxrwx 1 root 43 Jul  9  2019 /etc/alternatives/java -> /usr/lib/jvm/java-11-openjdk-armhf/bin/java
% export JREHOME=/usr/lib/jvm/java-11-openjdk-armhf/

 

  1. HelloWorld Test

To sanity-check the installation, create and run a basic HelloWorld example.

These steps assume you are familiar with DDS and the RTI Tools. (For a much more detailed description of the tools, and a series of tutorials on Connext DDS, please refer to the following document: RTI Connext DDS Getting Started Guide.)

mkdir ~/HelloWorld

cd  ~/HelloWorld

 

edit HelloWorld.idl

struct HelloMsg {
   long id; //@key
   string<256> msg;
};

 

Configure environmental variables (NDDSHOME, LD_LIBRARY_PATH).

Set NDDSHOME  to the location where the deployment package was extracted into.

Set LD_LIBRARY_PATH to the target-specific library in the extracted deployment package. 

For example:     

# manualy configure environmental variables
export NDDSHOME=~/rti_connext_dds-rpi
export LD_LIBRARY_PATH=$NDDSHOME/lib/armv8Linux4gcc7.3.0

# These two steps can be performed automatically via the target architecture specific helper script:
source ~/rti_connext_dds-rpi/resource/scripts/rtisetenv_armv8Linux4gcc7.3.0.bash   

 

Create an example using rtiddsgen:

$NDDSHOME/bin/rtiddsgen -language C++ -example armv8Linux4gcc7.3.0 HelloWorld.idl

 

Build the example:  

make -f makefile_HelloWorld_armv8Linux4gcc7.3.0

 

Run the example:

./objs/armv8Linux4gcc7.3.0/HelloWorld_publisher

./objs/armv8Linux4gcc7.3.0/HelloWorld_subscriber
 

 

As part of the deployment package, the various Connext utility was copied into the $NDDSHOME/bin directory:

ubuntu@rpi4: ls -l $NDDSHOME/bin
-rwxrwxr-x 1 ubuntu ubuntu 5046 May 6 14:18 rtiadminconsole
-rwxrwxr-x 1 ubuntu ubuntu 981 May 6 14:18 rticonverter
-rwxrwxr-x 1 ubuntu ubuntu 3672 May 6 14:18 rtiddsgen
-rwxrwxr-x 1 ubuntu ubuntu 1718 May 6 14:18 rtiddsgen_server
-rwxrwxr-x 1 ubuntu ubuntu 994 May 6 14:18 rtiddsping
-rwxrwxr-x 1 ubuntu ubuntu 972 May 6 14:18 rtiddsprototyper
-rwxrwxr-x 1 ubuntu ubuntu 966 May 6 14:18 rtiddsspy
-rwxrwxr-x 1 ubuntu ubuntu 2846 May 6 14:18 rtilauncher
-rwxrwxr-x 1 ubuntu ubuntu 2063 May 6 14:18 rtimonitor
-rwxrwxr-x 1 ubuntu ubuntu 980 May 6 14:18 rtipersistenceservice
-rwxrwxr-x 1 ubuntu ubuntu 4261 May 6 14:18 rtipkginstall
-rwxrwxr-x 1 ubuntu ubuntu 1037 May 6 14:18 rtipssh
-rwxrwxr-x 1 ubuntu ubuntu 979 May 6 14:18 rtirecordingindexer
-rwxrwxr-x 1 ubuntu ubuntu 980 May 6 14:18 rtirecordingservice
-rwxrwxr-x 1 ubuntu ubuntu 2747 May 6 14:18 rtirecordingservice_list_tags
-rwxrwxr-x 1 ubuntu ubuntu 980 May 6 14:18 rtireplayservice
-rwxrwxr-x 1 ubuntu ubuntu 976 May 6 14:18 rtiroutingservice
-rwxrwxr-x 1 ubuntu ubuntu 964 May 6 14:18 rtirssh
-rwxrwxr-x 1 ubuntu ubuntu 1884 May 6 14:18 rtishapesdemo
-rwxrwxr-x 1 ubuntu ubuntu 1254 May 6 14:18 rtisystemdesigner
-rwxrwxr-x 1 ubuntu ubuntu 812 May 6 14:18 rtiwanserver
-rwxrwxr-x 1 ubuntu ubuntu 984 May 6 14:18 rtixmlconverter

Not all of these can be run on the Raspberry Pi due to special requirements needed such as RTI Admin Console and RTI System Designer.  However, the command-line utilities work as expected and are very useful for debugging and DDS application development --- rtiddsping, rtiddsspy, etc.

Notes:

create_rpi_deployment.sh script contents

#!/bin/bash

if [ -z "$1" ]; then
 echo "! Please specify location of RTI Connext installation."
 echo "Syntax => create_rpi_installation <Connext installation> <ARM target architecture>"
 exit 1
fi

if [ -z "$2" ]; then
 echo "! Please specify ARM target architecture. Example: armv6vfph"
 echo "Syntax => create_rpi_installation <Connext installation> <ARM target architecture>"
 exit 1
fi

 installation_loc="$1"
 rpi_arch="$2"

 rpi_folder="rti_connext_dds-rpi"
 pi_lib_dir="$installation_loc/lib/$rpi_arch"

 if [ ! -d "$pi_lib_dir" ]; then
  echo "! RPi libraries ($rpi_arch) not found in RTI Connext installation path."
  echo "! Searched for $pi_lib_dir"
  exit 1
  else
  echo "RPi libraries found."
 fi

 if [ -d "$rpi_folder" ]; then
 read -p "$rpi_folder folder already exists. Delete it? (y/n) " yn
  case $yn in
   [Yy]* ) rm -rf $rpi_folder;;
   [Nn]* ) echo "Exiting"; exit;;
  esac
 fi

 echo "Copying RPi files from: $1 ..."
 mkdir $rpi_folder
 mkdir $rpi_folder/lib
 mkdir $rpi_folder/resource
 mkdir -p $rpi_folder/resource/app/bin
 mkdir -p $rpi_folder/resource/app/lib
 mkdir -p $rpi_folder/resource/app/app_support
 mkdir -p $rpi_folder/resource/xml
 cp -r $installation_loc/rti_versions.xml $rpi_folder/
 cp -r $installation_loc/RTI_License_Agreement.pdf $rpi_folder/
 cp -r $installation_loc/include $rpi_folder/
 cp -r $installation_loc/bin $rpi_folder/
 cp -r $installation_loc/lib/$rpi_arch $rpi_folder/lib/
 cp -r $installation_loc/lib/java $rpi_folder/lib/
 cp -r $installation_loc/resource/scripts $rpi_folder/resource/
 cp -r $installation_loc/resource/idl $rpi_folder/resource/
 cp -r $installation_loc/resource/schema $rpi_folder/resource/
 #cp -r $installation_loc/resource/app/lib/$rpi_arch $rpi_folder/resource/app/lib/
 cp -r $installation_loc/resource/app/lib/java $rpi_folder/resource/app/lib/
 cp -r $installation_loc/resource/app/bin/$rpi_arch
 $rpi_folder/resource/app/bin/
 cp -r $installation_loc/resource/app/app_support/rtiddsgen
 $rpi_folder/resource/app/app_support
 cp -r $installation_loc/resource/xml $rpi_folder/resource/
 echo "Tar'ing up folder..."
 DATE=$(date +"%Y%m%d%H%M")
 tar -zcf rti_connext_dds-rpi_$DATE.tar.gz rti_connext_dds-rpi
 rm -f -R rti_connext_dds-rpi
 echo "Done."
Platform:

Comments

- Updated examples to 6.1.1 and armv8Linux4gcc7.3.0

- Added some clarify comments

 

Updated the create_rpi_deployment.sh script to remove the non-relevant line:

   #cp -r $installation_loc/resource/app/lib/$rpi_arch $rpi_folder/resource/app/lib/

This was to remove the attempt of copying a non-exist target directory.

     cp: cannot stat 'rti_connext_dds-6.1.2/resource/app/lib/armv8Linux4gcc7.3.0': No such file or directory

Updated examples to 6.1.2

(Also tested on 7.2.0 .. Raspberry Pi 5)