From bd96def4be63ff0af030c319d5a70403ce271a9e Mon Sep 17 00:00:00 2001 From: Luca Date: Mon, 20 Jun 2022 15:13:39 -0400 Subject: [PATCH 01/19] added get capture --- src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a495e41..b8deebb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -186,6 +186,11 @@ impl Pwm { pwm_file_parse::(&self.chip, self.number, "duty_cycle") } + /// Get the capture + pub fn get_capture(&self) -> Result { + pwm_file_parse::(&self.chip, self.number, "capture") + } + /// The active time of the PWM signal /// /// Value is in nanoseconds and must be less than the period. @@ -240,8 +245,9 @@ impl Pwm { "normal" => Ok(Polarity::Normal), "inversed" => Ok(Polarity::Inverse), _ => Err(Error::Unexpected(format!( - "Unexpected polarity file contents: {:?}", - s))), + "Unexpected polarity file contents: {:?}", + s + ))), } } } From 1b03a0b334424811d517b8f90a94646cc555c855 Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 24 Jun 2022 16:21:26 -0400 Subject: [PATCH 02/19] changed capture function to return tuple --- src/lib.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b8deebb..5b6f606 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,22 @@ fn pwm_file_parse(chip: &PwmChip, pin: u32, name: &str) -> Result } } +/// Get the two u32 from capture file descriptor +fn pwm_capture_parse(chip: &PwmChip, pin: u32, name: &str) -> Result> { + let mut s = String::with_capacity(10); + let mut f = pwm_file_ro(chip, pin, name)?; + f.read_to_string(&mut s)?; + s = s.trim().to_string(); + let capture = s.split_whitespace().collect::>(); + let mut vec: Vec = vec![]; + for s in capture.iter() { + if let Ok(j) = s.parse::() { + vec.push(j); + } + } + Ok(vec) +} + impl PwmChip { pub fn new(number: u32) -> Result { fs::metadata(&format!("/sys/class/pwm/pwmchip{}", number))?; @@ -187,8 +203,13 @@ impl Pwm { } /// Get the capture - pub fn get_capture(&self) -> Result { - pwm_file_parse::(&self.chip, self.number, "capture") + pub fn get_capture(&self) -> Result<(u32, u32)> { + let t = pwm_capture_parse::(&self.chip, self.number, "capture")?; + if t.len() == 2 { + Ok((t[0], t[1])) + } else { + Err(error::Error::Unexpected(format!("Failed exporting"))) + } } /// The active time of the PWM signal From 5a0ea58473029784c22e1d5868660dc83b09d90b Mon Sep 17 00:00:00 2001 From: Luca Vezoc Date: Thu, 4 Aug 2022 12:38:48 -0400 Subject: [PATCH 03/19] moved async functions to separate file --- Cargo.toml | 2 + src/async_pwm.rs | 161 +++++++++++++++++++++++++++++++++++++++++++++++ src/error.rs | 2 +- src/lib.rs | 1 + 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 src/async_pwm.rs diff --git a/Cargo.toml b/Cargo.toml index 615ff06..b85cab4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "sysfs-pwm" version = "0.2.0" +edition = "2021" authors = ["Rust Embedded WG Linux Team ", "Paul Osborne "] license = "MIT/Apache-2.0" @@ -15,3 +16,4 @@ See https://www.kernel.org/doc/Documentation/pwm.txt """ [dependencies] +tokio = { version = "1", features = ["full"] } \ No newline at end of file diff --git a/src/async_pwm.rs b/src/async_pwm.rs new file mode 100644 index 0000000..4a5eecf --- /dev/null +++ b/src/async_pwm.rs @@ -0,0 +1,161 @@ +use std::str::FromStr; +use tokio::fs; +use tokio::fs::File; +use tokio::io::AsyncReadExt; +use tokio::io::AsyncWriteExt; +use tokio::macros::support::Future; + +use crate::error; +use crate::Error; + +use crate::Pwm; +use crate::PwmChip; +pub type Result = ::std::result::Result; + +/// Open the specified entry name as a readable file +async fn pwm_file_ro_async(chip: &PwmChip, pin: u32, name: &str) -> Result { + let f = File::open(format!( + "/sys/class/pwm/pwmchip{}/pwm{}/{}", + chip.number, pin, name + )) + .await?; + Ok(f) +} + +/// Get the u32 value from the given entry +async fn pwm_file_parse_async(chip: &PwmChip, pin: u32, name: &str) -> Result { + let mut s = String::with_capacity(10); + let mut f = pwm_file_ro_async(chip, pin, name).await?; + f.read_to_string(&mut s).await?; + match s.trim().parse::() { + Ok(r) => Ok(r), + Err(_) => Err(Error::Unexpected(format!( + "Unexpeted value file contents: {:?}", + s + ))), + } +} + +/// Get the two u32 from capture file descriptor +async fn pwm_capture_parse_async( + chip: &PwmChip, + pin: u32, + name: &str, +) -> Result> { + let mut s = String::with_capacity(10); + let mut f = pwm_file_ro_async(chip, pin, name).await?; + f.read_to_string(&mut s).await?; + s = s.trim().to_string(); + let capture = s.split_whitespace().collect::>(); + let mut vec: Vec = vec![]; + for s in capture.iter() { + if let Ok(j) = s.parse::() { + vec.push(j); + } + } + Ok(vec) +} + +impl PwmChip { + pub async fn count_async(&self) -> Result { + let npwm_path = format!("/sys/class/pwm/pwmchip{}/npwm", self.number); + let mut npwm_file = File::open(&npwm_path).await?; + let mut s = String::new(); + npwm_file.read_to_string(&mut s).await?; + match s.parse::() { + Ok(n) => Ok(n), + Err(_) => Err(Error::Unexpected(format!( + "Unexpected npwm contents: {:?}", + s + ))), + } + } + + pub async fn export_async(&self, number: u32) -> Result<()> { + // only export if not already exported + if fs::metadata(&format!( + "/sys/class/pwm/pwmchip{}/pwm{}", + self.number, number + )) + .await + .is_err() + { + let path = format!("/sys/class/pwm/pwmchip{}/export", self.number); + let mut export_file = File::create(&path).await?; + let _ = export_file.write_all(format!("{}", number).as_bytes()); + } + Ok(()) + } + + pub async fn unexport_async(&self, number: u32) -> Result<()> { + if fs::metadata(&format!( + "/sys/class/pwm/pwmchip{}/pwm{}", + self.number, number + )) + .await + .is_ok() + { + let path = format!("/sys/class/pwm/pwmchip{}/unexport", self.number); + let mut export_file = File::create(&path).await?; + let _ = export_file.write_all(format!("{}", number).as_bytes()); + } + Ok(()) + } +} +impl Pwm { + /// Run a closure with the GPIO exported + #[inline] + pub async fn with_exported_async(&self, closure: impl Future) -> Result<()> + where + F: FnOnce() -> Result<()>, + { + self.export_async().await?; + let y = closure.await; + match y() { + Ok(()) => self.unexport_async().await, + Err(e) => match self.unexport_async().await { + Ok(()) => Err(e), + Err(ue) => Err(error::Error::Unexpected(format!( + "Failed unexporting due to:\n{}\nwhile handling:\n{}", + ue, e + ))), + }, + } + } + + /// Export the Pwm for use + pub async fn export_async(&self) -> Result<()> { + self.chip.export_async(self.number).await + } + + /// Unexport the PWM + pub async fn unexport_async(&self) -> Result<()> { + self.chip.unexport_async(self.number).await + } + + /// Query the state of enable for a given PWM pin + pub async fn get_enabled_async(&self) -> Result { + pwm_file_parse_async::(&self.chip, self.number, "enable") + .await + .map(|enable_state| match enable_state { + 1 => true, + 0 => false, + _ => panic!("enable != 1|0 should be unreachable"), + }) + } + + /// Get the capture + pub async fn get_capture_async(&self) -> Result<(u32, u32)> { + let t = pwm_capture_parse_async::(&self.chip, self.number, "capture").await?; + if t.len() == 2 { + Ok((t[0], t[1])) + } else { + Err(error::Error::Unexpected(format!("Failed exporting"))) + } + } + + /// Get the currently configured duty_cycle as percentage of period + pub async fn get_duty_cycle_async(&self) -> Result { + Ok((self.get_duty_cycle_ns()? as f32) / (self.get_period_ns()? as f32)) + } +} diff --git a/src/error.rs b/src/error.rs index ae792e6..ce34799 100644 --- a/src/error.rs +++ b/src/error.rs @@ -29,7 +29,7 @@ impl ::std::error::Error for Error { } } - fn cause(&self) -> Option<&::std::error::Error> { + fn cause(&self) -> Option<&dyn (::std::error::Error)> { match *self { Error::Io(ref e) => Some(e), _ => None, diff --git a/src/lib.rs b/src/lib.rs index 5b6f606..629ae0d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,7 @@ use std::fs::OpenOptions; use std::io::prelude::*; use std::str::FromStr; +pub mod async_pwm; mod error; pub use error::Error; From 2421fca5c7e15b7f1b48416dfa2729bb62257f91 Mon Sep 17 00:00:00 2001 From: Luca Vezoc Date: Fri, 5 Aug 2022 16:17:59 -0400 Subject: [PATCH 04/19] added missing await --- src/async_pwm.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/async_pwm.rs b/src/async_pwm.rs index 4a5eecf..543508d 100644 --- a/src/async_pwm.rs +++ b/src/async_pwm.rs @@ -82,7 +82,9 @@ impl PwmChip { { let path = format!("/sys/class/pwm/pwmchip{}/export", self.number); let mut export_file = File::create(&path).await?; - let _ = export_file.write_all(format!("{}", number).as_bytes()); + let _ = export_file + .write_all(format!("{}", number).as_bytes()) + .await; } Ok(()) } @@ -97,7 +99,9 @@ impl PwmChip { { let path = format!("/sys/class/pwm/pwmchip{}/unexport", self.number); let mut export_file = File::create(&path).await?; - let _ = export_file.write_all(format!("{}", number).as_bytes()); + let _ = export_file + .write_all(format!("{}", number).as_bytes()) + .await; } Ok(()) } From 62cbb5df0393e839ce6939b07424dccee4ca3514 Mon Sep 17 00:00:00 2001 From: Luca Vezoc Date: Mon, 8 Aug 2022 13:59:56 -0400 Subject: [PATCH 05/19] added more functions to async_pwm --- src/async_pwm.rs | 142 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 112 insertions(+), 30 deletions(-) diff --git a/src/async_pwm.rs b/src/async_pwm.rs index 543508d..0b6332c 100644 --- a/src/async_pwm.rs +++ b/src/async_pwm.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use tokio::fs; use tokio::fs::File; +use tokio::fs::OpenOptions; use tokio::io::AsyncReadExt; use tokio::io::AsyncWriteExt; use tokio::macros::support::Future; @@ -8,12 +9,31 @@ use tokio::macros::support::Future; use crate::error; use crate::Error; -use crate::Pwm; -use crate::PwmChip; -pub type Result = ::std::result::Result; +#[derive(Debug)] +pub struct PwmAsync { + chip: PwmChipAsync, + number: u32, +} + +#[derive(Debug)] +pub struct PwmChipAsync { + pub number: u32, +} + +/// Open the specified entry name as a writable file +async fn pwm_file_wo(chip: &PwmChipAsync, pin: u32, name: &str) -> Result { + let f = OpenOptions::new() + .write(true) + .open(format!( + "/sys/class/pwm/pwmchip{}/pwm{}/{}", + chip.number, pin, name + )) + .await?; + Ok(f) +} /// Open the specified entry name as a readable file -async fn pwm_file_ro_async(chip: &PwmChip, pin: u32, name: &str) -> Result { +async fn pwm_file_ro(chip: &PwmChipAsync, pin: u32, name: &str) -> Result { let f = File::open(format!( "/sys/class/pwm/pwmchip{}/pwm{}/{}", chip.number, pin, name @@ -23,9 +43,13 @@ async fn pwm_file_ro_async(chip: &PwmChip, pin: u32, name: &str) -> Result } /// Get the u32 value from the given entry -async fn pwm_file_parse_async(chip: &PwmChip, pin: u32, name: &str) -> Result { +async fn pwm_file_parse( + chip: &PwmChipAsync, + pin: u32, + name: &str, +) -> Result { let mut s = String::with_capacity(10); - let mut f = pwm_file_ro_async(chip, pin, name).await?; + let mut f = pwm_file_ro(chip, pin, name).await?; f.read_to_string(&mut s).await?; match s.trim().parse::() { Ok(r) => Ok(r), @@ -37,13 +61,13 @@ async fn pwm_file_parse_async(chip: &PwmChip, pin: u32, name: &str) } /// Get the two u32 from capture file descriptor -async fn pwm_capture_parse_async( - chip: &PwmChip, +async fn pwm_capture_parse( + chip: &PwmChipAsync, pin: u32, name: &str, -) -> Result> { +) -> Result, error::Error> { let mut s = String::with_capacity(10); - let mut f = pwm_file_ro_async(chip, pin, name).await?; + let mut f = pwm_file_ro(chip, pin, name).await?; f.read_to_string(&mut s).await?; s = s.trim().to_string(); let capture = s.split_whitespace().collect::>(); @@ -56,8 +80,13 @@ async fn pwm_capture_parse_async( Ok(vec) } -impl PwmChip { - pub async fn count_async(&self) -> Result { +impl PwmChipAsync { + pub async fn new(number: u32) -> Result { + fs::metadata(&format!("/sys/class/pwm/pwmchip{}", number)).await?; + Ok(PwmChipAsync { number: number }) + } + + pub async fn count(&self) -> Result { let npwm_path = format!("/sys/class/pwm/pwmchip{}/npwm", self.number); let mut npwm_file = File::open(&npwm_path).await?; let mut s = String::new(); @@ -71,7 +100,7 @@ impl PwmChip { } } - pub async fn export_async(&self, number: u32) -> Result<()> { + pub async fn export(&self, number: u32) -> Result<(), error::Error> { // only export if not already exported if fs::metadata(&format!( "/sys/class/pwm/pwmchip{}/pwm{}", @@ -89,7 +118,7 @@ impl PwmChip { Ok(()) } - pub async fn unexport_async(&self, number: u32) -> Result<()> { + pub async fn unexport(&self, number: u32) -> Result<(), error::Error> { if fs::metadata(&format!( "/sys/class/pwm/pwmchip{}/pwm{}", self.number, number @@ -106,18 +135,32 @@ impl PwmChip { Ok(()) } } -impl Pwm { +impl PwmAsync { + /// Create a new Pwm wiht the provided chip/number + /// + /// This function does not export the Pwm pin + pub async fn new(chip: u32, number: u32) -> Result { + let chip: PwmChipAsync = PwmChipAsync::new(chip).await?; + Ok(PwmAsync { + chip: chip, + number: number, + }) + } + /// Run a closure with the GPIO exported #[inline] - pub async fn with_exported_async(&self, closure: impl Future) -> Result<()> + pub async fn with_exported( + &self, + closure: impl Future, + ) -> Result<(), error::Error> where - F: FnOnce() -> Result<()>, + F: FnOnce() -> Result<(), error::Error>, { - self.export_async().await?; + self.export().await?; let y = closure.await; match y() { - Ok(()) => self.unexport_async().await, - Err(e) => match self.unexport_async().await { + Ok(()) => self.unexport().await, + Err(e) => match self.unexport().await { Ok(()) => Err(e), Err(ue) => Err(error::Error::Unexpected(format!( "Failed unexporting due to:\n{}\nwhile handling:\n{}", @@ -128,18 +171,18 @@ impl Pwm { } /// Export the Pwm for use - pub async fn export_async(&self) -> Result<()> { - self.chip.export_async(self.number).await + pub async fn export(&self) -> Result<(), error::Error> { + self.chip.export(self.number).await } /// Unexport the PWM - pub async fn unexport_async(&self) -> Result<()> { - self.chip.unexport_async(self.number).await + pub async fn unexport(&self) -> Result<(), error::Error> { + self.chip.unexport(self.number).await } /// Query the state of enable for a given PWM pin - pub async fn get_enabled_async(&self) -> Result { - pwm_file_parse_async::(&self.chip, self.number, "enable") + pub async fn get_enabled(&self) -> Result { + pwm_file_parse::(&self.chip, self.number, "enable") .await .map(|enable_state| match enable_state { 1 => true, @@ -149,8 +192,8 @@ impl Pwm { } /// Get the capture - pub async fn get_capture_async(&self) -> Result<(u32, u32)> { - let t = pwm_capture_parse_async::(&self.chip, self.number, "capture").await?; + pub async fn get_capture(&self) -> Result<(u32, u32), error::Error> { + let t = pwm_capture_parse::(&self.chip, self.number, "capture").await?; if t.len() == 2 { Ok((t[0], t[1])) } else { @@ -159,7 +202,46 @@ impl Pwm { } /// Get the currently configured duty_cycle as percentage of period - pub async fn get_duty_cycle_async(&self) -> Result { - Ok((self.get_duty_cycle_ns()? as f32) / (self.get_period_ns()? as f32)) + pub async fn get_duty_cycle_async(&self) -> Result { + Ok((self.get_duty_cycle_ns().await? as f32) / (self.get_period_ns().await? as f32)) + } + + /// Get the currently configured duty_cycle in nanoseconds + pub async fn get_duty_cycle_ns(&self) -> Result { + pwm_file_parse::(&self.chip, self.number, "duty_cycle").await + } + + /// Get the currently configured period in nanoseconds + pub async fn get_period_ns(&self) -> Result { + pwm_file_parse::(&self.chip, self.number, "period").await + } + + /// The period of the PWM signal in Nanoseconds + pub async fn set_period_ns(&self, period_ns: u32) -> Result<(), error::Error> { + let mut period_file = pwm_file_wo(&self.chip, self.number, "period").await?; + period_file + .write_all(format!("{}", period_ns).as_bytes()) + .await?; + Ok(()) + } + + /// The active time of the PWM signal + /// + /// Value is in nanoseconds and must be less than the period. + pub async fn set_duty_cycle_ns(&self, duty_cycle_ns: u32) -> Result<(), error::Error> { + // we'll just let the kernel do the validation + let mut duty_cycle_file = pwm_file_wo(&self.chip, self.number, "duty_cycle").await?; + duty_cycle_file + .write_all(format!("{}", duty_cycle_ns).as_bytes()) + .await?; + Ok(()) + } + + /// Enable/Disable the PWM Signal + pub async fn enable(&self, enable: bool) -> Result<(), error::Error> { + let mut enable_file = pwm_file_wo(&self.chip, self.number, "enable").await?; + let contents = if enable { "1" } else { "0" }; + enable_file.write_all(contents.as_bytes()).await?; + Ok(()) } } From 9fa6a6dcd19fda3e6b7cd9f083da0edd44b93cf1 Mon Sep 17 00:00:00 2001 From: Luca Vezoc Date: Tue, 16 Aug 2022 16:48:10 -0400 Subject: [PATCH 06/19] added sync all to functions with write all --- src/async_pwm.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/async_pwm.rs b/src/async_pwm.rs index 0b6332c..c4f72a5 100644 --- a/src/async_pwm.rs +++ b/src/async_pwm.rs @@ -114,6 +114,8 @@ impl PwmChipAsync { let _ = export_file .write_all(format!("{}", number).as_bytes()) .await; + let _ = export_file.sync_all().await; + println!("EXPORT SUCCESS"); } Ok(()) } @@ -131,6 +133,7 @@ impl PwmChipAsync { let _ = export_file .write_all(format!("{}", number).as_bytes()) .await; + let _ = export_file.sync_all().await; } Ok(()) } @@ -222,6 +225,7 @@ impl PwmAsync { period_file .write_all(format!("{}", period_ns).as_bytes()) .await?; + let _ = period_file.sync_all().await; Ok(()) } @@ -234,6 +238,7 @@ impl PwmAsync { duty_cycle_file .write_all(format!("{}", duty_cycle_ns).as_bytes()) .await?; + let _ = duty_cycle_file.sync_all().await; Ok(()) } @@ -242,6 +247,7 @@ impl PwmAsync { let mut enable_file = pwm_file_wo(&self.chip, self.number, "enable").await?; let contents = if enable { "1" } else { "0" }; enable_file.write_all(contents.as_bytes()).await?; + let _ = enable_file.sync_all().await; Ok(()) } } From f5c02fa13b9390faa02f34173372c22dfca18552 Mon Sep 17 00:00:00 2001 From: Luca Vezoc Date: Tue, 16 Aug 2022 16:48:24 -0400 Subject: [PATCH 07/19] added sync all to functions with write all --- src/async_pwm.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/async_pwm.rs b/src/async_pwm.rs index c4f72a5..345c61d 100644 --- a/src/async_pwm.rs +++ b/src/async_pwm.rs @@ -115,7 +115,6 @@ impl PwmChipAsync { .write_all(format!("{}", number).as_bytes()) .await; let _ = export_file.sync_all().await; - println!("EXPORT SUCCESS"); } Ok(()) } From 613ca499802b61b7462e823663d4a412dd6517e7 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Tue, 5 Jul 2022 07:40:57 +0200 Subject: [PATCH 08/19] Some trivial simplifications --- src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 629ae0d..fcd7e01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,7 +91,7 @@ fn pwm_capture_parse(chip: &PwmChip, pin: u32, name: &str) -> Result impl PwmChip { pub fn new(number: u32) -> Result { fs::metadata(&format!("/sys/class/pwm/pwmchip{}", number))?; - Ok(PwmChip { number: number }) + Ok(PwmChip { number }) } pub fn count(&self) -> Result { @@ -144,10 +144,7 @@ impl Pwm { /// This function does not export the Pwm pin pub fn new(chip: u32, number: u32) -> Result { let chip: PwmChip = PwmChip::new(chip)?; - Ok(Pwm { - chip: chip, - number: number, - }) + Ok(Pwm { chip, number }) } /// Run a closure with the GPIO exported From a1c9a960fb1ada5c20836e867211b73e207f5713 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Tue, 5 Jul 2022 07:41:40 +0200 Subject: [PATCH 09/19] Remove implementation of deprecated Error::description function --- src/error.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/error.rs b/src/error.rs index ce34799..b11cbd1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -22,13 +22,6 @@ pub enum Error { } impl ::std::error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::Io(ref e) => e.description(), - Error::Unexpected(_) => "something unexpected", - } - } - fn cause(&self) -> Option<&dyn (::std::error::Error)> { match *self { Error::Io(ref e) => Some(e), From f3ea21a3c778b50b213a391c3dcb604496d67bb3 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Tue, 5 Jul 2022 07:46:37 +0200 Subject: [PATCH 10/19] Update URLs --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b85cab4..b2669d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,8 @@ edition = "2021" authors = ["Rust Embedded WG Linux Team ", "Paul Osborne "] license = "MIT/Apache-2.0" -homepage = "https://github.com/posborne/rust-sysfs-pwm" -documentation = "https://posborne.github.io/rust-sysfs-pwm" +homepage = "https://github.com/rust-embedded/rust-sysfs-pwm" +documentation = "https://docs.rs/rust-sysfs-pwm" description = """ Provides access to the Linux sysfs interfaces to PWMs. Via this crate you can export, unexport, and control PWM pins for From cc21cdb7c5e2c4a8903827a66bd8285e4a0a6711 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Tue, 5 Jul 2022 07:48:32 +0200 Subject: [PATCH 11/19] Improve metadata --- Cargo.toml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b2669d4..4dcc031 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,14 @@ [package] name = "sysfs-pwm" version = "0.2.0" -edition = "2021" -authors = ["Rust Embedded WG Linux Team ", - "Paul Osborne "] +authors = [ + "Rust Embedded WG Linux Team ", + "Paul Osborne " +] license = "MIT/Apache-2.0" +repository = "https://github.com/rust-embedded/rust-sysfs-pwm" homepage = "https://github.com/rust-embedded/rust-sysfs-pwm" -documentation = "https://docs.rs/rust-sysfs-pwm" +documentation = "https://docs.rs/sysfs-pwm" description = """ Provides access to the Linux sysfs interfaces to PWMs. Via this crate you can export, unexport, and control PWM pins for @@ -14,6 +16,7 @@ which there is an appropriate driver loaded in the kernel. See https://www.kernel.org/doc/Documentation/pwm.txt """ +readme = "README.md" [dependencies] tokio = { version = "1", features = ["full"] } \ No newline at end of file From 48272620acda8313abaf88f5a1a725a497245ea8 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Tue, 5 Jul 2022 07:52:13 +0200 Subject: [PATCH 12/19] Update readme --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ca085ed..74e089d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -# rust-sysfs-pwm +# sysfs-pwm -[![Build Status](https://travis-ci.org/rust-embedded/rust-sysfs-pwm.svg?branch=master)](https://travis-ci.org/rust-embedded/rust-sysfs-pwm) +[![Build Status](https://github.com/rust-embedded/rust-sysfs-pwm/workflows/CI/badge.svg)](https://github.com/rust-embedded/rust-sysfs-pwm/actions) [![Version](https://img.shields.io/crates/v/sysfs-pwm.svg)](https://crates.io/crates/sysfs-pwm) +![Minimum Supported Rust Version](https://img.shields.io/badge/rustc-1.28+-blue.svg) [![License](https://img.shields.io/crates/l/sysfs-pwm.svg)](README.md#license) - [API Documentation](https://docs.rs/sysfs-pwm) @@ -17,13 +18,13 @@ To use `sysfs-pwm`, first add this to your `Cargo.toml`: ```toml [dependencies] # or latest version -sysfs-pwm = "^0.1.0" +sysfs-pwm = "0.2.0" ``` Then, add this to your crate root: ```rust -extern crate sysfs_pwm; +use sysfs_pwm; ``` ## MSRV (Minimum Supported Rust Version) @@ -54,7 +55,7 @@ machine (although it could be). In those cases, you will need to cross-compile. The [instructions here][rust-cross] provide great details on cross compiling for your platform. -[rust-cross]: https://github.com/japaric/rust-cross +[rust-cross]: https://github.com/cross-rs/cross ## Running the Example From 0e2754050447c1ab9b023b8fc9fd0a1862dcb38e Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Tue, 5 Jul 2022 07:58:31 +0200 Subject: [PATCH 13/19] Add CI --- .github/CODEOWNERS | 1 + .github/bors.toml | 31 ++++++++ .github/workflows/ci.yml | 157 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/bors.toml create mode 100644 .github/workflows/ci.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..2f02147 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* rust-embedded/embedded-linux diff --git a/.github/bors.toml b/.github/bors.toml new file mode 100644 index 0000000..7f34491 --- /dev/null +++ b/.github/bors.toml @@ -0,0 +1,31 @@ +block_labels = ["needs-decision"] +delete_merged_branches = true +required_approvals = 1 +status = [ + "CI (stable, aarch64-unknown-linux-gnu)", + "CI (stable, arm-unknown-linux-gnueabi)", + "CI (stable, armv7-unknown-linux-gnueabihf)", + "CI (stable, i686-unknown-linux-gnu)", + "CI (stable, i686-unknown-linux-musl)", + "CI (stable, mips-unknown-linux-gnu)", + "CI (stable, mips64-unknown-linux-gnuabi64)", + "CI (stable, mips64el-unknown-linux-gnuabi64)", + "CI (stable, mipsel-unknown-linux-gnu)", + "CI (stable, powerpc-unknown-linux-gnu)", + "CI (stable, powerpc64le-unknown-linux-gnu)", + "CI (stable, s390x-unknown-linux-gnu)", + "CI (stable, x86_64-unknown-linux-gnu)", + "CI (stable, x86_64-unknown-linux-musl)", + "CI (stable, x86_64-apple-darwin)", + + "CI (stable, --features=async-tokio, x86_64-unknown-linux-gnu)", + "CI (stable, --features=mio-evented, x86_64-unknown-linux-gnu)", + + "CI (1.46.0, --features=async-tokio, x86_64-unknown-linux-gnu)", + "CI (1.46.0, --features=mio-evented, x86_64-unknown-linux-gnu)", + "CI (1.46.0, x86_64-unknown-linux-gnu)", + "CI (1.46.0, x86_64-apple-darwin)", + + "checks" +] +timeout_sec = 3600 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c90a703 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,157 @@ +on: + push: + branches: [ staging, trying, master ] + pull_request: + +name: CI + +env: + RUSTFLAGS: '--deny warnings' + +jobs: + ci-linux: + name: CI + runs-on: ubuntu-latest + strategy: + matrix: + rust: [stable] + TARGET: + - aarch64-unknown-linux-gnu + - arm-unknown-linux-gnueabi + - armv7-unknown-linux-gnueabihf + - i686-unknown-linux-gnu + - i686-unknown-linux-musl + - mips-unknown-linux-gnu + - mips64-unknown-linux-gnuabi64 + - mips64el-unknown-linux-gnuabi64 + - mipsel-unknown-linux-gnu + - powerpc-unknown-linux-gnu + # - powerpc64-unknown-linux-gnu + - powerpc64le-unknown-linux-gnu + - s390x-unknown-linux-gnu + - x86_64-unknown-linux-gnu + - x86_64-unknown-linux-musl + + include: + - rust: 1.28.0 + TARGET: x86_64-unknown-linux-gnu + + # Test nightly but don't fail + - rust: nightly + TARGET: x86_64-unknown-linux-gnu + experimental: true + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.TARGET }} + override: true + + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --target=${{ matrix.TARGET }} + + - name: Test + uses: actions-rs/cargo@v1 + with: + use-cross: true + command: test + args: --target=${{ matrix.TARGET }} + + ci-linux-msrv: + name: CI + runs-on: ubuntu-latest + strategy: + matrix: + rust: [1.28.0] + TARGET: + - x86_64-unknown-linux-gnu + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.TARGET }} + override: true + + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --target=${{ matrix.TARGET }} + + - name: Test + uses: actions-rs/cargo@v1 + with: + use-cross: true + command: test + args: --target=${{ matrix.TARGET }} + + ci-macos: + name: CI + runs-on: macos-11 + + strategy: + matrix: + rust: [stable, 1.28.0] + TARGET: [x86_64-apple-darwin] + + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.TARGET }} + override: true + + - uses: actions-rs/cargo@v1 + with: + command: build + args: --target=${{ matrix.TARGET }} + + checks: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + components: rustfmt + + - name: Doc + uses: actions-rs/cargo@v1 + with: + command: doc + + - name: Formatting + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + runs-on: ubuntu-latest + env: + RUSTFLAGS: '--allow warnings' + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: 1.62.0 + components: clippy + + - uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} From af5d6bb966f7494c4adb0a3eddadf006cc2ccd18 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Tue, 5 Jul 2022 07:59:04 +0200 Subject: [PATCH 14/19] Remove Travis CI --- .travis.yml | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a5ab080..0000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: rust -rust: - - 1.28.0 - - stable - - beta - - nightly - -script: - - cargo build --verbose - - cargo test --verbose - - cargo doc - -# Use Travis container-based system (much faster to start up) -sudo: false From 5dca9a26be7d01f035bf93faa894c1cfb3a5ebed Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Fri, 8 Jul 2022 08:15:21 +0200 Subject: [PATCH 15/19] Fix .github/CODEOWNERS Co-authored-by: Ryan --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2f02147..3024413 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* rust-embedded/embedded-linux +* @rust-embedded/embedded-linux From 0bf20f78d3966294a004bff9d1a8e11a5dbe9643 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Fri, 8 Jul 2022 08:54:43 +0200 Subject: [PATCH 16/19] Fix bors --- .github/bors.toml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/bors.toml b/.github/bors.toml index 7f34491..16dd274 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -18,13 +18,8 @@ status = [ "CI (stable, x86_64-unknown-linux-musl)", "CI (stable, x86_64-apple-darwin)", - "CI (stable, --features=async-tokio, x86_64-unknown-linux-gnu)", - "CI (stable, --features=mio-evented, x86_64-unknown-linux-gnu)", - - "CI (1.46.0, --features=async-tokio, x86_64-unknown-linux-gnu)", - "CI (1.46.0, --features=mio-evented, x86_64-unknown-linux-gnu)", - "CI (1.46.0, x86_64-unknown-linux-gnu)", - "CI (1.46.0, x86_64-apple-darwin)", + "CI (1.28.0, x86_64-unknown-linux-gnu)", + "CI (1.28.0, x86_64-apple-darwin)", "checks" ] From e67f6ae23b1fcac740c594a0282abe25edb14b5c Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Fri, 30 Jun 2023 18:28:10 +0200 Subject: [PATCH 17/19] Switch to GHMQ --- .github/bors.toml | 26 -------------------------- .github/workflows/ci.yml | 8 +++++--- 2 files changed, 5 insertions(+), 29 deletions(-) delete mode 100644 .github/bors.toml diff --git a/.github/bors.toml b/.github/bors.toml deleted file mode 100644 index 16dd274..0000000 --- a/.github/bors.toml +++ /dev/null @@ -1,26 +0,0 @@ -block_labels = ["needs-decision"] -delete_merged_branches = true -required_approvals = 1 -status = [ - "CI (stable, aarch64-unknown-linux-gnu)", - "CI (stable, arm-unknown-linux-gnueabi)", - "CI (stable, armv7-unknown-linux-gnueabihf)", - "CI (stable, i686-unknown-linux-gnu)", - "CI (stable, i686-unknown-linux-musl)", - "CI (stable, mips-unknown-linux-gnu)", - "CI (stable, mips64-unknown-linux-gnuabi64)", - "CI (stable, mips64el-unknown-linux-gnuabi64)", - "CI (stable, mipsel-unknown-linux-gnu)", - "CI (stable, powerpc-unknown-linux-gnu)", - "CI (stable, powerpc64le-unknown-linux-gnu)", - "CI (stable, s390x-unknown-linux-gnu)", - "CI (stable, x86_64-unknown-linux-gnu)", - "CI (stable, x86_64-unknown-linux-musl)", - "CI (stable, x86_64-apple-darwin)", - - "CI (1.28.0, x86_64-unknown-linux-gnu)", - "CI (1.28.0, x86_64-apple-darwin)", - - "checks" -] -timeout_sec = 3600 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c90a703..ee78978 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,9 @@ on: - push: - branches: [ staging, trying, master ] - pull_request: + push: # Run CI for all branches except GitHub merge queue tmp branches + branches-ignore: + - "gh-readonly-queue/**" + pull_request: # Run CI for PRs on any branch + merge_group: # Run CI for the GitHub merge queue name: CI From f78a342d5de01f2e3ca8592470ac5632b8d676da Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 5 Jan 2024 13:43:04 -0500 Subject: [PATCH 18/19] edition 2021 --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 4dcc031..8e9db2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "sysfs-pwm" version = "0.2.0" +edition = "2021" authors = [ "Rust Embedded WG Linux Team ", "Paul Osborne " From 6e8bd12a37e4a29b2b7d6536e3493428169ff42f Mon Sep 17 00:00:00 2001 From: Luca Date: Tue, 9 Jan 2024 09:29:29 -0500 Subject: [PATCH 19/19] use only necessary tokio features --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8e9db2b..28e5997 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,4 @@ See https://www.kernel.org/doc/Documentation/pwm.txt readme = "README.md" [dependencies] -tokio = { version = "1", features = ["full"] } \ No newline at end of file +tokio = { version = "1", features = ["io-util", "fs"] } \ No newline at end of file