diff --git a/Cargo.toml b/Cargo.toml index 5e99f56..1fc2418 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["std"] +default = [] std = [] [lib] @@ -26,8 +26,8 @@ name = "flem" path = "examples/example.rs" [[example]] -name = "traits" -path = "examples/traits.rs" +name = "encode_decode" +path = "examples/encode_decode.rs" [[example]] name = "software_host_simple" diff --git a/README.md b/README.md index 200ce4e..b2e750a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Flem Build and Tests](https://github.com/amcelroy/flem-rust/actions/workflows/rust.yml/badge.svg) -# FLEM Rust 0.6.0 +# FLEM Rust 0.6.2 FLEM stands for Flexible, Light-weight, Embedded Messaging and is a Little Endian messaging protocol intended for use in communicating with embedded @@ -10,7 +10,9 @@ systems targets over numerous types of buses. ### Changelog 0.6.2 - Added feature = ["std"] -- Added `Channel` trait. This +- Added `Channel` trait. This trait requires features = ["std"]. It servers as a set of traits that can be used +to implement different hardware or to emulate a device. It uses the `std` library for threading and `mpsc` channels. +- Added examples to show how to emulate a device use the `Channel` trait. ### Changelog 0.6.1 - Added fmt::Debug trait to Packet that prints the header, checksum, request, response, length, and status. diff --git a/examples/traits.rs b/examples/encode_decode.rs similarity index 100% rename from examples/traits.rs rename to examples/encode_decode.rs diff --git a/examples/software_host_complex.rs b/examples/software_host_complex.rs index 0d4199f..1ea2d4e 100644 --- a/examples/software_host_complex.rs +++ b/examples/software_host_complex.rs @@ -1,25 +1,20 @@ -use flem::{ - Packet, - DataId, - traits::Channel -}; +use flem::{traits::Channel, DataId, Packet}; use std::{ - time::Duration, sync::{ - Arc, - Mutex, - mpsc::{self, Sender, Receiver} + mpsc::{self, Receiver, Sender}, + Arc, Mutex, }, thread, + time::Duration, }; const PACKET_SIZE: usize = 512; const PACKET_DEVICE_SIZE: usize = 128; #[derive(Clone)] -struct FlemSoftwareHost{ - listening: Arc>, - flem_packet_handler: Option) -> Packet> +struct FlemSoftwareHost { + listening: Arc>, + flem_packet_handler: Option) -> Packet>, } impl FlemSoftwareHost { @@ -48,13 +43,18 @@ impl Channel for FlemSoftwareHost (Sender>, Receiver>) { + fn listen( + &mut self, + rx_sleep_time_ms: u64, + tx_sleep_time_ms: u64, + ) -> (Sender>, Receiver>) { // This example is similar to how flem-serial-rs works, except we need to add in a simulated byte-by-byte hardware transmission. // If there is no need to simulate Rx and Tx hardware, a single thread would work that accepts a packet from `packet_to_transmit`, // parses it, and sends a response on `validated_packet`. - + // Tx packets are marshalled into a single queue, and dispatched over hardware. - let (tx_packet_from_program, packet_to_transmit) = mpsc::channel::>(); + let (tx_packet_from_program, packet_to_transmit) = + mpsc::channel::>(); // Rx data is coming off of hardware, usually a byte at a time, and needs to be constructed into a packet and validated before passing back into the program let (validated_packet, rx_packet_to_program) = mpsc::channel::>(); @@ -62,7 +62,7 @@ impl Channel for FlemSoftwareHost(); let (simulated_hardware_device_tx, simulated_hardware_host_rx) = mpsc::channel::(); - + *self.listening.lock().unwrap() = true; let listening_clone_rx = self.listening.clone(); @@ -73,11 +73,17 @@ impl Channel for FlemSoftwareHost Channel for FlemSoftwareHost::new(); - while *listening_clone_device.lock().unwrap() { + while *listening_clone_device.lock().unwrap() { // List for data on hardware - if let Ok(byte) = simulated_hardware_device_rx.recv_timeout(Duration::from_millis(10)) { + if let Ok(byte) = + simulated_hardware_device_rx.recv_timeout(Duration::from_millis(10)) + { match packet.construct(byte) { Ok(_) => { // Packet received - println!("Packet received on device successfully with checksum {}", packet.get_checksum()); + println!( + "Packet received on device successfully with checksum {}", + packet.get_checksum() + ); if device_flem_handler.is_none() { println!("Packet handler not set, working as a loop-back"); for byte in packet.bytes() { simulated_hardware_device_tx.send(*byte).unwrap(); - } - }else{ + } + } else { println!("Packet handler set, calling handler"); let handler = device_flem_handler.as_ref().unwrap(); let response = handler(&packet); for byte in response.bytes() { simulated_hardware_device_tx.send(*byte).unwrap(); - } + } + println!( + "Raw packet from device to host in bytes: {:?}", + response.bytes() + ); } println!("Packet sent from device successfully"); - packet.reset_lazy(); - }, + packet.reset_lazy(); + } Err(error) => { match error { flem::Status::PacketBuilding => { @@ -125,7 +140,7 @@ impl Channel for FlemSoftwareHost Channel for FlemSoftwareHost { // Packet received - println!("Packet received successfully with checksum {}", packet.get_checksum()); + println!( + "Packet received successfully with checksum {}", + packet.get_checksum() + ); validated_packet.send(packet); println!("Packet sent to program"); - packet.reset_lazy(); - }, + packet.reset_lazy(); + } Err(error) => { match error { flem::Status::PacketBuilding => { @@ -158,7 +178,7 @@ impl Channel for FlemSoftwareHost { response.set_request(flem::request::ID); response.set_response(flem::response::UNKNOWN_REQUEST); @@ -211,23 +231,22 @@ fn main() { tx.send(packet).unwrap(); loop { - if let Ok(packet) = rx.recv_timeout(Duration::from_millis(25)) - { + if let Ok(packet) = rx.recv_timeout(Duration::from_millis(25)) { println!("Received packet: {:?}", packet); - // Do stuff with the packet + // Do stuff with the packet match packet.get_request() { flem::request::ID => { let id = DataId::from(&packet.get_data()).unwrap(); println!( - "DataId Message: {}, max packet size: {}, Major: {}, Minor: {}, Patch: {}", + "DataId Message: {}, max packet size: {}, Major: {}, Minor: {}, Patch: {}", String::from_iter(id.get_name().iter()), id.get_max_packet_size(), id.get_major(), id.get_minor(), id.get_patch() ); - }, + } _ => { // Unknown request } @@ -237,4 +256,4 @@ fn main() { break; } } -} \ No newline at end of file +}