Message ID | acd12e70cfb30f04761f3c2efc868ec138c90c63.1657279685.git.viresh.kumar@linaro.org |
---|---|
State | New |
Headers | show |
Series | libgpiod: Add Rust bindings | expand |
On Fri, Jul 08, 2022 at 05:04:58PM +0530, Viresh Kumar wrote: > Add examples for the usage of the rust bindings, quite similar to the > ones in cxx bindings. > > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> > --- > bindings/rust/examples/gpiodetect.rs | 37 ++++++++++++ > bindings/rust/examples/gpiofind.rs | 42 +++++++++++++ > bindings/rust/examples/gpioget.rs | 42 +++++++++++++ > bindings/rust/examples/gpioinfo.rs | 89 ++++++++++++++++++++++++++++ > bindings/rust/examples/gpiomon.rs | 68 +++++++++++++++++++++ > bindings/rust/examples/gpioset.rs | 52 ++++++++++++++++ > 6 files changed, 330 insertions(+) > create mode 100644 bindings/rust/examples/gpiodetect.rs > create mode 100644 bindings/rust/examples/gpiofind.rs > create mode 100644 bindings/rust/examples/gpioget.rs > create mode 100644 bindings/rust/examples/gpioinfo.rs > create mode 100644 bindings/rust/examples/gpiomon.rs > create mode 100644 bindings/rust/examples/gpioset.rs > > diff --git a/bindings/rust/examples/gpiodetect.rs b/bindings/rust/examples/gpiodetect.rs > new file mode 100644 > index 000000000000..82307e4eecea > --- /dev/null > +++ b/bindings/rust/examples/gpiodetect.rs > @@ -0,0 +1,37 @@ > +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause > +// > +// Copyright 2022 Linaro Ltd. All Rights Reserved. > +// Viresh Kumar <viresh.kumar@linaro.org> > +// > +// Simplified Rust implementation of gpiodetect tool. > + > +use std::env; > +use std::fs; > +use std::path::Path; > + > +use libgpiod::{gpiod_is_gpiochip_device, Chip}; > + > +fn main() { > + let args: Vec<String> = env::args().collect(); > + if args.len() > 1 { > + println!("Usage: {}", args[0]); > + return; > + } > + > + for entry in fs::read_dir(Path::new("/dev")).unwrap() { use .flatten() to have the iterator unwrap the entry so it is actually an entry, not a Result. > + let pathbuf = entry.unwrap().path(); > + let path = pathbuf.to_str().unwrap(); > + is_gpiochip_device() and Chip::open() (and ChipInternal) should accept anything that can be converted into a &Path, e.g. a PathBuf, so the path variable becomes redundant. e.g. pub(crate) fn open<P: AsRef<std::path::Path>>(path: &P) -> Result<Self> { // Null-terminate the string let path = path.as_ref().to_string_lossy() + "\0"; ... and then example code becomes: for entry in fs::read_dir(Path::new("/dev")).unwrap().flatten() { let path = entry.path(); if gpiod_is_gpiochip_device(&path) { let chip = Chip::open(&path).unwrap(); ... (renaming pathbuf to path) Similarly other examples. > + if gpiod_is_gpiochip_device(path) { > + let chip = Chip::open(path).unwrap(); > + let ngpio = chip.get_num_lines(); > + Why does ngpio get a variable, unlike name and label? > + println!( > + "{} [{}] ({})", > + chip.get_name().unwrap(), > + chip.get_label().unwrap(), > + ngpio > + ); > + } > + } > +} Avoid using unwrap(). Have main return a Result and use ?. Not so important here, but below for helper functions returning Results allows the caller to determine how to handle the error. And it reads better. > diff --git a/bindings/rust/examples/gpiofind.rs b/bindings/rust/examples/gpiofind.rs > new file mode 100644 > index 000000000000..bbbd7a87ece8 > --- /dev/null > +++ b/bindings/rust/examples/gpiofind.rs > @@ -0,0 +1,42 @@ > +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause > +// > +// Copyright 2022 Linaro Ltd. All Rights Reserved. > +// Viresh Kumar <viresh.kumar@linaro.org> > +// > +// Simplified Rust implementation of gpiofind tool. > + > +use std::env; > +use std::fs; > +use std::path::Path; > + > +use libgpiod::{gpiod_is_gpiochip_device, Chip}; > + > +fn main() { > + let args: Vec<String> = env::args().collect(); > + if args.len() != 2 { > + println!("Usage: {} <line-name>", args[0]); > + return; > + } > + > + for entry in fs::read_dir(Path::new("/dev")).unwrap() { > + let pathbuf = entry.unwrap().path(); > + let path = pathbuf.to_str().unwrap(); > + > + if gpiod_is_gpiochip_device(path) { Perhaps have the bindings provide an iterator that returns the paths of available gpiochips? > + let chip = Chip::open(path).unwrap(); > + > + let offset = chip.find_line(&args[1]); > + if offset.is_ok() { > + println!( > + "Line {} found: Chip: {}, offset: {}", > + args[1], > + chip.get_name().unwrap(), > + offset.unwrap() > + ); > + return; > + } > + } > + } > + > + println!("Failed to find line: {}", args[1]); > +} > diff --git a/bindings/rust/examples/gpioget.rs b/bindings/rust/examples/gpioget.rs > new file mode 100644 > index 000000000000..c3bc35fcfdb6 > --- /dev/null > +++ b/bindings/rust/examples/gpioget.rs > @@ -0,0 +1,42 @@ > +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause > +// > +// Copyright 2022 Linaro Ltd. All Rights Reserved. > +// Viresh Kumar <viresh.kumar@linaro.org> > +// > +// Simplified Rust implementation of gpioget tool. > + > +use std::env; > + > +use libgpiod::{Chip, Direction, LineConfig, RequestConfig}; > + > +fn main() { > + let args: Vec<String> = env::args().collect(); > + if args.len() < 3 { > + println!("Usage: {} <chip> <line_offset0> ...", args[0]); > + return; > + } > + > + let mut config = LineConfig::new().unwrap(); > + let mut offsets = Vec::<u32>::new(); > + > + for arg in &args[2..] { > + let offset = arg.parse::<u32>().unwrap(); > + > + offsets.push(offset); > + config.set_direction_override(Direction::Input, offset); > + } > + > + let path = format!("/dev/gpiochip{}", args[1]); > + let chip = Chip::open(&path).unwrap(); > + > + let rconfig = RequestConfig::new().unwrap(); > + rconfig.set_consumer(&args[0]); > + rconfig.set_offsets(&offsets); > + > + let request = chip.request_lines(&rconfig, &config).unwrap(); > + > + let mut values: Vec<i32> = vec![0; offsets.len()]; > + request.get_values(&mut values).unwrap(); > + > + println!("{:?}", values); > +} > diff --git a/bindings/rust/examples/gpioinfo.rs b/bindings/rust/examples/gpioinfo.rs > new file mode 100644 > index 000000000000..bd30d9096ce8 > --- /dev/null > +++ b/bindings/rust/examples/gpioinfo.rs > @@ -0,0 +1,89 @@ > +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause > +// > +// Copyright 2022 Linaro Ltd. All Rights Reserved. > +// Viresh Kumar <viresh.kumar@linaro.org> > +// > +// Simplified Rust implementation of gpioinfo tool. > + > +use std::env; > +use std::fs; > +use std::path::Path; > + > +use libgpiod::{gpiod_is_gpiochip_device, Chip, Direction}; > + > +fn line_info(chip: &Chip, offset: u32) { > + let info = chip.line_info(offset).unwrap(); > + let off = info.get_offset(); > + > + let name = match info.get_name() { > + Ok(name) => name, > + _ => "unused", > + }; > + > + let consumer = match info.get_consumer() { > + Ok(name) => name, > + _ => "unnamed", > + }; > + > + let low = if info.is_active_low() { > + "active-low" > + } else { > + "active-high" > + }; > + > + let dir = match info.get_direction().unwrap() { > + Direction::AsIs => "None", > + Direction::Input => "Input", > + Direction::Output => "Output", > + }; > + > + println!( > + "\tline {:>3}\ > + \t{:>10}\ > + \t{:>10}\ > + \t{:>6}\ > + \t{:>14}", > + off, name, consumer, dir, low > + ); > +} > + > +fn chip_info(path: &str) { > + if gpiod_is_gpiochip_device(path) { > + let chip = Chip::open(path).unwrap(); > + let ngpio = chip.get_num_lines(); > + > + println!("GPIO Chip name: {}", chip.get_name().unwrap()); > + println!("\tlabel: {}", chip.get_label().unwrap()); > + println!("\tpath: {}", chip.get_path().unwrap()); > + println!("\tngpio: {}\n", ngpio); > + > + println!("\tLine information:"); > + > + for offset in 0..ngpio { > + line_info(&chip, offset); > + } > + println!("\n"); > + } > +} > + > +fn main() { > + let args: Vec<String> = env::args().collect(); > + if args.len() > 2 { > + println!("Usage: {}", args[0]); > + return; > + } > + > + if args.len() == 1 { > + for entry in fs::read_dir(Path::new("/dev")).unwrap() { > + let pathbuf = entry.unwrap().path(); > + let path = pathbuf.to_str().unwrap(); > + > + chip_info(path); > + } > + } else { > + let index = args[1].parse::<u32>().unwrap(); > + let path = format!("/dev/gpiochip{}", index); > + > + chip_info(&path); > + } > +} > diff --git a/bindings/rust/examples/gpiomon.rs b/bindings/rust/examples/gpiomon.rs > new file mode 100644 > index 000000000000..872907b386f3 > --- /dev/null > +++ b/bindings/rust/examples/gpiomon.rs > @@ -0,0 +1,68 @@ > +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause > +// > +// Copyright 2022 Linaro Ltd. All Rights Reserved. > +// Viresh Kumar <viresh.kumar@linaro.org> > +// > +// Simplified Rust implementation of the gpiomon tool. > + > +use std::env; > +use std::time::Duration; > + > +use libgpiod::{Chip, Edge, EdgeEventBuffer, Error, LineConfig, LineEdgeEvent, RequestConfig}; > + > +fn usage(name: &str) { > + println!("Usage: {} <chip> <offset0> ...", name); > +} > + > +fn main() { > + let args: Vec<String> = env::args().collect(); > + if args.len() < 3 { > + usage(&args[0]); > + return; > + } > + > + let mut config = LineConfig::new().unwrap(); > + let mut offsets = Vec::<u32>::new(); > + > + for arg in &args[2..] { > + let offset = arg.parse::<u32>().unwrap(); > + > + offsets.push(offset); > + } > + > + config.set_edge_detection_default(Edge::Both); > + > + let path = format!("/dev/gpiochip{}", args[1]); > + let chip = Chip::open(&path).unwrap(); > + > + let rconfig = RequestConfig::new().unwrap(); > + rconfig.set_offsets(&offsets); > + > + let buffer = EdgeEventBuffer::new(1).unwrap(); > + let request = chip.request_lines(&rconfig, &config).unwrap(); > + > + loop { > + match request.wait_edge_event(Duration::new(1, 0)) { > + Err(Error::OperationTimedOut) => continue, timeout/continue required as you can't (currently) block indefinitely? > + Err(x) => { > + println!("{:?}", x); > + return; > + } > + Ok(()) => (), > + } > + > + let count = request.read_edge_event(&buffer, 1).unwrap(); > + if count == 1 { > + let event = buffer.get_event(0).unwrap(); > + println!( > + "line: {} type: {}, time: {:?}", > + event.get_line_offset(), > + match event.get_event_type().unwrap() { > + LineEdgeEvent::Rising => "Rising", > + LineEdgeEvent::Falling => "Falling", > + }, > + event.get_timestamp() > + ); > + } > + } > +} > diff --git a/bindings/rust/examples/gpioset.rs b/bindings/rust/examples/gpioset.rs > new file mode 100644 > index 000000000000..ef70e8edbaae > --- /dev/null > +++ b/bindings/rust/examples/gpioset.rs > @@ -0,0 +1,52 @@ > +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause > +// > +// Copyright 2022 Linaro Ltd. All Rights Reserved. > +// Viresh Kumar <viresh.kumar@linaro.org> > +// > +// Simplified Rust implementation of the gpioset tool. > + > +use std::env; > + > +use libgpiod::{Chip, Direction, LineConfig, RequestConfig}; > + > +fn usage(name: &str) { > + println!("Usage: {} <chip> <line_offset0>=<value0> ...", name); > +} > + > +fn main() { > + let args: Vec<String> = env::args().collect(); > + if args.len() < 3 { > + usage(&args[0]); > + return; > + } > + > + let mut config = LineConfig::new().unwrap(); > + let mut offsets = Vec::<u32>::new(); > + let mut values = Vec::<i32>::new(); > + > + for arg in &args[2..] { > + let pair: Vec<&str> = arg.split('=').collect(); > + if pair.len() != 2 { > + usage(&args[0]); > + return; > + } > + > + let offset = pair[0].parse::<u32>().unwrap(); > + let value = pair[1].parse::<u32>().unwrap(); > + > + offsets.push(offset); > + values.push(value as i32); > + } > + > + config.set_direction_default(Direction::Output); > + config.set_output_values(&offsets, &values).unwrap(); > + > + let path = format!("/dev/gpiochip{}", args[1]); > + let chip = Chip::open(&path).unwrap(); > + > + let rconfig = RequestConfig::new().unwrap(); > + rconfig.set_consumer(&args[0]); > + rconfig.set_offsets(&offsets); > + > + chip.request_lines(&rconfig, &config).unwrap(); Wait rather than exiting immediately? > +} > -- > 2.31.1.272.g89b43f80a514 > And, as mentioned elsewhere, add a gpiowatch example. Cheers, Kent.
On 27-07-22, 10:58, Kent Gibson wrote: > On Fri, Jul 08, 2022 at 05:04:58PM +0530, Viresh Kumar wrote: > > diff --git a/bindings/rust/examples/gpioset.rs b/bindings/rust/examples/gpioset.rs > > + let rconfig = RequestConfig::new().unwrap(); > > + rconfig.set_consumer(&args[0]); > > + rconfig.set_offsets(&offsets); > > + > > + chip.request_lines(&rconfig, &config).unwrap(); > > Wait rather than exiting immediately? Wait for what exactly ? > And, as mentioned elsewhere, add a gpiowatch example. Will do, sure. Any existing example of the same will help though.
On Wed, Jul 27, 2022 at 02:53:19PM +0530, Viresh Kumar wrote: > On 27-07-22, 10:58, Kent Gibson wrote: > > On Fri, Jul 08, 2022 at 05:04:58PM +0530, Viresh Kumar wrote: > > > diff --git a/bindings/rust/examples/gpioset.rs b/bindings/rust/examples/gpioset.rs > > > + let rconfig = RequestConfig::new().unwrap(); > > > + rconfig.set_consumer(&args[0]); > > > + rconfig.set_offsets(&offsets); > > > + > > > + chip.request_lines(&rconfig, &config).unwrap(); > > > > Wait rather than exiting immediately? > > Wait for what exactly ? > For long enough for the user to check that the line is set, as there is the possibility that when the line is released it will be set back to its default value and you will get users reporting that your set doesn't work ;-). So wait for a keypress? > > And, as mentioned elsewhere, add a gpiowatch example. > > Will do, sure. Any existing example of the same will help though. > There is an example in my proposed tool changes for v2[1]. It is very similar to gpiomon, just on the chip and with line info instead of edge events. Though that example is more complicated than you need as it supports named lines and operating over multiple chips. Hopefully you can see past that. The basic operation is watch the line, then wait for the chip fd to be readable and read the info changed event from it. You would only unwatch if you no longer had an interest in the line, which I expect will be the case in the D-BUS daemon that Bart has suggested. Cheers, Kent. [1]https://lore.kernel.org/linux-gpio/20220708120626.89844-5-warthog618@gmail.com/
On 27-07-22, 17:59, Kent Gibson wrote: > For long enough for the user to check that the line is set, as there is > the possibility that when the line is released it will be set back to > its default value and you will get users reporting that your set > doesn't work ;-). > > So wait for a keypress? I thought we wanted to avoid human-intervention to the tests :) Can't we just read the values of the lines again here somehow and match ? I don't expect/want the user to do this for running the test. Not to mention, the user may eventually be a bot running the tests for each commit added to the tree.
On Wed, Jul 27, 2022 at 03:36:33PM +0530, Viresh Kumar wrote: > On 27-07-22, 17:59, Kent Gibson wrote: > > For long enough for the user to check that the line is set, as there is > > the possibility that when the line is released it will be set back to > > its default value and you will get users reporting that your set > > doesn't work ;-). > > > > So wait for a keypress? > > I thought we wanted to avoid human-intervention to the tests :) > This is for an example gpioset, right? You have tests for your examples? And even then you could either inject a keypress or just kill the process. (e.g. the tests for the proposed tool changes do that) Cheers, Kent. > Can't we just read the values of the lines again here somehow and match ? I > don't expect/want the user to do this for running the test. Not to mention, the > user may eventually be a bot running the tests for each commit added to the > tree. >
On 27-07-22, 18:32, Kent Gibson wrote:
> This is for an example gpioset, right?
Damn, got confused :(
diff --git a/bindings/rust/examples/gpiodetect.rs b/bindings/rust/examples/gpiodetect.rs new file mode 100644 index 000000000000..82307e4eecea --- /dev/null +++ b/bindings/rust/examples/gpiodetect.rs @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +// +// Copyright 2022 Linaro Ltd. All Rights Reserved. +// Viresh Kumar <viresh.kumar@linaro.org> +// +// Simplified Rust implementation of gpiodetect tool. + +use std::env; +use std::fs; +use std::path::Path; + +use libgpiod::{gpiod_is_gpiochip_device, Chip}; + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() > 1 { + println!("Usage: {}", args[0]); + return; + } + + for entry in fs::read_dir(Path::new("/dev")).unwrap() { + let pathbuf = entry.unwrap().path(); + let path = pathbuf.to_str().unwrap(); + + if gpiod_is_gpiochip_device(path) { + let chip = Chip::open(path).unwrap(); + let ngpio = chip.get_num_lines(); + + println!( + "{} [{}] ({})", + chip.get_name().unwrap(), + chip.get_label().unwrap(), + ngpio + ); + } + } +} diff --git a/bindings/rust/examples/gpiofind.rs b/bindings/rust/examples/gpiofind.rs new file mode 100644 index 000000000000..bbbd7a87ece8 --- /dev/null +++ b/bindings/rust/examples/gpiofind.rs @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +// +// Copyright 2022 Linaro Ltd. All Rights Reserved. +// Viresh Kumar <viresh.kumar@linaro.org> +// +// Simplified Rust implementation of gpiofind tool. + +use std::env; +use std::fs; +use std::path::Path; + +use libgpiod::{gpiod_is_gpiochip_device, Chip}; + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() != 2 { + println!("Usage: {} <line-name>", args[0]); + return; + } + + for entry in fs::read_dir(Path::new("/dev")).unwrap() { + let pathbuf = entry.unwrap().path(); + let path = pathbuf.to_str().unwrap(); + + if gpiod_is_gpiochip_device(path) { + let chip = Chip::open(path).unwrap(); + + let offset = chip.find_line(&args[1]); + if offset.is_ok() { + println!( + "Line {} found: Chip: {}, offset: {}", + args[1], + chip.get_name().unwrap(), + offset.unwrap() + ); + return; + } + } + } + + println!("Failed to find line: {}", args[1]); +} diff --git a/bindings/rust/examples/gpioget.rs b/bindings/rust/examples/gpioget.rs new file mode 100644 index 000000000000..c3bc35fcfdb6 --- /dev/null +++ b/bindings/rust/examples/gpioget.rs @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +// +// Copyright 2022 Linaro Ltd. All Rights Reserved. +// Viresh Kumar <viresh.kumar@linaro.org> +// +// Simplified Rust implementation of gpioget tool. + +use std::env; + +use libgpiod::{Chip, Direction, LineConfig, RequestConfig}; + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() < 3 { + println!("Usage: {} <chip> <line_offset0> ...", args[0]); + return; + } + + let mut config = LineConfig::new().unwrap(); + let mut offsets = Vec::<u32>::new(); + + for arg in &args[2..] { + let offset = arg.parse::<u32>().unwrap(); + + offsets.push(offset); + config.set_direction_override(Direction::Input, offset); + } + + let path = format!("/dev/gpiochip{}", args[1]); + let chip = Chip::open(&path).unwrap(); + + let rconfig = RequestConfig::new().unwrap(); + rconfig.set_consumer(&args[0]); + rconfig.set_offsets(&offsets); + + let request = chip.request_lines(&rconfig, &config).unwrap(); + + let mut values: Vec<i32> = vec![0; offsets.len()]; + request.get_values(&mut values).unwrap(); + + println!("{:?}", values); +} diff --git a/bindings/rust/examples/gpioinfo.rs b/bindings/rust/examples/gpioinfo.rs new file mode 100644 index 000000000000..bd30d9096ce8 --- /dev/null +++ b/bindings/rust/examples/gpioinfo.rs @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +// +// Copyright 2022 Linaro Ltd. All Rights Reserved. +// Viresh Kumar <viresh.kumar@linaro.org> +// +// Simplified Rust implementation of gpioinfo tool. + +use std::env; +use std::fs; +use std::path::Path; + +use libgpiod::{gpiod_is_gpiochip_device, Chip, Direction}; + +fn line_info(chip: &Chip, offset: u32) { + let info = chip.line_info(offset).unwrap(); + let off = info.get_offset(); + + let name = match info.get_name() { + Ok(name) => name, + _ => "unused", + }; + + let consumer = match info.get_consumer() { + Ok(name) => name, + _ => "unnamed", + }; + + let low = if info.is_active_low() { + "active-low" + } else { + "active-high" + }; + + let dir = match info.get_direction().unwrap() { + Direction::AsIs => "None", + Direction::Input => "Input", + Direction::Output => "Output", + }; + + println!( + "\tline {:>3}\ + \t{:>10}\ + \t{:>10}\ + \t{:>6}\ + \t{:>14}", + off, name, consumer, dir, low + ); +} + +fn chip_info(path: &str) { + if gpiod_is_gpiochip_device(path) { + let chip = Chip::open(path).unwrap(); + let ngpio = chip.get_num_lines(); + + println!("GPIO Chip name: {}", chip.get_name().unwrap()); + println!("\tlabel: {}", chip.get_label().unwrap()); + println!("\tpath: {}", chip.get_path().unwrap()); + println!("\tngpio: {}\n", ngpio); + + println!("\tLine information:"); + + for offset in 0..ngpio { + line_info(&chip, offset); + } + println!("\n"); + } +} + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() > 2 { + println!("Usage: {}", args[0]); + return; + } + + if args.len() == 1 { + for entry in fs::read_dir(Path::new("/dev")).unwrap() { + let pathbuf = entry.unwrap().path(); + let path = pathbuf.to_str().unwrap(); + + chip_info(path); + } + } else { + let index = args[1].parse::<u32>().unwrap(); + let path = format!("/dev/gpiochip{}", index); + + chip_info(&path); + } +} diff --git a/bindings/rust/examples/gpiomon.rs b/bindings/rust/examples/gpiomon.rs new file mode 100644 index 000000000000..872907b386f3 --- /dev/null +++ b/bindings/rust/examples/gpiomon.rs @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +// +// Copyright 2022 Linaro Ltd. All Rights Reserved. +// Viresh Kumar <viresh.kumar@linaro.org> +// +// Simplified Rust implementation of the gpiomon tool. + +use std::env; +use std::time::Duration; + +use libgpiod::{Chip, Edge, EdgeEventBuffer, Error, LineConfig, LineEdgeEvent, RequestConfig}; + +fn usage(name: &str) { + println!("Usage: {} <chip> <offset0> ...", name); +} + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() < 3 { + usage(&args[0]); + return; + } + + let mut config = LineConfig::new().unwrap(); + let mut offsets = Vec::<u32>::new(); + + for arg in &args[2..] { + let offset = arg.parse::<u32>().unwrap(); + + offsets.push(offset); + } + + config.set_edge_detection_default(Edge::Both); + + let path = format!("/dev/gpiochip{}", args[1]); + let chip = Chip::open(&path).unwrap(); + + let rconfig = RequestConfig::new().unwrap(); + rconfig.set_offsets(&offsets); + + let buffer = EdgeEventBuffer::new(1).unwrap(); + let request = chip.request_lines(&rconfig, &config).unwrap(); + + loop { + match request.wait_edge_event(Duration::new(1, 0)) { + Err(Error::OperationTimedOut) => continue, + Err(x) => { + println!("{:?}", x); + return; + } + Ok(()) => (), + } + + let count = request.read_edge_event(&buffer, 1).unwrap(); + if count == 1 { + let event = buffer.get_event(0).unwrap(); + println!( + "line: {} type: {}, time: {:?}", + event.get_line_offset(), + match event.get_event_type().unwrap() { + LineEdgeEvent::Rising => "Rising", + LineEdgeEvent::Falling => "Falling", + }, + event.get_timestamp() + ); + } + } +} diff --git a/bindings/rust/examples/gpioset.rs b/bindings/rust/examples/gpioset.rs new file mode 100644 index 000000000000..ef70e8edbaae --- /dev/null +++ b/bindings/rust/examples/gpioset.rs @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause +// +// Copyright 2022 Linaro Ltd. All Rights Reserved. +// Viresh Kumar <viresh.kumar@linaro.org> +// +// Simplified Rust implementation of the gpioset tool. + +use std::env; + +use libgpiod::{Chip, Direction, LineConfig, RequestConfig}; + +fn usage(name: &str) { + println!("Usage: {} <chip> <line_offset0>=<value0> ...", name); +} + +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() < 3 { + usage(&args[0]); + return; + } + + let mut config = LineConfig::new().unwrap(); + let mut offsets = Vec::<u32>::new(); + let mut values = Vec::<i32>::new(); + + for arg in &args[2..] { + let pair: Vec<&str> = arg.split('=').collect(); + if pair.len() != 2 { + usage(&args[0]); + return; + } + + let offset = pair[0].parse::<u32>().unwrap(); + let value = pair[1].parse::<u32>().unwrap(); + + offsets.push(offset); + values.push(value as i32); + } + + config.set_direction_default(Direction::Output); + config.set_output_values(&offsets, &values).unwrap(); + + let path = format!("/dev/gpiochip{}", args[1]); + let chip = Chip::open(&path).unwrap(); + + let rconfig = RequestConfig::new().unwrap(); + rconfig.set_consumer(&args[0]); + rconfig.set_offsets(&offsets); + + chip.request_lines(&rconfig, &config).unwrap(); +}
Add examples for the usage of the rust bindings, quite similar to the ones in cxx bindings. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> --- bindings/rust/examples/gpiodetect.rs | 37 ++++++++++++ bindings/rust/examples/gpiofind.rs | 42 +++++++++++++ bindings/rust/examples/gpioget.rs | 42 +++++++++++++ bindings/rust/examples/gpioinfo.rs | 89 ++++++++++++++++++++++++++++ bindings/rust/examples/gpiomon.rs | 68 +++++++++++++++++++++ bindings/rust/examples/gpioset.rs | 52 ++++++++++++++++ 6 files changed, 330 insertions(+) create mode 100644 bindings/rust/examples/gpiodetect.rs create mode 100644 bindings/rust/examples/gpiofind.rs create mode 100644 bindings/rust/examples/gpioget.rs create mode 100644 bindings/rust/examples/gpioinfo.rs create mode 100644 bindings/rust/examples/gpiomon.rs create mode 100644 bindings/rust/examples/gpioset.rs