Skip to the main content.

Did you know?

 

RTI is the world’s largest DDS supplier and Connext is the most trusted software framework for critical systems.

Success-Plan-Services-DSSuccess-Plan Services

Our Professional Services and Customer Success teams bring extensive experience to train, problem-solve, mentor, and accelerate customer success.

Learn more

Developers

From downloads to Hello World, we've got you covered. Find all of the tutorials, documentation, peer conversations and inspiration you need to get started using Connext today.

Try the Connectivity Selection Tool ⇢

Resources

RTI provides a broad range of technical and high-level resources designed to assist in understanding industry applications, the RTI Connext product line and its underlying data-centric technology.

Company

RTI is the infrastructure software company for smart-world systems. The company’s RTI Connext product is the world's leading software framework for intelligent distributed systems.

Contact Us

News & Events
Cooperation

3 min read

How to Build and Run RTI Connext DDS Micro on a Microcontroller

How to Build and Run RTI Connext DDS Micro on a Microcontroller

As you might know, we ship a buildable source for RTI Connext DDS Micro so you can build it for your own architecture. In the past few months, we have noticed that customers are interested in building our product for microcontrollers without a Memory Management Unit (MMU), and they’re using a uClibc-based OS. The purpose of this post is to support this expressed need and illustrate how to port RTI Connext DDS Micro to uCLinux with relatively few changes. The development board that we will use in this practical example is STM32F769I-DISCO. You should be able to extrapolate it to any other board by knowing your toolchain. You can even extrapolate it to any other OS that uses uClibc!

Let’s get started.

Enabling Multithreading Support

In order to work with RTI Connext DDS Micro, you will need support for pthreads library. Make sure to enable it in your uCLinux OS. The uClibc included in codesourcery toolchain does not have posix threads support. For our board, Emcraft implemented it and shipped it with their board support package. You will need access to their cross development environment. Unpack it in any folder you want (we will call it <cross-dev-dir> here), and follow the instructions in the EMCraft web link provided.

After following the steps, you should find the libs (including pthread) in the following folder:

<cross-dev-dir>/A2F/root/usr/lib

And the header files in this one:

<cross-dev-dir>/A2F/root/usr/include

Finally, you should have the toolchain in:

<cross-dev-dir>/tools/arm-2010q1

And the binaries (gcc, g++, gdb…):

<cross-dev-dir>/tools/arm-2010q1/bin

You can run the ACTIVATE.sh script provided by Emcraft or just add <cross-dev-env-dir>/tools/arm-2010q1/bin to your path. After that, you can build your threaded application with the following line:

arm-uclinuxeabi-gcc pthreadapp.c -o pthreadapp \
-I <cross-dev-dir>/A2F/root/usr/include \
-mthumb -march=armv7 -mfix-cortex-m3-ldrd \
-L <cross-dev-dir>/A2F/root/usr/lib -pthread

Compile Static Micro Libraries

  1. Get the cross development and toolchain, and install them as explained in *Enabling multithreading support*.
  2. Make sure to have <cross-dev-dir>/tools/arm-2010q1/bin in your PATH.
  3. Get the buildable sources for Micro. Unpack them in a different dir. We will work in the <buildable_source_folder>/source/unix/ directory, so all paths will part from there.
  4. Modify resource/cmake/cmake_module.txtfile with this patch file. This allows us to not compile dynamic libraries since uCLinux does not support dynamic linking. To patch the file, copy the cmake_modules.txt.patch to resource/cmake/ and run the following command:
    patch < cmake_module.txt.patch
  5. Configure the target architecture. To do so you will need two files:
    1. Architecture file: Copy it to resource/cmake/architectures directory
    2. compiler file: Then copy it to resource/cmake/architectures/compiler directory
  6. Implement the necessary code changes:
    1. In src/osapi/posix/posixHeap.c (OSAPI_Heap_allocate_buffer() func): Replace malloc_usable_size() with the RTI_UINT32 size variable.
    2. In src/osapi/posix/posisSystem.c (OSAPI_SystemPosix_timer_thread() func):
      Replace clock_nanosleep() calls with nanosleep() function. Leave only the last two arguments in the call to nanosleep.
    3. In src/osapi/posix/posix/posixThread.c (OSAPI_Thread_sleep() func):
      The same as in b
      Note: you can also avoid errors in 6.b and 6.c by adding the line ADD_DEFINITIONS(-DUSE_TIMER_THREAD_SLEEP) to the uCLinux.tc file downloaded in step 5.a
  7. (From <buildable_source_folder>/source/unix) Run the rtime_make script:
    ./resource/scripts/rtime-make \
    -DRTI_NO_SHARED_LIB:bool=true \
    --delete \
    --target uCLinux \
    --name armSTM32uCLinuxgcc4.4.1 \
    -G "Unix Makefiles" \
    --build \
    --config Release 

    Note that you can use --config Debug to build the corresponding libs.
  8. You should find the built libraries in <buildable_source_folder>/lib/armSTM32uCLinuxgcc4.4.1 (or the lib name you chose)

Compile and run a DDS publisher/subscriber application

Currently there isn’t any support for multicast in this board, so you will need to disable multicast transport. To do it, add the following to the qos settings before creating the participant:

DDS_StringSeq_set_maximum(&dp_qos.discovery.enabled_transprts,2);

DDS_StringSeq_set_length(&dp_qos.discovery.enabled_transports,2);

*DDS_StringSeq_get_reference(&dp_qos.discovery.enabled_transports,0) =
        DDS_String_dup("_udp://");

*DDS_StringSeq_get_reference(&dp_qos.discovery.enabled_transports,1) =
        DDS_String_dup("_udp://127.0.0.1");

Then you only have to edit the makefile for your application, to use the correct compiler, and the right flags, headers, and includes. You will have to use the cross development environment folder. Add the following to your makefile:

  1. Header files: add the folder <cross-dev-folder>/A2F/root/usr/include 
  2. Library files: add the folder: <cross-dev-folder>/A2F/root/usr/lib
  3. Compiler flags: -mthumb -march=armv7 -mfix-cortex-m3-ldrd
  4. Compiler: arm-uclinuxeabi-gcc

As a simple test, we will use the shipped HelloWorld_dpde example with a properly-modified Makefile. To avoid hardcoding paths, it’s assumed that you will put the cross development environment path into an environment variable called CDE_DIR. Also include the arm-uclinuxeabi-gcc in your PATH, and set RTIMEHOME and RTIMEARCH as usual. You can find the modified Makefile here.

That’s it! For more information and additional tutorials head on over to the RTI Community. If you’re up for some more fun, I suggest you visit RTI Labs and take one of our experimental projects for a test drive.