提交 6d5800dc authored 作者: Serhij S's avatar Serhij S

raw udp for primary ipc

上级 e805cf4f
[package]
name = "roboplc"
version = "0.1.14"
version = "0.1.15"
edition = "2021"
authors = ["Serhij S. <div@altertech.com>"]
license = "Apache-2.0"
......
use roboplc::io::raw_udp::{UdpInput, UdpOutput};
use roboplc::io::{UdpReceiver, UdpSender};
use roboplc::prelude::*;
use roboplc::time::interval;
use tracing::{error, info};
......@@ -10,6 +10,8 @@ enum Message {
// A raw UDP structure, to be sent and received
//
// The recommended way of IPC for RoboPLC
//
// Raw UDP structures are used by various software, e.g. Matlab, LabView, etc. as well as by some
// fieldbus devices
#[derive(Debug, Clone)]
......@@ -28,7 +30,7 @@ struct UdpIn {}
impl Worker<Message, ()> for UdpIn {
fn run(&mut self, context: &Context<Message, ()>) -> WResult {
let server = UdpInput::<EnvData>::bind("127.0.0.1:25000", 24)?;
let server = UdpReceiver::<EnvData>::bind("127.0.0.1:25000", 24)?;
// [`UdpInput`] is an iterator of incoming UDP packets which are automatically parsed
for data in server {
match data {
......@@ -52,7 +54,7 @@ struct UdpOut {}
impl Worker<Message, ()> for UdpOut {
fn run(&mut self, context: &Context<Message, ()>) -> WResult {
let mut client = UdpOutput::connect("localhost:25000")?;
let mut client = UdpSender::connect("localhost:25000")?;
for _ in interval(Duration::from_secs(1)) {
let data = EnvData {
temp: 25.0,
......
......@@ -4,7 +4,9 @@ use binrw::{BinRead, BinWrite};
use crate::Result;
pub mod modbus;
pub mod raw_udp;
mod raw_udp;
pub use raw_udp::{UdpReceiver, UdpSender};
#[allow(clippy::module_name_repetitions)]
pub trait IoMapping {
......
......@@ -7,7 +7,8 @@ use std::{
use crate::{Error, Result};
pub struct UdpInput<T>
/// Raw UDP receiver
pub struct UdpReceiver<T>
where
T: for<'a> BinRead<Args<'a> = ()>,
{
......@@ -16,7 +17,7 @@ where
_phantom: PhantomData<T>,
}
impl<T> UdpInput<T>
impl<T> UdpReceiver<T>
where
T: for<'a> BinRead<Args<'a> = ()>,
{
......@@ -30,7 +31,7 @@ where
}
}
impl<T> Iterator for UdpInput<T>
impl<T> Iterator for UdpReceiver<T>
where
T: for<'a> BinRead<Args<'a> = ()>,
{
......@@ -47,13 +48,23 @@ where
}
}
pub struct UdpOutput {
/// Raw UDP sender
pub struct UdpSender<T>
where
T: for<'a> BinWrite<Args<'a> = ()>,
{
socket: UdpSocket,
target: SocketAddr,
data_buf: Vec<u8>,
// keep the generic `T` global (including traits) as each instance is dedicated to send a
// specific type only
_phantom: PhantomData<T>,
}
impl UdpOutput {
impl<T> UdpSender<T>
where
T: for<'a> BinWrite<Args<'a> = ()>,
{
pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<Self> {
let socket = UdpSocket::bind(("0.0.0.0", 0))?;
let target = addr
......@@ -64,13 +75,11 @@ impl UdpOutput {
socket,
target,
data_buf: <_>::default(),
_phantom: PhantomData,
})
}
pub fn send<T>(&mut self, value: T) -> Result<()>
where
T: for<'a> BinWrite<Args<'a> = ()>,
{
pub fn send(&mut self, value: T) -> Result<()> {
let mut buf = Cursor::new(&mut self.data_buf);
value.write_le(&mut buf)?;
self.socket.send_to(&self.data_buf, self.target)?;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论