提交 8476d4b9 authored 作者: Serhij S's avatar Serhij S

v0.4 (rtsc 0.3)

上级 6883e204
......@@ -17,8 +17,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: cargo test
run: cargo test --all-features --all-targets --features openssl-vendored
- name: cargo test default
run: cargo test --all-targets
- name: cargo test locking-rt
run: cargo test --no-default-features --all-targets -F locking-rt
- name: cargo test locking-rt-safe
run: cargo test --no-default-features --all-targets -F locking-rt-safe
- name: cargo test default full
run: cargo test --all-targets -F full,openssl-vendored
- name: cargo test locking-rt full
run: cargo test --no-default-features --all-targets -F locking-rt,full,openssl-vendored
- name: cargo test locking-rt-safe full
run: cargo test --no-default-features --all-targets -F locking-rt-safe,full,openssl-vendored
fmt:
runs-on: ubuntu-latest
steps:
......@@ -31,7 +42,8 @@ jobs:
- uses: actions/checkout@v3
- name: cargo clippy
run: |
cargo clippy --all-targets -- -W clippy::all -W clippy::pedantic \
cargo clippy -F full,openssl-vendored --all-targets -- \
-W clippy::all -W clippy::pedantic \
-A clippy::used-underscore-binding \
-A clippy::doc_markdown \
-A clippy::needless_pass_by_value \
......
......@@ -2,6 +2,16 @@
## RoboPLC
### 0.4.0 (2024-07-29)
* Custom real-time locking policies
* Stability and architecture improvements
* [RFlow](https://crates.io/crates/rflow) integration
* Docker support
### 0.3.0 (2024-06-16)
* Real-time-safe data synchronization components moved to
......
......@@ -43,10 +43,12 @@ log = "0.4.21"
metrics-exporter-prometheus = { version = "0.14.0", optional = true, default-features = false, features = ["http-listener"] }
metrics = { version = "0.22.3", optional = true }
snmp = { version = "0.2.2", optional = true }
rtsc = "0.2"
rvideo = { version = "0.4", optional = true }
rflow = { version = "0", optional = true }
rtsc = "0.3"
rvideo = { version = "0.5", optional = true }
rflow = { version = "0.1", optional = true }
once_cell = { version = "1.19.0", optional = true }
parking_lot = { version = "0.12.3", optional = true }
parking_lot_rt = { version = "0.12.1", optional = true }
[features]
eapi = ["eva-common", "eva-sdk", "busrt", "tokio", "hostname", "once_cell"]
......@@ -56,8 +58,14 @@ rflow = ["dep:rflow"]
modbus = ["rmodbus"]
openssl-vendored = ["busrt/openssl-vendored", "eva-common/openssl-vendored"]
metrics = ["dep:metrics", "metrics-exporter-prometheus"]
full = ["eapi", "modbus", "metrics", "pipe", "rvideo", "rflow"]
#default = ["modbus"]
async = ["dep:parking_lot_rt"]
full = ["eapi", "modbus", "metrics", "pipe", "rvideo", "rflow", "async"]
locking-default = ["dep:parking_lot", "rtsc/parking_lot"]
locking-rt = ["dep:parking_lot_rt"]
locking-rt-safe = []
default = ["locking-default"]
[dev-dependencies]
insta = "1.36.1"
......
......@@ -103,6 +103,23 @@ affinity (Linux only).
[`supervisor::Supervisor`] provides a lightweight task supervisor to manage
launched threads.
## Locking safety
Note: the asynchronous components uses `parking_lot_rt` locking only.
By default, the crate (both the server and the client modules) uses
[parking_lot](https://crates.io/crates/parking_lot) for locking. For real-time
applications, the following features are available:
* `locking-rt` - use [parking_lot_rt](https://crates.io/crates/parking_lot_rt)
crate which is a spin-free fork of parking_lot.
* `locking-rt-safe` - use [RTSC](https://crates.io/crates/rtsc)
priority-inheritance locking, which is not affected by priority inversion
(Linux only).
Note: to switch locking policy, disable the crate default features.
## Controller
[`controller::Controller`] is the primary component of mixing up all the
......@@ -140,3 +157,20 @@ Currently supported:
The components [`thread_rt`], [`supervisor`] and [`controller`] can work on
Linux machines only.
## Migration from 0.3.x
* [`roboplc::pchannel`] and [`roboplc::pchannel_async`] have been renamed to
[`roboplc::policy_channel`] and [`roboplc::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](https://crates.io/crates/rtsc) components are lock-agnostic, which
requires to specify generic locking types, the modules [`roboplc::channel`],
[`roboplc::policy_channel`], [`roboplc::buf`] and [`roboplc::semaphore`] are
now wrappers around RTSC modules with the chosen locking policy.
* [`roboplc::hub_async`] now requires `async` feature to be enabled.
use crate::pchannel;
use crate::policy_channel as pchannel;
use crate::{Error, Result};
use super::{
......
......@@ -3,7 +3,7 @@ use std::sync::Arc;
use crate::locking::Mutex;
use rtsc::data_policy::DataDeliveryPolicy;
use crate::pchannel::{self, Receiver, Sender};
use crate::policy_channel::{self as pchannel, Receiver, Sender};
use crate::{Error, Result};
use self::prelude::DataChannel;
......
use std::future::Future;
use std::sync::Arc;
use crate::locking::Mutex;
use parking_lot_rt::Mutex;
use crate::pchannel_async::{self, Receiver, Sender};
use crate::policy_channel_async::{self as pchannel_async, Receiver, Sender};
use crate::{DataDeliveryPolicy, Error, Result};
type ConditionFunction<T> = Box<dyn Fn(&T) -> bool + Send + Sync>;
......
......@@ -28,6 +28,10 @@ static CARGO_PKG_VERSION: OnceCell<String> = OnceCell::new();
/// Sets the EAPI module information. Must be called only once. Usually not needed to be called
/// directly, as executed by the `init_eapi!` macro.
///
/// # Panics
///
/// Will panic if called more than once
pub fn set_program_info(authors: &str, description: &str, version: &str) {
CARGO_PKG_AUTHORS.set(authors.to_owned()).unwrap();
CARGO_PKG_DESCRIPTION.set(description.to_owned()).unwrap();
......@@ -48,9 +52,9 @@ macro_rules! init_eapi {
}
use crate::controller::{Context, SLEEP_STEP};
use crate::{pchannel_async, DataDeliveryPolicy, DeliveryPolicy};
use crate::{policy_channel_async as pchannel_async, DataDeliveryPolicy, DeliveryPolicy};
use crate::{
pchannel_async::{Receiver as ReceiverAsync, Sender as SenderAsync},
policy_channel_async::{Receiver as ReceiverAsync, Sender as SenderAsync},
Error, Result,
};
use busrt::{
......
use crate::io::{modbus::ModbusRegister, IoMapping};
use crate::locking::{Mutex, MutexGuard};
use crate::semaphore::Semaphore;
use crate::{
comm::{self, Protocol},
Error, Result,
......@@ -9,7 +10,6 @@ use rmodbus::{
server::{context::ModbusContext, storage::ModbusStorage, ModbusFrame},
ModbusFrameBuf, ModbusProto,
};
use rtsc::semaphore::Semaphore;
use serial::SystemPort;
use std::time::Duration;
use std::{
......
......@@ -14,7 +14,7 @@ use tokio::{
use tracing::error;
use crate::{
pchannel_async::{self, Receiver},
policy_channel_async::{self as pchannel_async, Receiver},
DataDeliveryPolicy, Result,
};
......
......@@ -12,16 +12,79 @@ use thread_rt::{RTParams, Scheduling};
pub use log::LevelFilter;
pub use rtsc::{DataChannel, DataPolicy};
pub use rtsc::locking;
#[cfg(feature = "locking-default")]
pub use parking_lot as locking;
#[cfg(feature = "locking-rt")]
pub use parking_lot_rt as locking;
#[cfg(feature = "locking-rt-safe")]
pub use rtsc::pi as locking;
#[cfg(feature = "metrics")]
pub use metrics;
pub use rtsc::buf;
pub use rtsc::pchannel;
pub use rtsc::pchannel_async;
pub use rtsc::policy_channel_async;
pub use rtsc::time;
/// Wrapper around [`rtsc::buf`] with the chosen locking policy
pub mod buf {
/// Type alias for [`rtsc::buf::DataBuffer`] with the chosen locking policy
pub type DataBuffer = rtsc::buf::DataBuffer<crate::locking::RawMutex>;
}
/// Wrapper around [`rtsc::channel`] with the chosen locking policy
pub mod channel {
/// Type alias for [`rtsc::channel::Sender`] with the chosen locking policy
pub type Sender<T> =
rtsc::channel::Sender<T, crate::locking::RawMutex, crate::locking::Condvar>;
/// Type alias for [`rtsc::channel::Receiver`] with the chosen locking policy
pub type Receiver<T> =
rtsc::channel::Receiver<T, crate::locking::RawMutex, crate::locking::Condvar>;
/// Function alias for [`rtsc::channel::bounded`] with the chosen locking policy
#[inline]
pub fn bounded<T>(capacity: usize) -> (Sender<T>, Receiver<T>) {
rtsc::channel::bounded(capacity)
}
}
/// Wrapper around [`rtsc::policy_channel`] with the chosen locking policy
pub mod policy_channel {
use crate::DataDeliveryPolicy;
/// Type alias for [`rtsc::policy_channel::Sender`] with the chosen locking policy
pub type Sender<T> =
rtsc::policy_channel::Sender<T, crate::locking::RawMutex, crate::locking::Condvar>;
/// Type alias for [`rtsc::policy_channel::Receiver`] with the chosen locking policy
pub type Receiver<T> =
rtsc::policy_channel::Receiver<T, crate::locking::RawMutex, crate::locking::Condvar>;
/// Function alias for [`rtsc::policy_channel::bounded`] with the chosen locking policy
#[inline]
pub fn bounded<T: DataDeliveryPolicy>(capacity: usize) -> (Sender<T>, Receiver<T>) {
rtsc::policy_channel::bounded(capacity)
}
/// Function alias for [`rtsc::policy_channel::ordered`] with the chosen locking policy
#[inline]
pub fn ordered<T: DataDeliveryPolicy>(capacity: usize) -> (Sender<T>, Receiver<T>) {
rtsc::policy_channel::ordered(capacity)
}
}
/// Wrapper around [`rtsc::semaphore`] with the chosen locking policy
pub mod semaphore {
/// Type alias for [`rtsc::semaphore::Semaphore`] with the chosen locking policy
pub type Semaphore =
rtsc::semaphore::Semaphore<crate::locking::RawMutex, crate::locking::Condvar>;
/// Type alias for [`rtsc::semaphore::SemaphoreGuard`] with the chosen locking policy
#[allow(clippy::module_name_repetitions)]
pub type SemaphoreGuard =
rtsc::semaphore::SemaphoreGuard<crate::locking::RawMutex, crate::locking::Condvar>;
}
pub use rtsc::data_policy::{DataDeliveryPolicy, DeliveryPolicy};
/// Reliable TCP/Serial communications
......@@ -32,6 +95,7 @@ pub mod controller;
/// In-process data communication pub/sub hub, synchronous edition
pub mod hub;
/// In-process data communication pub/sub hub, asynchronous edition
#[cfg(feature = "async")]
pub mod hub_async;
/// I/O
pub mod io;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论