62 releases

0.4.6 Oct 19, 2024
0.4.4 Aug 27, 2024
0.4.2 Jul 30, 2024
0.1.23 Mar 31, 2024

#253 in Concurrency


Used in 2 crates

Apache-2.0

180KB
4K SLoC

RoboPLC crates.io page docs.rs page

RoboPLC is an ultimate pack of a framework and tools for creating real-time micro-services, PLCs and industrial-grade robots in Rust.

The crate is designed to let using all its components both separately and together.

RoboPLC is a part of EVA ICS industrial automation platform.

Real-time-safe data synchronization components are re-exported from the RTSC crate which is a part of RoboPLC project and can be used directly, with no requirement to use RoboPLC.

Technical documentation

Available at https://info.bma.ai/en/actual/roboplc/index.html

Examples

Can be found at https://github.com/roboplc/roboplc/tree/main/examples

DataBuffer

buf::DataBuffer covers a typical data exchange pattern when data frames are collected (cached) from a single or multiple producers, then taken by a single consumer in bulk and submitted, e.g. into a local database or into an external bus.

  • always has got a fixed capacity

  • thread-safe out-of-the-box

  • frames may be forcibly pushed, overriding the previous ones, like in a ring-buffer.

Hub

hub::Hub implements a data-hub (in-process pub/sub) model, when multiple clients (usually thread workers) exchange data via a single virtual bus instead of using direct channels.

This brings some additional overhead into data exchange, however makes the architecture significantly clearer, lowers code support costs and brings additional features.

  • classic pub/sub patterns with no data serialization overhead

  • based on policy_channel which allows to mix different kinds of data and apply additional policies if required

  • a fully passive model with no "server" thread.

pdeque and policy_channel

A policy-based deque rtsc::pdeque::Deque is a component to build policy-based channels.

policy_channel is a channel module, based on the policy-based deque.

Data policies supported:

  • Always a frame is always delivered
  • Latest a frame is always delivered, previous are dropped if no room (acts like a ring-buffer)
  • Optional a frame can be skipped if no room
  • Single a frame must be delivered only once (the latest one)
  • SingleOptional a frame must be delivered only once (the latest one) and is optional

Additionally, components support ordering by data priority and automatically drop expired data if the data type has got an expiration marker method implemented.

policy_channel is a real-time safe channel, mean it may be not so fast as popular channel implementations (it may be even slower than channels provided by std::sync::mpsc). But it is completely safe for real-time applications, mean there are no spin loops, data is always delivered with minimal latency and threads do not block each other.

Real-time

thread_rt::Builder provides a thread builder component, which extends the standard thread builder with real-time capabilities: scheduler policies and CPU affinity (Linux only).

supervisor::Supervisor provides a lightweight task supervisor to manage launched threads.

Controller

controller::Controller is the primary component of mixing up all the functionality together.

I/O

[io] module provides a set of tools to work with field devices and SCADA buses.

Currently supported:

Locking safety

Note: the asynchronous components use parking_lot_rt locking only.

By default, the crate uses parking_lot for locking. For real-time applications, the following features are available:

  • locking-rt - use parking_lot_rt crate which is a spin-free fork of parking_lot.

  • locking-rt-safe - use RTSC priority-inheritance locking, which is not affected by priority inversion (Linux only, recommended Kernel 5.14+).

Note: to switch locking policy, disable the crate default features.

The locking policy can be also selected in CLI when creating a new project:

robo new --locking rt-safe # the default for CLI-created projects is rt-safe

Using on other platforms

The components thread_rt, supervisor and controller can work on Linux machines only.

Migration from 0.3.x

  • pchannel and pchannel_async have been renamed to policy_channel and policy_channel_async respectively.

  • By default, the crate uses parking_lot for locking. To switch to more safe real-time locking, disable the crate default features and enable either locking-rt or locking-rt-safe. This is important for real-time applications and must be enabled manually.

  • As RTSC components are lock-agnostic, which requires to specify generic locking types, the modules channel, policy_channel, [buf] and semaphore are now wrappers around RTSC modules with the chosen locking policy.

  • hub_async now requires async feature to be enabled.

Dependencies

~9–25MB
~393K SLoC