Make examples less dependent on embedded-hal where able (#1342)

* Add support for building a package without its default features to `xtask`

* Do not require `embedded_hal_02` traits in examples where they are not required

* Do not require `embedded_hal_02` traits for filling a buffer with random bytes
This commit is contained in:
Jesse Braham 2024-03-25 13:14:22 +00:00 committed by GitHub
parent 8da8425907
commit ace679f13b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 92 additions and 120 deletions

View File

@ -63,8 +63,6 @@
//! rng.read(&mut buffer).unwrap();
//! ```
#[cfg(feature = "embedded-hal-02")]
use core::convert::Infallible;
use core::marker::PhantomData;
use crate::{peripheral::Peripheral, peripherals::RNG};
@ -95,48 +93,53 @@ impl Rng {
.read()
.bits()
}
}
#[cfg(feature = "embedded-hal-02")]
impl embedded_hal_02::blocking::rng::Read for Rng {
type Error = Infallible;
fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> {
#[inline]
/// Reads enough bytes from hardware random number generator to fill
/// `buffer`.
///
/// If any error is encountered then this function immediately returns. The
/// contents of buf are unspecified in this case.
///
/// If this function returns an error, it is unspecified how many bytes it
/// has read, but it will never read more than would be necessary to
/// completely fill the buffer.
pub fn read(&mut self, buffer: &mut [u8]) {
for chunk in buffer.chunks_mut(4) {
let bytes = self.random().to_le_bytes();
chunk.copy_from_slice(&bytes[..chunk.len()]);
}
}
}
#[cfg(feature = "embedded-hal-02")]
impl embedded_hal_02::blocking::rng::Read for Rng {
type Error = core::convert::Infallible;
fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.read(buffer);
Ok(())
}
}
impl rand_core::RngCore for Rng {
fn next_u32(&mut self) -> u32 {
// Directly use the existing random method to get a u32 random number
self.random()
}
fn next_u64(&mut self) -> u64 {
// Call random() twice to generate a u64 random number (сombine two u32)
let upper = self.random() as u64;
let lower = self.random() as u64;
(upper << 32) | lower
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
// Fill the destination buffer with random bytes
for chunk in dest.chunks_mut(4) {
let rand_bytes = self.random().to_le_bytes();
for (dest_byte, rand_byte) in chunk.iter_mut().zip(&rand_bytes) {
*dest_byte = *rand_byte;
}
}
self.read(dest);
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
// Similar implementation as fill_bytes, but encapsulated in a Result
self.fill_bytes(dest);
self.read(dest);
Ok(())
}
}

View File

@ -1,24 +1,21 @@
//! This shows example usage of the CRC functions in ROM
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
use core::fmt::Write;
use embedded_hal_02::timer::CountDown;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
delay::Delay,
peripherals::Peripherals,
prelude::*,
rom::{crc, md5},
timer::TimerGroup,
uart::Uart,
};
use nb::block;
#[entry]
fn main() -> ! {
@ -26,9 +23,7 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timg0.timer0;
timer0.start(1u64.secs());
let delay = Delay::new(&clocks);
let mut uart0 = Uart::new(peripherals.UART0, &clocks);
@ -95,6 +90,6 @@ fn main() -> ! {
)
.unwrap();
block!(timer0.wait()).unwrap();
delay.delay(1.secs());
}
}

View File

@ -2,7 +2,6 @@
//! hardware-accelerated and pure software ECC.
//% CHIPS: esp32c2 esp32c6 esp32h2
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
@ -16,10 +15,11 @@ use crypto_bigint::{
U256,
};
use elliptic_curve::sec1::ToEncodedPoint;
use embedded_hal_02::blocking::rng::Read;
use esp_backtrace as _;
#[cfg(feature = "esp32h2")]
use esp_hal::ecc::WorkMode;
use esp_hal::{
ecc::{Ecc, EllipticCurve, Error, WorkMode},
ecc::{Ecc, EllipticCurve, Error},
peripherals::Peripherals,
prelude::*,
rng::Rng,
@ -89,7 +89,7 @@ fn test_affine_point_multiplication(ecc: &mut Ecc, rng: &mut Rng) {
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
rng.read(k);
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
@ -202,7 +202,7 @@ fn test_affine_point_verification(ecc: &mut Ecc, rng: &mut Rng) {
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
rng.read(k);
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
@ -278,7 +278,7 @@ fn test_afine_point_verification_multiplication(ecc: &mut Ecc, rng: &mut Rng) {
let qz = &mut [0u8; 8];
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
rng.read(k);
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
@ -407,7 +407,7 @@ fn test_jacobian_point_multiplication(ecc: &mut Ecc, rng: &mut Rng) {
let (sw_k, _) = sw_k.split_at_mut(prime_field.len());
loop {
rng.read(k).unwrap();
rng.read(k);
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
@ -535,8 +535,8 @@ fn test_jacobian_point_verification(ecc: &mut Ecc, rng: &mut Rng) {
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_mul {
loop {
rng.read(k).unwrap();
rng.read(z).unwrap();
rng.read(k);
rng.read(z);
let is_zero = k.iter().all(|&elt| elt == 0) || z.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b)
|| z.iter().zip(prime_field).all(|(&a, &b)| a == b);
@ -629,7 +629,7 @@ fn test_afine_point_verification_jacobian_multiplication(ecc: &mut Ecc, rng: &mu
let (sw_k, _) = sw_k.split_at_mut(prime_field.len());
loop {
rng.read(k).unwrap();
rng.read(k);
let is_zero = k.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b);
if is_zero == false && is_modulus == false {
@ -763,8 +763,8 @@ fn test_finite_field_division(ecc: &mut Ecc, rng: &mut Rng) {
let mut delta_time = 0;
for _ in 0..TEST_PARAMS_VECTOR.nb_loop_inv {
loop {
rng.read(k).unwrap();
rng.read(y).unwrap();
rng.read(k);
rng.read(y);
let is_zero = k.iter().all(|&elt| elt == 0) || y.iter().all(|&elt| elt == 0);
let is_modulus = k.iter().zip(prime_field).all(|(&a, &b)| a == b)
|| y.iter().zip(prime_field).all(|(&a, &b)| a == b);

View File

@ -1,29 +1,27 @@
//! This shows how to write text to UART0.
//!
//! You can see the output with `espflash` if you provide the `--monitor`
//! option. Depending on the chip, you will need to ensure that you are
//! connected to the UART USB port, and not the USB-SERIAL-JTAG port.
//! If you want to test printing over USB-SERIAL-JTAG, try the usb_serial_jtag
//! example instead.
//! option.
//!
//! Depending on the chip, you will need to ensure that you are connected to
//! the UART USB port, and not the USB-SERIAL-JTAG port. If you want to test
//! printing over USB-SERIAL-JTAG, try the usb_serial_jtag example instead.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
use core::fmt::Write;
use embedded_hal_02::timer::CountDown;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
delay::Delay,
peripherals::Peripherals,
prelude::*,
timer::TimerGroup,
uart::Uart,
};
use nb::block;
#[entry]
fn main() -> ! {
@ -31,14 +29,12 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timg0.timer0;
timer0.start(1u64.secs());
let delay = Delay::new(&clocks);
let mut uart0 = Uart::new(peripherals.UART0, &clocks);
loop {
writeln!(uart0, "Hello world!").unwrap();
block!(timer0.wait()).unwrap();
delay.delay(1.secs());
}
}

View File

@ -53,12 +53,10 @@
//! ```
//% CHIPS: esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
use embedded_hal_02::blocking::rng::Read;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
@ -89,7 +87,7 @@ fn main() -> ! {
let mut hw_hmac = Hmac::new(peripherals.HMAC);
let mut src = [0_u8; 1024];
rng.read(src.as_mut_slice()).unwrap();
rng.read(src.as_mut_slice());
// println!("HMAC input {:02X?}", src);
let mut output = [0u8; 32];

View File

@ -22,17 +22,15 @@ use embedded_graphics::{
prelude::*,
text::{Alignment, Text},
};
use embedded_hal_02::timer::CountDown;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
delay::Delay,
gpio::IO,
i2c::I2C,
peripherals::Peripherals,
prelude::*,
timer::TimerGroup,
};
use nb::block;
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
#[entry]
@ -41,9 +39,7 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timer_group0.timer0;
let delay = Delay::new(&clocks);
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
// Create a new peripheral object with the described wiring
@ -56,9 +52,6 @@ fn main() -> ! {
&clocks,
);
// Start timer (5 second interval)
timer0.start(5u64.secs());
// Initialize display
let interface = I2CDisplayInterface::new(i2c);
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
@ -102,7 +95,7 @@ fn main() -> ! {
display.clear(BinaryColor::Off).unwrap();
// Wait 5 seconds
block!(timer0.wait()).unwrap();
delay.delay(5.secs());
// Write single-line centered text "Hello World" to buffer
Text::with_alignment(
@ -120,6 +113,6 @@ fn main() -> ! {
display.clear(BinaryColor::Off).unwrap();
// Wait 5 seconds
block!(timer0.wait()).unwrap();
delay.delay(5.secs());
}
}

View File

@ -4,7 +4,6 @@
//! second core.
//% CHIPS: esp32 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
@ -12,17 +11,15 @@
use core::cell::RefCell;
use critical_section::Mutex;
use embedded_hal_02::timer::CountDown;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
cpu_control::{CpuControl, Stack},
delay::Delay,
peripherals::Peripherals,
prelude::*,
timer::TimerGroup,
};
use esp_println::println;
use nb::block;
static mut APP_CORE_STACK: Stack<8192> = Stack::new();
@ -32,14 +29,7 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timg0.timer0;
let timg1 = TimerGroup::new(peripherals.TIMG1, &clocks);
let mut timer1 = timg1.timer0;
timer0.start(1u64.secs());
timer1.start(500u64.millis());
let delay = Delay::new(&clocks);
let counter = Mutex::new(RefCell::new(0u32));
@ -48,7 +38,7 @@ fn main() -> ! {
.start_app_core(unsafe { &mut APP_CORE_STACK }, || {
println!("Hello World - Core 1!");
loop {
block!(timer1.wait()).unwrap();
delay.delay(500.millis());
critical_section::with(|cs| {
let mut val = counter.borrow_ref_mut(cs);
*val = val.wrapping_add(1);
@ -58,7 +48,7 @@ fn main() -> ! {
.unwrap();
loop {
block!(timer0.wait()).unwrap();
delay.delay(1.secs());
let count = critical_section::with(|cs| *counter.borrow_ref(cs));
println!("Hello World - Core 0! Counter is {}", count);

View File

@ -12,23 +12,20 @@
//! We can also run code from RTC memory.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
use embedded_hal_02::timer::CountDown;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
delay::Delay,
macros::ram,
peripherals::Peripherals,
prelude::*,
rtc_cntl::Rtc,
timer::TimerGroup,
};
use esp_println::println;
use nb::block;
#[ram(rtc_fast)]
static mut SOME_INITED_DATA: [u8; 2] = [0xaa, 0xbb];
@ -45,16 +42,13 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timg0.timer0;
let delay = Delay::new(&clocks);
// The RWDT flash boot protection must be enabled, as it is triggered as part of
// the example.
let mut rtc = Rtc::new(peripherals.LPWR);
rtc.rwdt.enable();
timer0.start(1u64.secs());
println!(
"IRAM function located at {:p}",
function_in_ram as *const ()
@ -92,7 +86,7 @@ fn main() -> ! {
loop {
function_in_ram();
block!(timer0.wait()).unwrap();
delay.delay(1.secs());
}
}

View File

@ -1,12 +1,10 @@
//! Demonstrates the use of the hardware Random Number Generator (RNG)
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
use embedded_hal_02::blocking::rng::Read;
use esp_backtrace as _;
use esp_hal::{peripherals::Peripherals, prelude::*, rng::Rng};
use esp_println::println;
@ -21,7 +19,7 @@ fn main() -> ! {
// Fill a buffer with random bytes:
let mut buf = [0u8; 16];
rng.read(&mut buf).unwrap();
rng.read(&mut buf);
println!("Random bytes: {:?}", buf);
loop {}

View File

@ -11,18 +11,17 @@
use core::{cell::RefCell, fmt::Write};
use critical_section::Mutex;
use embedded_hal_02::{serial::Read, timer::CountDown};
use embedded_hal_02::serial::Read;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
delay::Delay,
interrupt::{self, Priority},
peripherals::{Interrupt, Peripherals, UART0},
prelude::*,
timer::TimerGroup,
uart::{config::AtCmdConfig, Uart},
Blocking,
};
use nb::block;
static SERIAL: Mutex<RefCell<Option<Uart<UART0, Blocking>>>> = Mutex::new(RefCell::new(None));
@ -32,8 +31,7 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timg0.timer0;
let delay = Delay::new(&clocks);
let mut uart0 = Uart::new(peripherals.UART0, &clocks);
uart0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None));
@ -43,8 +41,6 @@ fn main() -> ! {
interrupt::enable(Interrupt::UART0, Priority::Priority2).unwrap();
timer0.start(1u64.secs());
critical_section::with(|cs| SERIAL.borrow_ref_mut(cs).replace(uart0));
loop {
@ -54,7 +50,7 @@ fn main() -> ! {
writeln!(serial, "Hello World! Send a single `#` character or send at least 30 characters and see the interrupts trigger.").ok();
});
block!(timer0.wait()).unwrap();
delay.delay(1.secs());
}
}

View File

@ -4,7 +4,6 @@
//! Most dev-kits use a USB-UART-bridge - in that case you won't see any output.
//% CHIPS: esp32c3 esp32c6 esp32h2 esp32s3
//% FEATURES: embedded-hal-02
#![no_std]
#![no_main]
@ -12,17 +11,15 @@
use core::{cell::RefCell, fmt::Write};
use critical_section::Mutex;
use embedded_hal_02::timer::CountDown;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
delay::Delay,
interrupt::{self, Priority},
peripherals::{Interrupt, Peripherals},
prelude::*,
timer::TimerGroup,
usb_serial_jtag::UsbSerialJtag,
};
use nb::block;
static USB_SERIAL: Mutex<RefCell<Option<UsbSerialJtag>>> = Mutex::new(RefCell::new(None));
@ -32,10 +29,7 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timg0.timer0;
timer0.start(1.secs());
let delay = Delay::new(&clocks);
let mut usb_serial = UsbSerialJtag::new(peripherals.USB_DEVICE);
usb_serial.listen_rx_packet_recv_interrupt();
@ -52,7 +46,7 @@ fn main() -> ! {
.ok();
});
block!(timer0.wait()).unwrap();
delay.delay(1.secs());
}
}

View File

@ -9,14 +9,16 @@
#![no_std]
#![no_main]
use embedded_hal_02::{
timer::CountDown,
watchdog::{Watchdog, WatchdogEnable},
};
use embedded_hal_02::watchdog::{Watchdog, WatchdogEnable};
use esp_backtrace as _;
use esp_hal::{clock::ClockControl, peripherals::Peripherals, prelude::*, timer::TimerGroup};
use esp_hal::{
clock::ClockControl,
delay::Delay,
peripherals::Peripherals,
prelude::*,
timer::TimerGroup,
};
use esp_println::println;
use nb::block;
#[entry]
fn main() -> ! {
@ -24,16 +26,15 @@ fn main() -> ! {
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timg0.timer0;
let mut wdt0 = timg0.wdt;
let delay = Delay::new(&clocks);
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut wdt0 = timg0.wdt;
wdt0.start(2u64.secs());
timer0.start(1u64.secs());
loop {
wdt0.feed();
println!("Hello world!");
block!(timer0.wait()).unwrap();
delay.delay(1.secs());
}
}

View File

@ -334,6 +334,7 @@ pub fn run_example(
pub fn build_package(
package_path: &Path,
features: Vec<String>,
no_default_features: bool,
toolchain: Option<String>,
target: Option<String>,
) -> Result<()> {
@ -362,6 +363,10 @@ pub fn build_package(
builder = builder.features(&features);
}
if no_default_features {
builder = builder.arg("--no-default-features");
}
let args = builder.build();
log::debug!("{args:#?}");

View File

@ -64,6 +64,9 @@ struct BuildPackageArgs {
/// Toolchain to build with.
#[arg(long)]
toolchain: Option<String>,
/// Don't enabled the default features.
#[arg(long)]
no_default_features: bool,
}
#[derive(Debug, Args)]
@ -233,7 +236,13 @@ fn build_package(workspace: &Path, args: BuildPackageArgs) -> Result<()> {
let package_path = xtask::windows_safe_path(&workspace.join(args.package.to_string()));
// Build the package using the provided features and/or target, if any:
xtask::build_package(&package_path, args.features, args.toolchain, args.target)
xtask::build_package(
&package_path,
args.features,
args.no_default_features,
args.toolchain,
args.target,
)
}
fn bump_version(workspace: &Path, args: BumpVersionArgs) -> Result<()> {