提交 766bc301 authored 作者: Serhij S's avatar Serhij S

controller shared variables no longer under RwLock by default

上级 75e96170
...@@ -5,7 +5,10 @@ use roboplc::{ ...@@ -5,7 +5,10 @@ use roboplc::{
time::interval, time::interval,
}; };
use serde::Deserialize; use serde::Deserialize;
use std::sync::Arc; use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use tracing::info; use tracing::info;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
...@@ -18,7 +21,7 @@ struct Env { ...@@ -18,7 +21,7 @@ struct Env {
#[derive(Default)] #[derive(Default)]
struct Variables { struct Variables {
fan: bool, fan: AtomicBool,
} }
#[derive(DataPolicy, Clone)] #[derive(DataPolicy, Clone)]
...@@ -51,8 +54,10 @@ impl Worker<Message, Variables> for Worker1 { ...@@ -51,8 +54,10 @@ impl Worker<Message, Variables> for Worker1 {
pressure: temp as f64 / 3.0, pressure: temp as f64 / 3.0,
}, },
)?; )?;
self.eapi self.eapi.state_push(
.state_push(oid.clone(), u8::from(context.variables().read().fan))?; oid.clone(),
u8::from(context.variables().fan.load(Ordering::Acquire)),
)?;
//self.eapi.dobj_error(dobj_name.clone())?; //self.eapi.dobj_error(dobj_name.clone())?;
if !context.is_online() { if !context.is_online() {
break; break;
...@@ -83,7 +88,7 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> { ...@@ -83,7 +88,7 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
.action_handler("unit:tests/fan".parse().unwrap(), |action, context| { .action_handler("unit:tests/fan".parse().unwrap(), |action, context| {
let params = action.take_unit_params()?; let params = action.take_unit_params()?;
let val = u8::deserialize(params.value)?; let val = u8::deserialize(params.value)?;
context.variables().write().fan = val != 0; context.variables().fan.store(val != 0, Ordering::Release);
Ok(()) Ok(())
}); });
// this creates a connector instance with the name `fieldbus.HOSTNAME.plc`. To use a custom // this creates a connector instance with the name `fieldbus.HOSTNAME.plc`. To use a custom
......
use roboplc::locking::Mutex;
use roboplc::{ use roboplc::{
comm::{tcp, Client}, comm::{tcp, Client},
time::interval, time::interval,
...@@ -11,9 +12,11 @@ const MODBUS_TIMEOUT: Duration = Duration::from_secs(1); ...@@ -11,9 +12,11 @@ const MODBUS_TIMEOUT: Duration = Duration::from_secs(1);
// Do not make any decision if the sensor is older than this // Do not make any decision if the sensor is older than this
const ENV_DATA_TTL: Duration = Duration::from_millis(1); const ENV_DATA_TTL: Duration = Duration::from_millis(1);
type Variables = Mutex<VariablesData>;
// A shared traditional PLC context, does not used for logic here but provided as an example // A shared traditional PLC context, does not used for logic here but provided as an example
#[derive(Default)] #[derive(Default)]
struct Variables { struct VariablesData {
temperature: f32, temperature: f32,
} }
...@@ -66,7 +69,7 @@ impl Worker<Message, Variables> for ModbusPuller1 { ...@@ -66,7 +69,7 @@ impl Worker<Message, Variables> for ModbusPuller1 {
for _ in interval(Duration::from_millis(500)) { for _ in interval(Duration::from_millis(500)) {
match self.sensor_mapping.read::<EnvironmentSensors>() { match self.sensor_mapping.read::<EnvironmentSensors>() {
Ok(v) => { Ok(v) => {
context.variables().write().temperature = v.temperature; context.variables().lock().temperature = v.temperature;
hub.send(Message::EnvSensorData(TtlCell::new_with_value( hub.send(Message::EnvSensorData(TtlCell::new_with_value(
ENV_DATA_TTL, ENV_DATA_TTL,
v, v,
......
use roboplc::comm::Protocol; use roboplc::comm::Protocol;
use roboplc::io::modbus::prelude::*; use roboplc::io::modbus::prelude::*;
use roboplc::locking::Mutex;
use roboplc::{prelude::*, time::interval}; use roboplc::{prelude::*, time::interval};
use tracing::info; use tracing::info;
...@@ -35,10 +36,11 @@ struct Input { ...@@ -35,10 +36,11 @@ struct Input {
// This example does not use controller's data hub // This example does not use controller's data hub
type Message = (); type Message = ();
type Variables = Mutex<VariableData>;
// Controller's shared variables // Controller's shared variables
#[derive(Default)] #[derive(Default)]
struct Variables { struct VariableData {
data: Data, data: Data,
relays: Relays, relays: Relays,
input: Input, input: Input,
...@@ -58,7 +60,7 @@ struct Worker1 { ...@@ -58,7 +60,7 @@ struct Worker1 {
impl Worker<Message, Variables> for Worker1 { impl Worker<Message, Variables> for Worker1 {
fn run(&mut self, context: &Context<Message, Variables>) -> WResult { fn run(&mut self, context: &Context<Message, Variables>) -> WResult {
for _ in interval(Duration::from_secs(2)) { for _ in interval(Duration::from_secs(2)) {
let mut vars = context.variables().write(); let mut vars = context.variables().lock();
vars.data.counter += 1; vars.data.counter += 1;
vars.relays.relay1 = u8::from(vars.data.counter % 2 == 0); vars.relays.relay1 = u8::from(vars.data.counter % 2 == 0);
vars.relays.relay2 = u8::from(vars.data.counter % 2 != 0); vars.relays.relay2 = u8::from(vars.data.counter % 2 != 0);
......
...@@ -15,7 +15,6 @@ use crate::{ ...@@ -15,7 +15,6 @@ use crate::{
thread_rt::{Builder, RTParams, Scheduling}, thread_rt::{Builder, RTParams, Scheduling},
Error, Result, Error, Result,
}; };
use parking_lot_rt::RwLock;
pub use roboplc_derive::WorkerOpts; pub use roboplc_derive::WorkerOpts;
use rtsc::data_policy::DataDeliveryPolicy; use rtsc::data_policy::DataDeliveryPolicy;
use signal_hook::{ use signal_hook::{
...@@ -106,7 +105,7 @@ where ...@@ -106,7 +105,7 @@ where
supervisor: Supervisor<()>, supervisor: Supervisor<()>,
hub: Hub<D>, hub: Hub<D>,
state: State, state: State,
variables: Arc<RwLock<V>>, variables: Arc<V>,
} }
impl<D, V> Controller<D, V> impl<D, V> Controller<D, V>
...@@ -132,7 +131,7 @@ where ...@@ -132,7 +131,7 @@ where
supervisor: <_>::default(), supervisor: <_>::default(),
hub: <_>::default(), hub: <_>::default(),
state: State::new(), state: State::new(),
variables: Arc::new(RwLock::new(variables)), variables: Arc::new(variables),
} }
} }
/// Spawns a worker /// Spawns a worker
...@@ -280,7 +279,7 @@ where ...@@ -280,7 +279,7 @@ where
&self.supervisor &self.supervisor
} }
/// Controller shared variables /// Controller shared variables
pub fn variables(&self) -> &Arc<RwLock<V>> { pub fn variables(&self) -> &Arc<V> {
&self.variables &self.variables
} }
} }
...@@ -304,7 +303,7 @@ where ...@@ -304,7 +303,7 @@ where
{ {
hub: Hub<D>, hub: Hub<D>,
state: State, state: State,
variables: Arc<RwLock<V>>, variables: Arc<V>,
} }
impl<D, V> Clone for Context<D, V> impl<D, V> Clone for Context<D, V>
...@@ -331,7 +330,7 @@ where ...@@ -331,7 +330,7 @@ where
&self.hub &self.hub
} }
/// Controller's shared variables (locked) /// Controller's shared variables (locked)
pub fn variables(&self) -> &Arc<RwLock<V>> { pub fn variables(&self) -> &Arc<V> {
&self.variables &self.variables
} }
/// Controller's state /// Controller's state
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论