HOWTO Run RTI Connext DDS on Raspberry Pi

Originally posted in 2012, updated September 2016

1 Introduction

RTI has recently released a community port of RTI Connext DDS for Raspberry Pi, an inexpensive credit-card-sized single-board computer with an ARM processor. RTI Connext DDS is RTI's implementation of the OMG Data Distribution Service specification. 

This HOWTO describes the steps you need to follow to set up your machine to build DDS applications able to run on a Raspberry Pi. We will use a cross-compiler that can be run on a 32- or 64-bit Linux machine, but we will also provide some links with documentation to cross-compile from different platforms.

The document is organized as follows:

  • Section 2 explains how to set up your Raspberry Pi to run a supported version of Raspbian.
  • Section 3 shows how to install RTI Connext DDS on your Linux host.
  • Section 4 explains how to install the RTI Connext DDS libraries for Raspberry Pi on your Linux host.
  • Section 5 describes the steps you need to follow to set up a cross-compiling environment for Raspberry Pi.
  • Section 6 illustrates the development of DDS applications for Raspberry Pi.

2 Install Raspbian

Before installing RTI Connext DDS on your Raspberry Pi check that you have a supported image of Raspbian (hard-float ABI) installed in your SD. You can downloaded the latest version from the RaspberryPi repository or Raspian Images. We have tested our application on several versions starting with 2012-10-28-wheezy-raspbian images up to 2016-05-27-raspbian-jessie. If you find any issue running DDS applications on newer images, post a comment and we will look into it.

2.1 Install Raspbian image into the SD card

First, download and unzip the latest image (e.g., 2016-05-27-raspbian-jessie).

unzip 2016-05-27-raspbian-jessie.zip

To copy the image to the SD card, on Unix-based systems (e.g., Linux or MacOSX) you will need to use the dd command. If you are using Windows, use Win32DiskManager.

Note: This tutorial covers the process on Linux and MacOSX environments, you can find instructions on how to install the image from a Windows system here.

Before copying the image to the SD card, identify the device name comparing the results of df -h before and after inserting the SD card on your machine.

On Linux, the filesystem returned by df -h will be something like /dev/mmcblk0p1 (device name is /dev/mmcblk0 and partition number is p1) or /dev/sdd1 (device name is /dev/sdd and partition number is 1).

df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        19G  7.6G   11G  42% /
udev            494M  4.0K  494M   1% /dev
tmpfs           201M  812K  200M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            501M  124K  501M   1% /run/shm
/dev/sdd1        56M   17M   39M  30% /media/Untitled

On MacOSX, the filesystem returned by df -h will be something like /dev/disk3s1, where /dev/disk3 is the device name and s1 is the partition number.

df -h
Filesystem      Size   Used  Avail Capacity  Mounted on
/dev/disk0s2   465Gi  439Gi   26Gi    95%    /
devfs          112Ki  112Ki    0Bi   100%    /dev
map -hosts       0Bi    0Bi    0Bi   100%    /net
map auto_home    0Bi    0Bi    0Bi   100%    /home
/dev/disk3s1    56Mi   35Mi   21Mi    63%    /Volumes/Untitled

Once you have identified the device name, unmount the file system (if your SD card has more than one partition unmount all of them).

On Linux:

umount /media/Untitled

On MacOSX:

sudo umount /Volumes/Untitled

Now, copy the image to the SD card using the dd command. You should use the device name without the partition name (e.g., if the device name was /dev/sdd1 set of=/dev/sdd).

Note: You will lose all data stored on the device so be EXTREMELY CAREFUL specifying the right device.

On Linux, as indicated here, setting block size (bs) to 4M will work most of the time, try 1M if the process fails.

dd bs=4M if=/path/to/2016-05-27-raspbian-jessie.img of=/dev/sdd

On MacOSX, use /dev/rdiskX instead of /dev/diskX when specifying the output file (e.g., if the device name was /dev/disk3s1 set of=/dev/rdisk3). Set block size to 1m, as indicated here.

dd bs=1m if=/path/to/2016-05-27-raspbian-jessie.img of=/dev/rdisk3

If you get a "permission denied" error, triple-check you are specifying the right device on the of= argument and the use sudo as in:

sudo dd bs=1m if=/path/to/2016-05-27-raspbian-jessie.img of=/dev/rdisk3
Copying the image can take some time, depending on the size of the image and the speed of the SD card. For me it was about 8MB/sec on a MacBookPro, so the 4 GB raspbian-jessie image took about 8 minutes.
 

Finally, remove the SD card, put into the Raspberry Pi board and boot the board. You should have a monitor and a keyboard attached to the Raspberry Pi. You will see the board boot logging the process to the screen.

On the older raspbian images after the board finished booting the display would show the Rasbpain configuration screen.

Raspberry Pi configuration screen

On the newer Raspbian images after the boot the window system will start directly the LXDE desktop:

Raspbian Jessie LXDE desktop 

2.2 Configure Raspbian

The first time you boot the Raspberry Pi you will see a configuration menu with some actions. These are the actions we recommend you to do:

  • Expand root partition to fill SD card (expand_rootfs).
  • Change the password for the "pi" user (by default username is "pi" and password "raspberry").
  • Enable SSH server to allow remote access.

In the older Raspbian distributions this was done using the Raspbian configuration screen. In the newer ones with the LXDE desktop you need to go to the Raspberry menu and select "Preferences->Raspberry Pi Configuration" this will bring a configuration dialog (see below) where you can perform the actions listed above.

RaspberryPi configuration dialog

Once you are finished configuring the system, reboot the Rasbperry Pi. If you are using the older images with the special config screen you can access the configuration menu again running the command raspi-config as root. On the newer images it is available from the Raspberry menu.

2.3 Connect to the Raspberry over Ethernet

The easiest way to download the software into the Raspberry Pi is to use the ethernet connection. The older Raspberry Pis (up to model 2) did not include a wireless Ethernet adaptor so to simplify things the instrutions assume you are using the wired ethernet connector.

There are two approaches to this:

  1. Use a DHCP-capable router.
  2. Configure the IP address manually.

2.3.1 Option 1: Use a DHCP-capable Router

The simplest option is to plug the Raspberry to a DHCP enabled router/switch. If you have one of these routers, you can connect the Raspberry Pi to one of the ports and the router will automatically assign an IP address to the Raspberry Pi automatically.

If this process succeeds you will be able to see the IP address using the ifconfigcommand:

pi@raspberrypi ~ $ ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:03:24:b0  
          inet addr:192.168.33.10  Bcast:192.168.33.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:227 errors:0 dropped:0 overruns:0 frame:0
          TX packets:88 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:21872 (21.3 KiB)  TX bytes:17740 (17.3 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Here we see that the router assigned the IP address 192.168.33.10 to the eth0 interface on the Raspberry Pi.

2.3.2 Option 2: Configure the IP Address Manually

If you do not have a DHCP enabled router available you can connect the Raspberry Pi directly to the Ethernet port of another computer. You can use a regular Ethernet cable (no need for a so-called crossover cable) as the Raspberry Pi is smart enough to detect the direct connection.

If you connect your laptop or PC directly to the Raspberry Pi with an ethernet cable you also need to set the IP addresses manually as there is no DHCP server to assign them to the Raspberry Pi.

It is possible that when you connect the ethernet cable from the host to the Raspberry Pi, the host's network interface has already an auto-assigned IP address (e.g., 169.254.x.x). You can check that by typing ifconfigon Linux or MacOSX (or ipconfig on Windows). For instance, on MacOSX you will see something like:

ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	inet 127.0.0.1 netmask 0xff000000 
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 58:b0:35:fe:09:22 
	inet6 fe80::5ab0:35ff:fefe:922%en0 prefixlen 64 scopeid 0x4 
	inet 169.254.71.49 netmask 0xffff0000 broadcast 169.254.255.255
	media: autoselect (100baseTX <full-duplex,flow-control>)
	status: active
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 90:27:e4:e8:f1:e8 
	inet6 fe80::9227:e4ff:fee8:f1e8%en1 prefixlen 64 scopeid 0x5 
	inet 10.30.1.124 netmask 0xffffff00 broadcast 10.30.1.255
	media: autoselect
	status: active

In this case, en0 (the name MacOSX uses for the wired ethernet interface) was assigned the address 169.254.71.49 with the mask 0xffff0000 (i.e., 255.255.0.0).

If the host has an IP address, you only need to configure manually the address on the Raspberry Pi. If the host does not, you need to configure manually the IP address on both the host and the Raspberry Pi.

In our situation we only needed to configure manually the Raspberry Pi. To do this we need to choose an IP address that is on the same network as the host, for instance 169.254.71.1 as it is on the same 169.254.x.x network. You can set this IP address on the Raspberry Pi is done using the ifconfig command:

sudo ifconfig eth0 169.254.71.1 netmask 255.255.0.0 up

Once you have set the IP address you can use SSH to log in from your host using the username "pi" and the password you set on section 2.2. If you did not change the password, use "raspberry", which is the one configured by default. The messages below will vary depending on your host and raaspbian image.

ssh pi@169.254.71.1
The authenticity of host '169.254.71.1 (169.254.71.1)' can't be established.
RSA key fingerprint is ba:8a:bf:90:a0:42:fb:ba:34:74:03:b3:2d:55:50:f4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '169.254.71.1' (RSA) to the list of known hosts.
pi@169.254.71.1's password: 
Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Dec 16 21:32:50 2012 from 169.254.71.49
pi@raspberrypi ~ 
Note: If you want to set manually the IP address on both host and the Raspberry Pi you will need to pick two IP addresses. We recommend you to use addresses that fall in the private IP range. For instance, two in the 192.168.x.x range: 192.168.1.1 and 192.168.1.2. These addresses use a 255.255.255.0 mask. On the Raspberry Pi run:
sudo ifconfig eth0 192.168.1.1 netmask 255.255.255.0 up
If you are using a Linux host (assuming you are using the eth0 interface) run:
sudo ifconfig eth0 192.168.1.2 netmask 255.255.255.0 up
On MacOSX host (assuming you are ussing the en0 interface run the following command (you can also use the GUI under system utilities):
sudo ifconfig en0 192.168.1.2 netmask 255.255.255.0 up

2.3.3 Configure the Raspberry Pi get the same assigned IP each time it boots

If you want to setup the Raspberry Pi as a headless device—and you anticipate you will not be able to connect it to a DHCP-enabled router—you need to configure it so that it gets a manual IP address each time it boots. The effect of the ifconfig command only lasts until the next reboot, so you boot the Raspberry Pi headless (i.e., operating without a monitor, keyboard, and mouse) you will not be able to connect to it.

To configure the Rasberry Pi to get a specific IP address each time it boots, edit /etc/network/interfaces as root:

# Comment out the following line:
# iface eth0 inet dhcp

# And add the following lines instead:
iface eth0 inet static
address 169.254.71.1
netmask 255.255.0.0

The next time you reboot and connect the ethernet cable to the Rasberry Pi, it will have the assigned IP address and you will be able to SSH directly to it.

Note: Remember to revert these changes if you ever want to connect to a router and get an address automatically assigned via DHCP.

3 Install RTI Connext DDS on your Linux Host

The next thing you need is to do is to set up a Linux computer with the RTI Connext DDS Host development bundles. There are two ways in which you can do this:

  1. Downloading a bundle/installer from the RTI Support Portal.
  2. Downloading the RTI Open Community Source, free Evaluation, or University bundles.

3.1 Option 1: Install RTI Connext DDS from the RTI Support portal

If you have purchased a support contract, and you have an account on the RTI Support Portal you can download the Linux Host bundles from it.

You can use any of the options bellow, as RTI Connext Professional includes RTI Connext Messaging, which itself includes RTI Connext DDS.

3.2 Option 2: Download the RTI Connext free evaluation, the Open Community Source, or the University & IR&D bundles

If you do not want to use the RTI Live CD and you cannot access the RTI support portal, you can download RTI Connext from here. This link gives you access to the free RTI DDS Open Community Source, the free University and IR&D bundles, and also the full Connext DDS Product and Tools under an evaluation license.

4 Install RTI Connext DDS 5.2.3 libraries for Raspberry Pi on your Linux host

For this step we assume that you have completed the previous step and you have installed RTI Connext DDS under some directory on your Linux host. In the following we assume your installation directory is /home/rticonnext/rti_connext_dds-5.2.3.

The first step is to download and install the RTI Connext DDS 5.2.3 target libraries for Raspberry Pi. These libraries are distributed as an rtipkg file that needs to be installed using the rtipkginstall utility distributed along with RTI Connext DDS. You have the following options to download the Connext DDS libraries for Raspberry Pi:

Once you have download the appropriate rtipkg, you can install it as follows:

cd /home/rticonnext/rti_connext_dds-5.2.3
./bin/rtipkginstall ~/Downloads/rti_connext_dds-5.2.3-core-target-armv6vfphLinux3.xgcc4.7.2.rtipkg

You will see all the library files installed under the rti_connext_dds-5.2.3/lib directory:

ls ./lib/armv6vfphLinux3.xgcc4.7.2
libnddscd.so     libnddscorezd.a  libnddscppzd.a
libnddscored.so  libnddscppd.so   libnddsc.so
libnddscore.so   libnddscpp.so    libnddscz.a
libnddscorez.a   libnddscppz.a    libnddsczd.a

Note that in addition to the libraries, the utility programs rtiddsping, rtiddsspy, and rtiddsprototyper are all available to run on the Raspberry Pi.

Now, you can start building DDS applications for the Raspberry Pi.

Note: If you compile your application statically against the RTI Connext DDS libraries, you will not need to install these libraries on your Raspberry Pi. However, if you link RTI Connext DDS libraries dynamically, you will need follow the instructions above to also install RTI Connext onto the Raspberry Pi itself. If you do this, remember also to set the LD_LIBRARY_PATH environment variable on the Raspberry Pi to include the directory rti_connext_dds-5.2.3/lib/armv6vfphLinux3.xgcc4.7.2. For example, if you copied the RTI Connext DDS installation into your Raspberry under /home/pi/rti_connext_dds-5.2.3 you will need to set LD_LIBRARY_PATHas follows:
export LD_LIBRARY_PATH=/home/pi/rti_connext_dds-5.2.3/lib/armv6vfphLinux3.xgcc4.7.2:$LD_LIBRARY_PATH

5 Set up linux Cross-compiling Environment for Raspberry Pi

The Raspberry Pi has limited resources compared to a regular desktop PC. Development and compilation on the Raspberry Pi tends to be quite slow. For this reason, we normally cross-compile most applications. That is, we compile the application in a different machine (e.g., a regular x86 Linux desktop) using a cross-compiler able to create binaries for the ARM 6 processor used by the Raspberry Pi.

There are two ways to do this:

  1. Use an existing toolchain for cross-compilation to the Raspberry Pi.
  2. Create your own toolchain for cross-compilation to the Raspberry Pi.

5.1 Option 1 [Recommended]: Use an existing toolchain for cross-compilation

You can find many toolchains including cross-compilers capable of creating code that can be run on the Raspberry Pi. In this section, we show you how to use toolchains built by RTI for 32- and 64-bit Linux environments. If you want to build your own toolchain, see instructions on Section 5.2. If you want to build applications on Windows, take a look at this tutorial.

Download the Raspberry Pi toolchain for your platform into a suitable directory (e.g., under /home/rticonnext/toolchains).

mkdir -p /home/rticonnext/toolchains
cd /home/rticonnext/toolchains

On 32-bit Linux:

wget https://s3.amazonaws.com/RTI/Community/ports/toolchains/raspbian-toolchain-gcc-4.7.2-linux32.tar.gz
tar xvzf raspbian-toolchain-gcc-4.7.2-linux32.tar.gz

On 64-bit Linux:

wget https://s3.amazonaws.com/RTI/Community/ports/toolchains/raspbian-toolchain-gcc-4.7.2-linux64.tar.gz
tar xvzf raspbian-toolchain-gcc-4.7.2-linux64.tar.gz

Now that you have the toolchain, add its bin directory to the path. Assuming you are using BASH in a 32-bit environment, run:

export PATH=/home/rticonnext/toolchains/raspbian-toolchain-gcc-4.7.2-linux32/bin:$PATH

If you want these changes to be permanent on your system, assuming again you are using BASH, add the line above to ~/.bashrc.

5.2 Option 2: Build your own toolchain for cross-compilation to Raspberry Pi

Building a custom toolchain gives you great flexibility, as it allows you to tune the compiler for a specific target. In this tutorial we show you how to use Crosstool-ng—a toolchain generator for more than 40 platforms—to generate a toolchain to compile for your Raspberry Pi.

5.2.1 Install Crosstool-ng

To configure and compile Crosstool-ng you need to install some dependencies in your system. Assuming you are using Ubuntu (in other distributions package names will be quite similar) run:

sudo apt-get install bison flex texinfo gperf gawk libtool automake libncurses5-dev subversion

Now download, extract, compile, and install crosstool-ng. Assuming you want to install Crosstool-ng under /home/rticonnext/build_tools/crosstool-ng-1.17 run:

wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.17.0.tar.bz2
tar xvjf crosstool-ng-1.17.0.tar.bz2
cd crosstool-ng-1.17.0
mkdir -p /home/rticonnext/build_tools/crosstool-ng-1.17
./configure --prefix=/home/rticonnext/build_tools/crosstool-ng-1.17
make
make install

5.2.2 Configure and build the toolchain

Once you have compiled Crostool-ng, you can configure and build a toolchain for the Raspberry Pi:

/home/rticonnext/build_tools/crosstool-ng-1.17/bin/ct-ng menuconfig
Note: This will create a .config file under the working directory with your configuration (and a .build directory with all the binaries that will be copied later to the directory you want to install the toolchain on). We recommend you to run these commands from a place you can remove the files from once you are done building your toolchain.

In the configuration menu, edit the following options:

  • Paths and misc options
    • Try features marked as EXPERIMENTAL
    • In prefix directory indicate the directory where you want your toolchain. In this case: ${HOME}/toolchains/raspbian-toolchain-gcc-4.7.2-linux32
  • Target options
    • Target architecture: arm
    • Endianness: Little endian
    • Bitness: 32-bit
    • Floating point: hardware (FPU)
  • Toolchain options
    • Build static toolchain (Experimental)
    • Toolchain bug url: http://community.rti.com
    • Tuple's vendor string: raspbian
    • Tuple's alias: arm-linux-gnueabihf
  • Operating system
    • Target OS: Linux
    • You can also select the kernel version you run in your target. In this case, use 2.6.32.60.
  • C compiler
    • C compiler: gcc
    • gcc version: 4.7.2
    • In additional supported languages add C++

Once you are done with your configuration, run:

/home/rticonnext/build_tools/crosstool-ng-1.17/bin/ct-ng build

This toolchain building process takes quite long. Once the toolchain is ready, you should find it under /home/rticonnext/toolchains/raspbian-toolchain-gcc-4.7.2-linux32 (or the directory you selected when you run ct-ng menuconfig).

Now that you have the toolchain, add its bin directory to the path. Assuming you are using BASH in a 32-bit environment, run:

export PATH=/home/rticonnext/toolchains/raspbian-toolchain-gcc-4.7.2-linux32/bin:$PATH

6 Compile and Run a Hello World Example

To validate your installation you can build a "hello world" application in C++ and Java using rtiddsgen in your own machine. You will generate and and edit the source files in your machine, cross-compile the code, and copy the executables to your Raspberry Pi.

6.1 C++ Example

First, create a file called hello.idl with the following content:

struct hello_message {
   string name; //@key
   long count;
};

Use rtiddsgen to generate a C++ example for the Raspberry Pi platform:

./bin/rtiddsgen -example armv6vfphLinux3.xgcc4.7.2 -language C++ hello.idl
Note: Remember to export the NDDSHOME environment variable and include the toolchain bin/ directory in the PATH and as we explained in Sections 4 and 5.1.

The rtiddsgen utility generates several files, including a makefile and two source files with the publisher and subscriber applications. Now, edit hello_publisher.cxx and add some data to be sent. To do this, look for the comment "/* Modify the data to be sent here */" in the C++ source file and add the code highlighted here:

       printf("Writing hello_message, count %d\n", count);

       /* Modify the data to be sent here */
       strcpy(instance->name, "Fernando");
       instance->count = count;

       retcode = hello_message_writer->write(*instance, instance_handle);
       if (retcode != DDS_RETCODE_OK) {
           printf("write error %d\n", retcode);
       }

       NDDSUtility::sleep(send_period);

To build the examples, use the makefile generated by rtiddsgen.

make -f makefile_hello_armv6vfphLinux3.xgcc4.7.2

Finally, copy the executables and the XML file with the default QoS settings for the example to the Raspberry Pi (e.g., to /home/pi/examples), and run the publisher and subscriber applications.

scp objs/armv6vfphLinux3.xgcc4.7.2/hello_publisher \
pi@<raspberrypi_ip>:/home/pi/example/
scp objs/armv6vfphLinux3.xgcc4.7.2/hello_subscriber \
pi@<raspberrypi_ip>:/home/pi/example/
scp USER_QOS_PROFILES.xml pi@<raspberrypi_ip>:/home/pi/example/
ssh pi@
cd /home/pi/example
./hello_publisher
Writing hello_message, count 0
Writing hello_message, count 1
Writing hello_message, count 2
Writing hello_message, count 3
./hello_subscriber 
hello_message subscriber sleeping for 4 sec...

  name: "Fernando"
  count: 1
hello_message subscriber sleeping for 4 sec...

  name: "Fernando"
  count: 2
hello_message subscriber sleeping for 4 sec...

  name: "Fernando"
  count: 3

6.2 Java Example

In this example we will show you how to generate code for Java and how to run it on your Raspberry Pi. We assume that you already have JDK installed on your device.

6.2.1 Create RTI Connext Java Example

Just like in the C++ example, create a file called hello.idl with the following content in your computer:

struct hello_message {
   string name; //@key
   long count;
};

Use rtiddsgen to generate a Java example for the Raspberry Pi platform (armv6vfphLinux3.xgcc4.7.2 in this case). Remember to set NDDSHOME to the right path before running the rtiddsgen.

./bin/rtiddsgen -example armv6vfphLinux3.xgcc4.7.2 -language java hello.idl

Edit hello_messagePublisher.java and add some data to be sent. To do this, look for the comment "/* Modify the data to be sent here */" in the Java source file and add the code highlighted here:

                System.out.println("Writing hello_message, count " + count);

                /* Modify the instance to be written here */
                instance.name = "Fernando";
                instance.count = count;

                /* Write data */
                writer.write(instance, instance_handle);
                try {
                    Thread.sleep(sendPeriodMillis);
                } catch (InterruptedException ix) {
                    System.err.println("INTERRUPTED");
                    break;
                }

Although you can generate the Java .class files in your Raspberry Pi, "cross-compiling" the .class files from your computer will be much faster. 

make -f makefile_hello_armv6vfphLinux3.xgcc4.7.2

Now, copy the example to the Raspberry Pi (e.g., to /home/pi/examples).

scp -r /path/to/example_dir pi@<raspberrypi_ip>:/home/pi/example

6.2.3 Run RTI Connext Java Example

Finally, using the makefile we ship with the example, run the publisher and subscriber applications. Remember to set NDDSHOME to the right path before running the applications.

ssh pi@<raspberrypi_ip>
cd /home/pi/example
 
make -f makefile_hello_armv6vfphLinux3.xgcc4.7.2 hello_messagePublisher
javac -classpath .:/home/pi/rti_connext_dds-5.2.3/lib/java/nddsjava.jar hello_messagePublisher.java
java -classpath ".:/home/pi/rti_connext_dds-5.2.3/lib/java/nddsjava.jar" hello_messagePublisher
Writing hello_message, count 0
Writing hello_message, count 1
Writing hello_message, count 2
Writing hello_message, count 3
Writing hello_message, count 4

make -f makefile_hello_armv6vfphLinux3.xgcc4.7.2 hello_messageSubscriber
java -classpath ".:/home/pi/rti_connext_dds-5.2.3/lib/java/nddsjava.jar" hello_messageSubscriber
hello_message subscriber sleeping for 4 sec...
hello_message subscriber sleeping for 4 sec...
Received:
 name: Fernando
count: 0

hello_message subscriber sleeping for 4 sec...
Received:
    name: Fernando
    count: 1

hello_message subscriber sleeping for 4 sec...
Received:
    name: Fernando
    count: 2

hello_message subscriber sleeping for 4 sec...
Received:
    name: Fernando
    count: 3

Comments

In the absense of a full wired ethernet environment, If you have a MacOS X box you are using for your cross development host, and you would like DHCP, you can enable Internet Sharing (System Preferences -> Sharing -> Enable Internet Sharing).

Connecting the Pi and the host machine to the same hub (or even directly, if you have a cross-over cable or the Mac is self-switching) will enable the Pi to get a DHCP-served IP address from the MacOS box. Drawback: the host machine will not go to sleep if Internet Sharing is enabled.

Field Application Engineer
Mid-Atlantic/Southeast Regions
RTI

We have added Java support (JDK 8 Build b98) to our experimental port for Raspberry Pi. The HOWTO document includes specific instructions on how to run DDS Java applications on the Raspberry Pi.

We have also change the name of the target architecture to armv6vfphLinux3.xgcc4.7.2.

Excellent tutorial!

The download page linked in section 3.3 has options for the 30 day evaluation, internal IR&D and university license types, but does not mention any open community source license or link to it. Where can I find the open community source material?

Hi Johan,

You can request the open community source license here:

http://www.rti.com/downloads/rti-dds.html

Gerardo

Hi Fernando,

Would it be possible to make an armv7l port? I am running Ubuntu 12.04 with gcc 4.6.3 on an ARM Cortex A8 board (armhf, armv7l). The Rasberry Pi port does not work for me, as my programs making use of the Rasberry Pi port segfault due to the architecture difference.

- Lionel

Hi Lionel,

We have custom support for Mistral Linux on armv7l. However, since we cross compiled our libraries using -mfpu=neon -msoft-float (see platform notes), I think you will probably encounter some problem.

Can you share with us the toolchain and compilation flags you use to cross compile for your ARM Cortex A8 board?

Thanks,
Fernando.

Hi Fernando,

I use this toolchain that is available on the official Ubuntu repositories: g++-arm-linux-gnueabihf

The compilation flags are: -march=armv7-a -mfloat-abi=hard -mfpu=neon

I'm looking forward to the armv7 port!

- Lionel

Hi, 

I have successfuly run the Raspberry Pi port (-march=armv6 -mfpu=vfp -mfloat-abi=hard) on a Beable Bone, which comes with an ARM Cortext-A8. I spoke with Lionel this week, and he has also been able to run appplications on his ARM Cortex-A8 board using the Raspberry Pi libraries.

Fernando.

Hi,

is it possible to update this HOWTO document to include specific instructions on a Windows host, instead of a Linux host (no make command on Windows) ?

Thanks

Regards,
Aillet

Hi Aillet,

I use VirtualBox and a CentOS 6.4 guest to do cross compiles.  I just feel more comfortable in a "real" *nix environment.  That said:

Sections 1 and 2 of the original post are RPi specific, or there are links to external sites for how to use Windows to do something (burn the RPi OS to an SD card, for example)

Section 3 has you install RTI Connext DDS on your host machine.  You need to do this because the header files in the host installation are needed by the cross compiler when doing a build for the RPi.  In this case, use the RTI Connext DDS Win32 or Win64 .exe installer (recommend you install in c:\rti and not in 'c:\program files', btw).

Section 4 is RPi specific and needed.

Section 5 is for generating a cross compiler.  Getting Windows to do a cross-compile for anything is tricky, and you need to install a "unix-like" environment first.  Cygwin for example.  There are several web pages that describe cross-compiling on Win for Pi.  That will take you up through the end of Section 5 of the original thread post. 

Section 6 is the c++ example, and how that is done depends on how you set up the cross compiler (cygwin, or VisualGDB or ???)...

Cross-compiling on Windows for RPi, however, isn't our skill area (We do DDS).  We might be able to supply you with pointers, but actually getting it to work reliably may require your own native intelligence and knowledge about what you set up on your machine.  If you get mostly there, you can supply us with the compile-time errors and we can make suggestions, or (better!) you can show us any runtime DDS problems/errors and we'll certainl assist you there.

 

Hi,

If I use Java language for my DDS applications running on the RPi, is it necessary to have a raspbian toolchain on a Linux or Windows host (I understand for C/C++ language where binaries are not the same)?
In other words, with the Java slogan "Write once, run anywhere", what is the interest of using a cross-compiler for the RPi applications ?
In this case, is it not enough to compile the Java source, to package classes in a jar, copy this jar and its far dependencies to the RPi (with pscp.exe) and run it with the command "java -classpath ... Main" on the Rpi ?

Or am I missing something

Thanks.

Regards,
Aillet

Theoretically. 

I've been using c and/or the prototyper, so haven't needed to check the Java libraries.  The only thing I can think of that might come in the way is, is there a suitable jvm from the rpi, and your os of choice? (keeping in mind hw/sw floating point, etc)

regards,

rip

Hello

I have problems with the installation of option 3.1 
On the download page I can download only the version 5.1 instead of version 5.0
The libraries for the raspberry have version 5.0. 
Are these versions compatible?

Greetings

Hello HP,

You can still download the 5.0.0 Live CD from this URL. It is impotant that you use of 5.0.0 header files if you are going to link your application against 5.0.0 libraries. Remember that by downloading the RTI Live CD you acknowledge that you have read and accepted the terms of the RTI Software License Agreement. 

Also, note that 5.1.0 includes official support for Raspbian Weezy ARMv6 Hard-Float ABI (i.e., Raspberry Pi). You can talke a look at the What's New document and the Release Notes for more information. You can download the target from the RTI Support Portal if you have an account. Unfortunately, the 5.1.0 Live CD only includes libraries for Ubuntu 12.04 (Intel 32-bit processor).

Thanks,
Fernando.

Please advise. I'm getting this error. It seems I don't have the right dds libraries for the Rpi. I'm downloading RTI live CD 5.0.0. 

Thanks,

 

#

# A fatal error has been detected by the Java Runtime Environment:

#

#  SIGILL (0x4) at pc=0xa8003d48, pid=4183, tid=3058177136

#

# JRE version: Java(TM) SE Runtime Environment (7.0_60-b19) (build 1.7.0_60-

b19)

# Java VM: Java HotSpot(TM) Client VM (24.60-b09 mixed mode linux-arm )

# Problematic frame:

# C  [libnddscore.so+0x72d48]  call_gmon_start+0x7

#

# Failed to write core dump. Core dumps have been disabled. To enable core d

umping, try "ulimit -c unlimited" before starting Java again

#

# If you would like to submit a bug report, please visit:

#   http://bugreport.sun.com/bugreport/crash.jsp

# The crash happened outside the Java Virtual Machine in native code.

# See problematic frame for where to report the bug.

#

 

---------------  T H R E A D  ---------------

 

Current thread (0x00b1e540):  JavaThread "main" [_thread_in_native, id=4190,

 stack(0xb6432000,0xb6482000)]

 

siginfo:si_signo=SIGILL: si_errno=0, si_code=1 (ILL_ILLOPC), si_addr=0xa8003

d48

 

Registers:

  r0  = 0x00000004

  r1  = 0xbee961e4

  r2  = 0x000009d0

  r3  = 0x00000000

  r4  = 0x00000004

  r5  = 0xbee961e4

  r6  = 0xa8567de0

  r7  = 0x00b78de8

  r8  = 0xbee961e4

  r9  = 0xb6fb2048

  r10 = 0x00000004

  fp  = 0xb647f614

  r12 = 0xb647f7e8

  sp  = 0xb647f558

  lr  = 0xa8003cff

  pc  = 0xa8003d48

  cpsr = 0xa0000030

 

Top of Stack: (sp=0xb647f558)

0xb647f558:   a8003cf9 b6f9b210 00b78de8 00000001

0xb647f568:   00000000 a8567de0 00b78de8 bee961e4

0xb647f578:   00000004 b6f9b36c a8567de0 b6fb2560

0xb647f588:   a8567f3c b6fb2048 00000007 00000007

0xb647f598:   0000000b b6f9f3bc 00000001 b6fb2094

0xb647f5a8:   a8567de0 a8567de0 80000000 00000000

0xb647f5b8:   b647f8ec 00b1e540 b69cfeec 00000054

0xb647f5c8:   b647f678 00b201d4 00000000 b647f5b0 

 

Instructions: (pc=0xa8003d48)

0xa8003d28:   e28fc604 e28ccaa7 e5bcf2e0 e28fc604

0xa8003d38:   e28ccaa7 e5bcf2d8 4a044b03 589b447b

0xa8003d48:   f7ffb10b 4770bfe5 004a72b8 000009d0

0xa8003d58:   b5084a09 4b09447a 447b7812 4a08b95a 

 

Register to memory mapping:

 

  r0  = 0x00000004

0x00000004 is an unknown value

 

  r1  = 0xbee961e4

0xbee961e4 is an unknown value

 

  r2  = 0x000009d0

0x000009d0 is an unknown value

 

  r3  = 0x00000000

0x00000000 is an unknown value

 

  r4  = 0x00000004

0x00000004 is an unknown value

 

  r5  = 0xbee961e4

0xbee961e4 is an unknown value

 

  r6  = 0xa8567de0

0xa8567de0 is an unknown value

 

  r7  = 0x00b78de8

0x00b78de8 is an unknown value

 

  r8  = 0xbee961e4

0xbee961e4 is an unknown value

 

  r9  = 0xb6fb2048

0xb6fb2048: _rtld_global+0 in /lib/ld-linux-armhf.so.3 at 0xb6f8c000

 

  r10 = 0x00000004

0x00000004 is an unknown value

 

  fp  = 0xb647f614

0xb647f614 is pointing into the stack for thread: 0x00b1e540

 

  r12 = 0xb647f7e8

0xb647f7e8 is pointing into the stack for thread: 0x00b1e540

 

  sp  = 0xb647f558

0xb647f558 is pointing into the stack for thread: 0x00b1e540

 

  lr  = 0xa8003cff

0xa8003cff: <offset 0x72cff> in /home/ubuntu/demo-apps-0.2.2/bin/.nddshome/l

ib/armv6vfphLinux3.xgcc4.7.2jdk/libnddscore.so at 0xa7f91000

 

  pc  = 0xa8003d48

0xa8003d48: <offset 0x72d48> in /home/ubuntu/demo-apps-0.2.2/bin/.nddshome/l

ib/armv6vfphLinux3.xgcc4.7.2jdk/libnddscore.so at 0xa7f91000

 

 

 

Stack: [0xb6432000,0xb6482000],  sp=0xb647f558,  free space=309k

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native co

de)

C  [libnddscore.so+0x72d48]  call_gmon_start+0x7

 

Hello,

I am just starting to use your software with a university license and I came across two problems. Hope that you can help me.

I tried to install version 5.1.0 Live CD on VirtualBox but I am keep getting an error at the end of the installation, login in the OS and the if I restar it, it never turns back on. The 5.1.0 experimental works (but I dont know if it has everything that the 5.1.0 has) and also the 5.0.0 is working as well. I am planning on establishing communication between some Raspberry Pies and I would assume that is better to have the 5.1.0 running. Please let me know if someone else has the same problem, because I tried installing a new download on another pc with hyper-v (windows 8) and also running first the live linux and from inside it running the setup. Nothing worked :(

My other issue is with the 2012-12-16-wheezy-raspbian image. I have a few B+ models of Raspberry and the only image that is running is the 2014-09-09-wheezy-raspbian (or at least not the 2012-12-16 or 2014-07-01 that I tried to begin with). Have you tried running DDS applications on one of the latest versions? Are there any problems?

Thank you in advance,

Sios

Hello Sios,

Yesterday I was able to reproduce the installation error you reported. I have uploaded a new copy of the 5.1.0 Live CD that you should now be able to install--I have tested it on VMWare Fusion and it worked just fine. You will just need to click on the Install option of the Grub menu.

Regarding your other issue, I have not tried to run applications on the latest versions of Raspbian. But I don't expect major issues--there is nothing I can think of that should not be working. Let me know if you find something and I will upload the image on my Raspberry Pi to test it out.

Thanks,
Fernando.

Hey

Can I get DDS to run on Raspberry Pi 2 Model B too?

Thank you in advance,

Christian

Hi Christian,

I believe you will be able to run DDS on a Raspberry Pi 2 Model B using the current libraries -- ARMv7 should be backwards compatible with ARMv6. If you are unable to do so, please let us know so we can test what needs to be change or we can provide a rebuild of the libraries enabling new flags.

Thanks,
Fernando.

Hello again, 

thank you for your help last time. I was trying for some time to use the RTI monitor software of yours in order to monitor the publishers and subscribers that I have on some Raspberry Pis.

The RTI Monitor is always as the following image.

RTI monitor without monitoring data

I tried to enable QoS following this article https://community.rti.com/kb/what-does-it-mean-when-rti-monitor-shows-only-domainparticipants-and-topics-category-no-actual (and found the same in your manual etc), but I am getting a few errors.

Is it a problem that you have come across on the Raspberry Pis or should I sent more details on the errors that I am getting?

I hope that this makes sense,

Sios

Hi, I am just posting again in case that someone has an answer now, because I haven't get a response for some time now!

Thank you again,

Best,

Sios

Hi Sios,

As stated in the solution you found, you need to enable "monitoring" in your DDS applications to be able to access monitoring data via RTI Monitor. Can you post the errors you are getting? Do you have access to the librtimonitoring.so for armv6?

Thanks,
Fernando.

Hi Fernando,

Thank you for your reply. I 've implemented the xml code from the solution before.

<participant_qos>


<property>
<value>
<element>
<name>rti.monitor.library</name>
<value>rtimonitoring</value>
</element>
<element>
<name>rti.monitor.create_function</name>
<value>RTIDefaultMonitor_create</value>
</element>
</value>
</property>

<!--
The participant name, if it is set, will be displayed in the
RTI tools, making it easier for you to tell one
application from another when you're debugging.
-->
<participant_name>
<name>testParticipant</name>
<role_name>testParticipantRole</role_name>
</participant_name>

</participant_qos>
</qos_profile>

</qos_library>
</dds>

The error that I am getting when I am trying to run the example on the Rpi says that is about missing the librtimonitoringd.so library but I have both the librtimonitoringd.so and the librtimonitoring.so in the folders of my Rpi.

 Rpi motinor errors

Please let me know if I can provide you with any more relevant info in order to short this out.

 

Thank you again,

 

Sios

Hi Sios,

It looks like your application cannot find librtimonitoringd.so in the library path. If you have access to this library, please add the directory to your library path. For instance, if librtimonitoringd.so is located in /home/sios/rti/ndds.5.1.0/lib/armv6vphLinux3.xgcc4.7.2, you can do the following:

export LD_LIBRARY_PATH=/home/sios/rti/ndds.5.1.0/lib/armv6vphLinux3.xgcc4.7.2:$LD_LIBRARY_PATH

If you only have access to libmonitoring.so (i.e., the release version) just add the path to this library in the XML configuration file as follows:

<element>
    <name>rti.monitor.librar</name>
    <value>/home/sios/rti/ndds.5.1.0/lib/armv6vphLinux3.xgcc4.7.2/librtimonitoring.so</value>
</element>

If you do not have access to the monitoring library at all, please let me know and we will se what we can do.

Thanks,
Fernando.

Thank you for your reply once again Fernando.

after getting a proper look it seems that I dont have the librarys for the arm processor. Only for i86.

And I am assuming that here <name>rti.monitor.librar</name> should be <name>rti.monitor.library</name>

What could I do?

Best,

Sios

Hi, I am getting this error after installing the Raspberry PI libraries on my PI. When I tried to run a jar file (which works on my PC), it throws the following error.

NDDSHOME=/home/pi/RTI/ndds.5.0.0
DYLD_LIBRARY_PATH=/home/pi/RTI/ndds.5.0.0/lib/armv6vfphLinux3.xgcc4.7.2:/home/pi/RTI/ndds.5.0.0/lib/armv6vfphLinux3.xgcc4.7.2jdk:/home/pi/RTI/ndds.5.0.0/lib/armv6vfphLinux3.xgcc4.7.2jdk
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.rti.ndds.config.Version.get_core_library_build_number_string()Ljava/lang/String;
        at com.rti.ndds.config.Version.get_core_library_build_number_string(Native Method)
        at com.rti.ndds.config.Version.<init>(Unknown Source)
        at com.rti.ndds.config.Version.<clinit>(Unknown Source)
        at simpledds.MonitorDicoveredInformation.start(MonitorDicoveredInformation.java:37)
        at simpledds.MonitorDicoveredInformation.main(MonitorDicoveredInformation.java:312)

 

Thanks, Andrei