5.3. Connext Micro for QNX

5.3.1. Introduction

This chapter includes details regarding how Connext Micro is supported on QNX. Please note that this documentation does not include information regarding installation of QNX itself. Please consult your QNX documentation for how to install QNX.

5.3.2. QNX Platform Notes

Connext Micro uses an abstract platform API that must be ported to different platforms. This section discusses the impementation of the platform abtractions on the QNX platform.

5.3.2.1. Heap

Connext Micro allocates memory using the malloc API. This memory is managed internally by Connext Micro and is not freed.

5.3.2.2. Mutex

Connext Micro uses recursive mutexes to protect its critical sections. Because all Connext Micro APIs are synchronous, a mutex take operation blocks until the mutex becomes available. It is unexptected behavior if a mutex does not become available.

Note

QNX creates all mutexes such that priority inversion does not occur (SSR-3286-0760, Document QMS3286, QNX OS for Safety 2.1).

5.3.2.3. Semaphores

Connext Micro uses a semaphore to implement the DDS WaitSet. One semaphore is implemented with a condition variable while another sempahore is implemented with an internal timer (e.g. a DDS_WaitSet with a finite duration) that signals the condition variable upon timeout.

The resolution of a semaphore is rounded up to the nearest clock tick + 1. Thus, a semaphore may take up to 2 clock ticks (at most) extra to time out. The timeout is tied to the tick-time mentioned in Timers.

Note

Connext Micro does not support multiple threads blocking on a semaphore. None of the public Connext Micro APIs would cause multiple threads to block on the same semaphore.

5.3.2.4. Timers

Connext Micro implements its own software timers to support timed events such as periodic participant announcements and checking for missed deadlines.

The timer resolution for Connext Micro timers is 10 milliseonds. This cannot be changed without recompiling Connext Micro.

Connext Micro requires an external (to Connext Micro) clock tick to run its internal timers. On QNX, this clock tick is implemented with a POSIX real-time timer and the SIGRTMIN signal. This cannot be changed.

When the SIGRTMIN signal is raised, a timer handler signals a semaphore, which wakes up a separate thread that runs the timers. Thus, the timers are updated in a separate thread, not in the context of the signal handler.

In addition to runnning the internal timers, Connext Micro maintains an internal clock that is started when Connext Micro is first initialized, and which is incremented in each clock-tick. The clock-tick is maintained as a 32-bit signed second counter and a 32-bit unsigned nanosecond counter.

This internal clock is known as the “tick-time” and is a function of the number of clock-ticks, not the actual time. The tick-time is used to control semaphore timeout, deadline, and liveliness.

5.3.2.5. Time

DDS APIs use the time of day to timestamp samples. On QNX, this timestamp is retrieved using gettimeofday. Note that no check is performed on the returned time of day (such as time going backwards).

The time is also used to determine the interval between two samples when the sample ordering is per source timestamp on the DataWriter.

5.3.2.6. Threads

Connext Micro creates threads to run timers and process data received from the network.

By default, threads are created with the:

  • PTHREAD_EXPLICIT_SCHED attribute.

  • PTHREAD_CREATE_DETACHED attribute.

  • OS default stack size.

  • priority inheritied from spawning thread.

If the OSAPI_ThreadOptions OSAPI_THREAD_REALTIME_PRIORITY is used, the following attributes are set as well:

  • PTHREAD_SCOPE_SYSTEM

  • SCHED_FIFO

Two types of thread priorties can be set:

  • Absolute

    A priority equal to or larger than zero is used as is, and must be within the range allowed by the OS.

  • Calculated

    A priority between [OSAPI_THREAD_PRIORITY_LOW, OSAPI_THREAD_PRIORITY_HIGH] is calculated using the following formula:

    OS.min_priority + (((OS.max_priority - OS.min_priority) * priority_level)/OSAPI_THREAD_PRIORITY_HIGH);
    

5.3.2.7. Sockets

Connext Micro creates a single socket to send data with and one socket for each receive thread created. If a multicast address is specified to receive data on, multicast loopback is automatically enabled.

5.3.3. OS Resource Usage

Connext Micro uses OS resources to implement the Connext Micro abstraction layer. The following table outlines the type and amount of resources used by different entities and objects:

Entity

mutex

condition

timer

socket

threads

DDS_DomainParticipantFactory

3

0

1

0

1

DDS_DomainParticipant

2

0

0

0

0

DDS_DataReader

1

0

0

0

0

DDS_DataWriter

1

0

0

0

0

DDS_Publisher

1

0

0

0

0

DDS_Subscriber

1

0

0

0

0

DDS_WaitSet

3

2

0

0

0

DDS_GuardCondition

1

0

0

0

0

UDP Transport Send (per Participant)

0

0

0

1

0

UDP Transport Receive (per Receive locator)

0

0

0

1

1 per Receive locator

Resources:

  • mutex - POSIX mutex created with pthread_mutex_init

  • condition - POSIX condition variable created with pthread_cond_init

  • timer - POSIX real-time timer create with timer_create and using the signal SIGMINRT.

  • socket - socket created with socket

  • threads - POSIX thread created with pthread_create

5.3.4. Build environment

Source is included with Connext Micro and it is possible to compile Connext Micro from source. However, in the case of Connext Cert only binaries provided as part of the Certification Data Package are valid with the certification evidence. Compiling the source may be useful for development purposes.

Connext Micro is typically cross-compiled for QNX from a Linux host machine. Before Connext Micro can be compiled with the supplied cmake files, it is required to run the QNX setup script located in the QNX installation directory. For example, in a Linux environment:

source qnxsdp-env.sh

5.3.5. Compiling with rtime-make

Connext Micro includes cmake files for the following QNX architectures:

  • armv8QNX7.0.4qcc_gpp5.4.0 - QNX SDP 7, ARMv8

  • armv8QOS2.1qcc_gpp5.4.0 - QNX OS for Safety 2.1, ARMv8

To compile for these architectures, execute the following command:

resource/scripts/rtime-make --target <architecture> --build --config Release