Macro process_image::process_image
source · macro_rules! process_image { ( $( #[$meta:meta] )* $vis:vis struct $ProcessImage:ident, mut $ProcessImageMut:ident: $SIZE:literal { $( $( #[$field_meta:meta] )* $field_vis:vis $field_name:ident: ($($tag:tt)+) ),* $(,)? } ) => { ... }; ( $( #[$meta:meta] )* $vis:vis struct mut $ProcessImageMut:ident: $SIZE:literal { $( $( #[$field_meta:meta] )* $field_vis:vis $field_name:ident: ($($tag:tt)+) ),* $(,)? } ) => { ... }; ( $( #[$meta:meta] )* $vis:vis struct $ProcessImage:ident: $SIZE:literal { $( $( #[$field_meta:meta] )* $field_vis:vis $field_name:ident: ($($tag:tt)+) ),* $(,)? } ) => { ... }; }
Expand description
Build tag table for symbolic access to a process image.
- You will get two structs, one for mutable and one for immutable access (or just one of them, if you want).
- The process image has a fixed size which is always enforced.
- The tag addresses are in the format described in the
tag!()
macro.
§Example
process_image::process_image! {
// +-- Size of the process image in bytes
// V
pub struct PiExample, mut PiExampleMut: 16 {
// +-- Tag Name +-- Absolute Address
// V V
pub sensor_left: (X, 0, 0), // %MX0.0
pub sensor_right: (X, 0, 1), // %MX0.1
pub temperature: (D, 4), // %MD4
pub setpoint: (W, 2), // %MW2
}
}
let mut pi_buf = [0x00; 16];
let pi = PiExample::from(&pi_buf);
dbg!(pi.sensor_left());
dbg!(pi.sensor_left());
// You need to use try_from() when using a slice. The unwrap() will panic when the size of the
// slice does not match the size of the process image.
let pi_slice = &pi_buf[..];
let pi = PiExample::try_from(pi_slice).unwrap();
// Mutable access:
let pi_slice_mut = &mut pi_buf[..];
let mut pi = PiExampleMut::try_from(pi_slice_mut).unwrap();
*pi.temperature() = 1234;
*pi.setpoint() = 72;
*pi.sensor_left() = false;
As mentioned above, you can also generate just the mutable or just the immutable version:
process_image::process_image! {
pub struct PiInputs: 16 {
pub sensor_left: (X, 0, 0), // %IX0.0
pub sensor_right: (X, 0, 1), // %IX0.1
pub temperature: (D, 12), // %ID12
}
}
process_image::process_image! {
pub struct mut PiOutputs: 8 {
pub indicator_green: (X, 1, 0), // %QX1.0
pub indicator_red: (X, 1, 2), // %QX1.2
pub setpoint: (W, 2), // %QW2
}
}
let inp = PiInputs::try_from(&buffer_in).unwrap();
let mut out = PiOutputs::try_from(&mut buffer_out).unwrap();
let left_or_right = inp.sensor_left() || inp.sensor_right();
*out.indicator_green() = !left_or_right;
*out.indicator_red() = left_or_right;