Real-time threads

Intro

Linux is not a hard-realtime operating system, however in the most cases its soft real-time capabilities are enough to cope with the typical automation tasks, especially if mission-critical controls are moved to low-level dedicated equipment controllers and PLCs are used for high-level logic only.

In production environments it is recommended to isolate CPUs for input, output and program threads. It is also recommended to replace the default Linux kernel with a real-time one (if the used distribution has got a kernel with RT-PREEMPT or compile it manually), but in the majority of the cases CPU isolation is much more important.

CPU isolation

To perform CPU isolation, add isolcpus option to the Linux kernel.

Consider there are 8 CPUs in the system. To isolate the last one CPU #7 (CPU ids start from zero), on Debian/Ubuntu systems edit /etc/default/grub configuration file and add isolcpus=7 option into GRUB_CMDLINE_LINUX variable:

GRUB_CMDLINE_LINUX="isolcpus=7"

If the variable contains other options, they can be kept as space-separated. To isolate more CPUs, put their IDs to the same variable, comma separated (e.g. isolcpus=6,7).

Reboot the system. Now the CPU #7 is isolated from the default system scheduler.

Thread affinity and priority

Let us manually tune the input, output and program threads of our PLC program:

Note

This operation requires the process to be started under root.

PLC_THREAD_AFFINITY_NAME1=7,50 \
    PLC_THREAD_AFFINITY_NAME2=7,50 \
    PLC_THREAD_AFFINITY_NAME3=7,50 ./myplc

Where NAME1, NAME2, NAME3 - PLC thread names with prefixes (e.g. Pp1 for p1 program thread).

All the specified threads are automatically assigned to CPU #7 and share it using the same priority.

This can be verified by calling

rplc stat myplc

The output should show all the threads assigned to CPU #7 and their priority (50).