diff --git a/Cargo.lock b/Cargo.lock index 443fe9d..c2ae476 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,13 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "linux_realtime" +version = "0.1.0" +dependencies = [ + "libc", +] + [[package]] name = "nix" version = "0.28.0" @@ -54,6 +61,7 @@ version = "0.1.0" dependencies = [ "interrupts", "libc", + "linux_realtime", "rppal", ] diff --git a/Cargo.toml b/Cargo.toml index 09f9697..6df969c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,6 @@ rppal = "0.17.1" #rumqttc = "0.24.0" interrupts = "0.1.5" libc = "0.2.153" + +[dependencies.linux_realtime] +path = "../linux_realtime" diff --git a/src/dht11.rs b/src/dht11.rs index 7d021ff..5e4edde 100644 --- a/src/dht11.rs +++ b/src/dht11.rs @@ -1,8 +1,4 @@ -use std::{ - error::Error, - thread, - time::{Duration, Instant}, -}; +use std::{error::Error, time::Duration}; use rppal::gpio::Gpio; @@ -19,45 +15,47 @@ impl Dht11Sensor { Ok(Dht11Sensor { pin }) } - fn expect_pulse(&mut self, expected_level: bool) -> Result> { - let started = Instant::now(); + fn expect_pulse(&mut self, expected_level: bool) -> Result> { + let _guard = interrupts::disable(); + let mut count: u32 = 0; + let mut rtclock = linux_realtime::Clock::new()?; loop { if self.pin.is_high() != expected_level { break; } - if started.elapsed() >= Duration::from_micros(1000) { + if count >= 1000 { return Err(std::io::Error::new( std::io::ErrorKind::InvalidData, "Timeout while reading pulse", ) .into()); } - - thread::sleep(Duration::from_micros(1)); + count += 1; + rtclock.sleep(Duration::from_micros(1))?; } - Ok(started.elapsed()) + Ok(count) } pub fn read(&mut self) -> Result> { use rppal::gpio::{Bias, Mode}; let mut data = [0; 5]; - let mut cycles: [Duration; 80] = [Duration::from_micros(0); 80]; + let mut cycles: [u32; 80] = [0; 80]; - let guard = interrupts::disable(); + let mut rtclock = linux_realtime::Clock::new()?; self.pin.set_mode(Mode::Input); self.pin.set_bias(Bias::PullUp); - thread::sleep(Duration::from_millis(1)); + rtclock.sleep(Duration::from_millis(1))?; self.pin.set_mode(Mode::Output); self.pin.set_low(); - thread::sleep(Duration::from_millis(20)); + rtclock.sleep(Duration::from_millis(20))?; // Timing Critical Code self.pin.set_mode(Mode::Input); self.pin.set_bias(Bias::PullUp); - thread::sleep(Duration::from_micros(55)); + rtclock.sleep(Duration::from_micros(55))?; self.expect_pulse(false)?; self.expect_pulse(true)?; diff --git a/src/main.rs b/src/main.rs index 833e429..d057be8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,24 +1,35 @@ -use std::{error::Error, thread, time::Duration}; +use std::{error::Error, time::Duration}; use dht11::Dht11Sensor; +use linux_realtime::ThreadAttributes; mod dht11; fn main() -> Result<(), Box> { - unsafe { - libc::setpriority(libc::PRIO_PROCESS, 0, -20); - } let mut sensor = Dht11Sensor::new(2)?; - loop { - match sensor.read() { - Ok(data) => println!( - "Humidity: {}; Temperature: {}", - data.humidity, data.temperature - ), - Err(msg) => println!("Error: {}", msg), - } - thread::sleep(Duration::from_millis(2000)); - } + let t = linux_realtime::JoinHandle::spawn( + ThreadAttributes { + stack_size: libc::PTHREAD_STACK_MIN, + scheduler_policy: linux_realtime::SchedulerPolicy::Fifo, + thread_priority: 99, + }, + move || -> Result<(), Box> { + loop { + let mut rtclock = linux_realtime::Clock::new()?; + match sensor.read() { + Ok(data) => println!( + "Humidity: {}; Temperature: {}", + data.humidity, data.temperature + ), + Err(msg) => println!("Error: {}", msg), + } + for n in 1..10 { + rtclock.sleep(Duration::from_millis(500))?; + } + } + }, + )?; + _ = t.join(); Ok(()) }