Chapter 8 VxWorks Platforms
8.1 Building Applications for VxWorks Platforms
The following notes apply to VxWorks 7-based platforms, including VxWorks 23.09.
- Compiling a Connext application for VxWorks depends on the development platform. For more information, such as specific compiler flags, see the VxWorks Programmer’s Guide.
- Cross-compiling for any VxWorks platform is similar to building for a Linux target. To build a VxWorks application, create a makefile that reflects the compiler and linker for your target with appropriate flags defined. There will be several target-specific compile flags you must set to build correctly. For more information, see the VxWorks Programmer’s Guide.
- Required Makefile Change
After you run rtiddsgen, either edit the generated makefile to specify which VxWorks Source Build (VSB) you want to use or set an environment variable called VSB_DIR that points to the VSB. In the generated makefile, find this line and change it to match your VSB directory:
VSB_DIR = # Specify your VSB directory here.
Note: RTI uses a VSB based on the itl_generic BSP provided by Wind River to build the Connext libraries for VxWorks 7.0 for x64 CPUs.
- To run VxWorks tasks with Thread Local Storage, the kernel must be configured in advance with an explicit size for the TLS variables through the kernel parameter, DKM_TLS_SIZE. To run Connext in a VxWorks task, DKM_TLS_SIZE must be 160 or higher to fit the TLS variables. For more information, see the tlsLib API reference in your VxWorks 7 documentation.
- To avoid symbol duplication in applications generated with rtiddsgen, in statically linked Downloadable Kernel Modules (DKMs):
When using rtiddsgen to generate a Connext application, publisher and subscriber are created. By default, the generated makefile will create a separate application for the publisher and the subscriber. This poses a problem when linking static kernel modules. In this case, you would have a static DKM containing the publisher application + Connext libraries, and another static DKM containing the subscriber application + Connext libraries. When those two modules are loaded into the kernel, all the Connext symbols will be duplicated and you will likely run into issues.
To overcome this limitation, an additional target is created in the makefile for the VxWorks kernel architectures called pubsub. This target will create a single DKM containing both the publisher and subscriber application, plus the Connext libraries. With this approach, you can link this single DKM and still have the publisher and subscriber applications available in the kernel without duplication of symbols.
8.1.1 Libraries for RTP Mode on VxWorks Systems
Dynamic libraries are not available for VxWorks systems with Real Time Processes (RTP mode) on PowerPC (PPC) CPUs. This is due to a platform limitation in VxWorks PPC platforms that puts an upper bound on the size of the Global Offset Table (GOT) for any single library, which limits how many symbols the library can export. Some Connext libraries (in particular, libnddsc) export a number of symbols that exceed this upper bound.
Dynamic libraries are available for VxWorks systems with RTP mode.
8.1.2 Required Libraries and Compiler Flags
First, see the basic instructions in Chapter 2 Building Applications—Notes for All Platforms.
Table 8.1 Building Instructions for VxWorks Architectures lists the libraries you will need to link into your application and the required compiler flags.
Depending on which Connext features you want to use, you may need additional libraries; see 8.1.3 Additional Libraries for Other Features.
Make sure you are consistent in your use of static, dynamic, debug and release versions of the libraries. Do not link both static and dynamic libraries. Similarly, do not mix release and debug libraries.
Release and Debug Terminology:
Both release and debug versions of the libraries are provided. For Connext, debug libraries are created with debug symbols to facilitate debugging with gdb, for example. Release libraries do not contain debug information.
The Connext debug libraries are intended solely for development and debugging purposes. These libraries are not optimized for performance or resource consumption and may include additional diagnostic information that can affect runtime behavior. They are not intended for use in production environments. Please ensure that only the release libraries are used in production deployments. Debug libraries can be identified by the suffix "d" in their names.
Additional Documentation:
See the RTI Connext Core Libraries Getting Started Guide Addendum for Embedded Systems.
Verified Compiler Flags:
Compiler flags outside those documented in Table 8.1 Building Instructions for VxWorks Architectures have not been verified by RTI and can cause undefined behavior.
|
API |
Library Format |
Required Kernel Components |
Required Compiler Flags |
|
|
C++ (Traditional and Modern APIs) |
Static Release |
libnddscorez.a libnddscppz.a librticonnextmsgcppz.a |
INCLUDE_TIMESTAMP INCLUDE_POSIX_CLOCKS For RTI architectures with SMP support also use: |
-DRTI_VXWORKS -DRTI_CLANG -DRTI_64BIT |
|
Static Debug |
libnddscorezd.a libnddscppzd.a librticonnextmsgcppzd.a |
|||
|
Dynamic Release |
libnddscore.so libnddscpp.so librticonnextmsgcpp.so |
|||
|
Dynamic Debug |
libnddscored.so libnddscd.so libnddscppd.so librticonnextmsgcppd.so |
|||
|
C |
Static Release |
libnddscorez.a |
INCLUDE_TIMESTAMP INCLUDE_POSIX_CLOCKS For RTI architectures with SMP support, also use: INCLUDE_TLS |
-DRTI_VXWORKS -DRTI_CLANG -DRTI_64BIT |
|
Static Debug |
libnddscorezd.a |
|||
|
Dynamic Release |
libnddscore.so |
|||
|
Dynamic Debug |
libnddscored.so |
8.1.3 Additional Libraries for Other Features
This section discusses libraries for features that are not supported for every platform. Please refer to
If you plan to use the additional RTI libraries described in this section, they must be linked before the required RTI libraries (see Table 8.1 Building Instructions for VxWorks Architectures) in your included libraries for linking.
Make sure you are consistent in your use of static, dynamic, debug and release versions of the libraries. For example, if your Connext application is linked with the static release version of the Connext libraries, you will need to also use the static release version of the library. Do not link both static and dynamic libraries. Similarly, do not mix release and debug libraries.
8.1.3.1 Libraries Required for Distributed Logger
Table 8.2 Additional Libraries for using RTI Distributed Logger lists the additional libraries you will need in order to use Distributed Logger.
|
Language |
Static3 |
Dynamic4 |
||
|
Release |
Debug |
Release |
Debug |
|
|
C |
librtidlcz.a |
librtidlczd.a |
librtidlc.so |
librtidcd.so |
|
C++ (Traditional API) |
librtidlcz.a
|
librtidlczd.a |
librtidlc.so
|
librtidlcd.so
|
8.1.3.2 Libraries Required for Monitoring
If you are statically linking your application with DDS libraries and you want to add monitoring to your application, you will also need to statically link the monitoring library. The library cannot be loaded dynamically strictly through the QoS profile because it also depends on DDS to publish its data. Therefore, it depends on DDS; the DDS functionality would cause duplicate symbols to be found, resulting in the termination of the process.
Notes:
- Automatic loading of the dynamic monitoring library through QoS is not supported.
- Memory and CPU usage is not available in monitoring data.
|
Library Format |
Monitoring Libraries5 |
|
Dynamic Release |
librtimonitoring.so6 |
|
Dynamic Debug |
librtimonitoringd.so7 |
|
Static Release |
librtimonitoringz.a |
|
Static Debug |
librtimonitoringzd.a |
|
Library Format |
Monitoring Libraries 2.08 |
|
Dynamic Release |
librtimonitoring2.so9 |
|
Dynamic Debug |
librtimonitoringd2.so10 |
|
Static Release |
librtimonitoringz2.a |
|
Static Debug |
librtimonitoringzd2.a |
8.1.3.3 Libraries Required for Real-Time WAN Transport APIs
If you choose to use Real-Time WAN Transport, you must download and install a separate package that contains the transport libraries.
Using Real-Time WAN Transport requires one of the libraries in Table 8.5 Additional Libraries for Using Real-Time WAN Transport APIs. Select the file appropriate for your chosen library format.
|
Library Format |
Real-Time WAN Transport Libraries11 |
|
Dynamic Release |
libnddsrwt.so |
|
Dynamic Debug |
libnddsrwtd.so |
|
Static Release |
libnddsrwtz.a |
|
Static Debug |
libnddsrwtzd.a |
8.1.3.4 Libraries Required for Zero Copy Transfer Over Shared Memory
To use the Zero Copy Transfer Over Shared Memory feature, link against the additional library in Table 8.6 Additional Libraries for Zero Copy Transfer Over Shared Memory.
|
Library Format |
Zero Copy Over Shared Memory Libraries12 |
|
Dynamic Release |
libnddsmetp.so |
|
Dynamic Debug |
libnddsmetpd.so |
|
Static Release |
libnddsmetpz.a |
|
Static Debug |
libnddsmetpzd.a |
8.2 Running User Applications
Table 8.7 Running Instructions for VxWorks Architectures provides details on the environment variables that must be set at runtime for a VxWorks architecture.
|
RTI Architecture |
Library Format |
Environment Variables |
|
VxWorks Kernel mode architectures |
DKM |
None required |
|
VxWorks RTP architectures |
Dynamic |
LD_LIBRARY_PATH= <path_to_connext_libs>;<path_to_libc>"13 |
|
Static |
None required |
8.3 Known Defects
Defect V7COR-8916 can cause unpredictable segmentation faults in VxWorks 23.09 RTP applications. There is a patch available from Wind River, which they will provide upon request through their Support Network. This patch is required in order to support the x64Vx23.09llvm16.0 rtp architecture.
8.4 Increasing the Stack Size
Connext applications may require more than the default stack size on VxWorks.
To prevent stack overrun, you can create/enable the DomainParticipant in a thread with a larger stack, or increase the default stack size of the shell task by recompiling the kernel. For more information, please see the Solutions on the RTI Community portal, accessible from https://community.rti.com/kb.
8.5 Enabling Floating Point Coprocessor in Kernel Tasks
Some applications may require you to spawn the kernel with floating-point coprocessor support. To do so, you must pass the VX_FP_TASK option to the "options" argument of taskSpawn (please refer to Wind River documentation for more information about taskSpawn arguments).
If you spawn the task from the c-shell, the VX_FP_TASK definition is not available and you must provide a numeric value: 0x1000000 for VxWorks 6.x and newer versions. If the target system runs a PowerPC e500v2 CPU, you need to pass VX_SPE_TASK instead, whose value is 0x4000000.
8.6 Downloadable Kernel Modules (DKM) for Kernel Mode on VxWorks Systems
In VxWorks kernel mode, dynamic libraries are not supported. Instead, Downloadable Kernel Modules (DKMs) are used. Once a DKM has been loaded into the kernel, all the symbols from that DKM will be accessible from the kernel.
In VxWorks kernel mode, before a C++ DKM can be downloaded to the VxWorks kernel, it must undergo an additional host processing step known as munching. This step is necessary for proper initialization of static objects and to ensure that the C++ run-time support calls the correct constructor/destructors in the correct order for all static objects. All the Connext DKMs (libnddscore.so, libnddsc.so, libnddscpp.so, etc) are shipped already munched.
When you create an application as a DKM for use in kernel mode, you have two options for linking:
- Perform a static linkage: This involves linking all the needed Connext libraries inside the DKM (such as libnddscorez.a). Note that if you plan to load several statically linked DKMs into the kernel, you will have issues related to duplicate symbols, because the symbols from Connext will be loaded once per DKM.
- Perform a partial linkage: This involves building your application without linking against the Connext libraries. Later, at load time, you will need to load into the kernel the required Connext libraries and your application DKM. This is recommended if you plan to have more than one DKM using Connext.
For both options, you will need to munch your application DKMs.
8.7 Requirement for Restarting Applications
When restarting a VxWorks application, you may need to change the ‘appId’ value. In general, this is only required if you still have other Connext applications running on other systems that were talking to the restarted application. If all the Connext applications are restarted, there should be no problem.
This section explains why this is necessary and how to change the appId.
All Connext applications must have a unique GUID (globally unique ID). This GUID is composed of a hostId and an appId. RTI implements unique appIds by using the process ID of the application. On VxWorks systems, an application’s process ID will often be the same across reboots. This may cause logged errors during the discovery process, or discovery may not complete successfully for the restarted application.
The workaround is to manually provide a unique appId each time the application starts. The appId is stored in the DomainParticipant’s WireProtocol QosPolicy. There are two general approaches to providing a unique appId. The first approach is to save the appId in NVRAM or the file system, and then increment the appId across reboots. The second approach is to base the appId on something that is likely to be different across reboots, such as a time-based register.
8.8 Transports
8.8.1 Shared-Memory Communication between Applications Running in Kernel Mode and RTP Requires Explicitly Set Participant ID
By default, applications using the auto-generated Participant ID (-1) cannot communicate between user space and kernel space on the same host via SHMEM. The root cause is that the participants use the same participant ID. Therefore the workaround for this issue is to explicitly provide a participant ID when creating the DomainParticipants. The participant ID is set in the DomainParticipant’s WireProtocol QoS policy.
8.8.2 How To Run Connext Libraries in Kernels Built without Shared Memory
Since Connext libraries support shared memory as a built-in transport, building a kernel without shared-memory support will cause loading or linking errors, depending on whether the Connext libraries are loaded after boot, or linked at kernel build time.
The most straightforward way to fix these errors is to include shared-memory support in the kernel (INCLUDE_SHARED_DATA in the kernel build parameters ).
However, in some versions of VxWorks, it is not possible to include shared-memory support without also including RTP support. If you are unwilling or unable to include shared-memory support in your configuration, you will need to do the following:
- Add the component INCLUDE_POSIX_SEM
- Define stubs that return failure for the missing symbols sdOpen and sdUnmap as described below:
- For sdOpen, we recommend providing an implementation that returns NULL, and sets errno to ENOSYS. For the function prototype, refer to the file sdLib.h in the VxWorks distribution.
- For sdUnmap, we recommend providing an implementation that returns ERROR and sets errno to ENOSYS. For the function prototype, refer to the file sdLibCommon.h in the VxWorks distribution.
In addition to providing the symbol stubs for sdOpen and sdUnmap, we also recommend disabling the SHMEM transport by using the transport_builtin mask in the QoS configuration.
8.9 Unsupported Features
These features are not supported on VxWorks platforms:
- Backtrace
- Controlling CPU Core Affinity
- Durable Writer History and Durable Reader State
- 'Find Package' CMake script
Please refer to
8.10 Monotonic Clock Support
The monotonic clock (described in Configuring the Clock per DomainParticipant, in the RTI Connext Core Libraries User's Manual) is supported on all VxWorks platforms.
8.11 Use of Real-Time Clock
Starting with 5.3.0, Connext uses the Real Time Clock to get the time from the System Clock on VxWorks 6.x and higher platforms. Previously tickGet() was used for the system clock.
8.12 Thread Configuration
8.12.1 Thread Settings, Thread-Priority Definitions, and Thread Kinds
See these tables:
- Table 8.8 Thread Setting for VxWorks Platforms
- Table 8.9 Thread-Priority Definitions for VxWorks Platforms
- Table 8.10 Thread Kinds for VxWorks Platforms
|
Applicable Thread |
DDS_ThreadSettings_t |
Platform-Specific Setting |
|
Asynchronous Publisher, |
mask |
OS default thread type |
|
priority |
100 |
|
|
stack_size |
40 * 1024 |
|
|
cpu_list |
CPU core affinity not supported |
|
|
cpu_rotation |
CPU core affinity not supported |
|
|
Database thread |
mask |
DDS_THREAD_SETTINGS_STDIO |
|
priority |
120 |
|
|
stack_size |
40 * 1024 |
|
|
cpu_list |
CPU core affinity not supported |
|
|
cpu_rotation |
CPU core affinity not supported |
|
|
Event thread |
mask |
DDS_THREAD_SETTINGS_STDIO | DDS_THREAD_SETTINGS_FLOATING_POINT |
|
priority |
110 |
|
|
stack_size |
4 * 40 * 1024 |
|
|
cpu_list |
CPU core affinity not supported |
|
|
cpu_rotation |
CPU core affinity not supported |
|
|
ReceiverPool threads |
mask |
DDS_THREAD_SETTINGS_STDIO | DDS_THREAD_SETTINGS_FLOATING_POINT |
|
priority |
71 |
|
|
stack_size |
4 * 40 * 1024 |
|
|
cpu_list |
CPU core affinity not supported |
|
|
cpu_rotation |
CPU core affinity not supported |
|
Thread-Priority Definition |
Operating-System Priority |
|
THREAD_PRIORITY_DEFAULT |
100 |
|
THREAD_PRIORITY_HIGH |
68 |
|
THREAD_PRIORITY_ABOVE_NORMAL |
71 |
|
THREAD_PRIORITY_NORMAL |
100 |
|
THREAD_PRIORITY_BELOW_NORMAL |
110 |
|
THREAD_PRIORITY_LOW |
120 |
|
Thread Kinds |
Operating-System Configuration14 |
|
DDS_THREAD_SETTINGS_FLOATING_POINT |
Uses VX_FP_TASK when calling taskSpawn() |
|
DDS_THREAD_SETTINGS_STDIO |
Uses VX_STDIO when calling taskSpawn() (Kernel mode only) |
|
DDS_THREAD_SETTINGS_REALTIME_PRIORITY |
Configures the schedule policy to SCHED_FIFO. |
|
DDS_THREAD_SETTINGS_PRIORITY_ENFORCE |
N/A |
8.12.2 Automatic Thread-Specific Storage Cleanup
VxWorks systems do not support automatic thread-specific storage cleanup. Use of the DomainParticipantFactory::unregister_thread API is therefore required to clean up thread-specific storage in user threads.
8.13 Socket Buffer Size Configuration
See Table 8.11 UDP send_socket_buffer_size and Table 8.12 UDP receive_socket_buffer_size. For more information on the send_socket_buffer_size and receive_socket_buffer_size properties, see Setting Builtin Transport Properties with the PropertyQosPolicy, in the RTI Connext Core Libraries User's Manual.
|
Property |
Behavior |
|---|---|
|
NDDS_TRANSPORT_UDPV4_SOCKET_BUFFER_SIZE_OS_DEFAULT |
Uses default send socket buffer size |
|
NDDS_TRANSPORT_UDPV4_SOCKET_BUFFER_SIZE_OS_MAX |
Not supported (NDDS_TRANSPORT_UDPV4_SEND_SOCKET_BUFFER_SIZE_DEFAULT will be used) |
|
NDDS_TRANSPORT_UDPV6_SOCKET_BUFFER_SIZE_OS_DEFAULT |
Uses default send socket buffer size |
|
NDDS_TRANSPORT_UDPV6_SOCKET_BUFFER_SIZE_OS_MAX |
Not supported (NDDS_TRANSPORT_UDPV6_SEND_SOCKET_BUFFER_SIZE_DEFAULT will be used) |
|
Property |
Behavior |
|---|---|
|
NDDS_TRANSPORT_UDPV4_SOCKET_BUFFER_SIZE_OS_DEFAULT |
Uses default receive socket buffer size |
|
NDDS_TRANSPORT_UDPV4_SOCKET_BUFFER_SIZE_OS_MAX |
Not supported (NDDS_TRANSPORT_UDPV4_RECV_SOCKET_BUFFER_SIZE_DEFAULT will be used) |
|
NDDS_TRANSPORT_UDPV6_SOCKET_BUFFER_SIZE_OS_DEFAULT |
Uses default receive socket buffer size |
|
NDDS_TRANSPORT_UDPV6_SOCKET_BUFFER_SIZE_OS_MAX |
Not supported (NDDS_TRANSPORT_UDPV6_RECV_SOCKET_BUFFER_SIZE_DEFAULT will be used) |