fix: small bugfixes and adding n_times c functions
This commit is contained in:
parent
55a1ff9445
commit
63c45edba1
11 changed files with 186 additions and 37 deletions
|
@ -1,4 +1,5 @@
|
|||
#include "crc32.h"
|
||||
#include <stdint.h>
|
||||
|
||||
const uint32_t CRC32_INIT = 0xffffffff;
|
||||
const uint32_t CRC32_TABLE[256] = {
|
||||
|
@ -68,3 +69,12 @@ ChecksumCrc32 crc32_checksum(const uint8_t *data, uint32_t len) {
|
|||
crc32_process(data, len, &crc32);
|
||||
return crc32.buf;
|
||||
}
|
||||
|
||||
ChecksumCrc32 crc32_checksum_n_times(uint32_t n, const uint8_t *data,
|
||||
uint32_t len) {
|
||||
ChecksumCrc32 buf;
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
buf = crc32_checksum(data, len);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -19,5 +19,7 @@ Crc32 crc32_new();
|
|||
void crc32_process(const uint8_t *data, size_t len, Crc32 *crc32);
|
||||
|
||||
ChecksumCrc32 crc32_checksum(const uint8_t *data, uint32_t len);
|
||||
ChecksumCrc32 crc32_checksum_n_times(uint32_t n, const uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
#endif // CRC32_H
|
||||
|
|
|
@ -411,3 +411,11 @@ SHA2Result sha2_256_oneshot(const uint8_t data[], const size_t len,
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
void sha2_256_oneshot_n_times(uint32_t n, const uint8_t data[],
|
||||
const size_t len) {
|
||||
SHA2Digest digest;
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
sha2_256_oneshot(data, len, digest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,5 +49,7 @@ extern SHA2Result sha2_256_reset(SHA2Context *context);
|
|||
extern SHA2Result sha2_256_input(SHA2Context *context, const uint8_t data[],
|
||||
size_t len);
|
||||
extern SHA2Result sha2_256_result(SHA2Context *context, SHA2Digest digest);
|
||||
extern void sha2_256_oneshot_n_times(uint32_t n, const uint8_t data[],
|
||||
const size_t len);
|
||||
|
||||
#endif // !SHA2_H
|
||||
|
|
|
@ -7,6 +7,7 @@ unsafe extern "C" {
|
|||
fn crc32_process(data: *const u8, len: u32, crc32: *mut Crc32);
|
||||
|
||||
fn crc32_checksum(data: *const u8, len: u32) -> ChecksumCrc32;
|
||||
fn crc32_checksum_n_times(n: u32, data: *const u8, len: u32) -> ChecksumCrc32;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -19,27 +20,36 @@ impl Crc for Crc32 {
|
|||
|
||||
type Checksum = ChecksumCrc32;
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn new() -> Self {
|
||||
unsafe { crc32_new() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn process(&mut self, data: &Self::Input) {
|
||||
unsafe { crc32_process(ref_to_ptr(data), data.len() as u32, self as *mut Self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn shift_reg(&mut self) -> &mut Self::Checksum {
|
||||
&mut self.buf
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn checksum(data: &Self::Input) -> Self::Checksum {
|
||||
unsafe { crc32_checksum(ref_to_ptr(data), data.len() as u32) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Crc32 {
|
||||
#[inline(always)]
|
||||
pub fn checksum_n_times(n: u32, data: &<Crc32 as Crc>::Input) {
|
||||
unsafe {
|
||||
crc32_checksum_n_times(n, ref_to_ptr(data), data.len() as u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::crc::CHECK_DATA;
|
||||
|
|
|
@ -62,10 +62,12 @@ mod ffi {
|
|||
context: *mut Sha2_256Context,
|
||||
digest: *mut Digest256,
|
||||
) -> SHA2Outcome;
|
||||
|
||||
pub fn sha2_256_oneshot_n_times(n: u32, data: *const u8, len: usize);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn sha2_256_oneshot(data: &[u8]) -> Result<Digest256, SHA2Outcome> {
|
||||
let mut digest: Digest256 = DIGEST256_EMPTY;
|
||||
let res =
|
||||
|
@ -73,23 +75,33 @@ pub fn sha2_256_oneshot(data: &[u8]) -> Result<Digest256, SHA2Outcome> {
|
|||
to_res(digest, res)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sha2_256_reset(context: &mut Sha2_256Context) -> Result<(), SHA2Outcome> {
|
||||
let res = unsafe { ffi::sha2_256_reset(ref_to_ptr_mut(context)) };
|
||||
to_res((), res)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sha2_256_input(context: &mut Sha2_256Context, data: &[u8]) -> Result<(), SHA2Outcome> {
|
||||
let res = unsafe { ffi::sha2_256_input(ref_to_ptr_mut(context), ref_to_ptr(data), data.len()) };
|
||||
to_res((), res)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn sha2_256_result(context: &mut Sha2_256Context) -> Result<Digest256, SHA2Outcome> {
|
||||
let mut digest: Digest256 = DIGEST256_EMPTY;
|
||||
let res = unsafe { ffi::sha2_256_result(ref_to_ptr_mut(context), ref_to_ptr_mut(&mut digest)) };
|
||||
to_res(digest, res)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn sha2_256_oneshot_n_times(n: u32, data: &[u8]) {
|
||||
unsafe {
|
||||
ffi::sha2_256_oneshot_n_times(n, ref_to_ptr(data), data.len());
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn to_res<T>(if_ok: T, res: SHA2Outcome) -> Result<T, SHA2Outcome> {
|
||||
if res == SHA2Outcome::shaSuccess {
|
||||
Ok(if_ok)
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
# i can't build for x86_64 anymore, which means I can't run the unit tests.
|
||||
TARGET="thumbv6m-none-eabi"
|
||||
cargo build --target $TARGET
|
||||
cargo run --target $TARGET $@
|
||||
cargo run -r --target $TARGET $@
|
||||
|
|
2
scripts/winattach.sh
Executable file
2
scripts/winattach.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
powershell.exe -Command "probe-rs attach C:\SVN\nt\BA\trunk\Studium\Christoph_Scherr\system\Implementation\crcbench\target\thumbv6m-none-eabi\release\nucleo-l053r8-benches --chip STM32L053R8"
|
|
@ -7,6 +7,6 @@ TARGET="thumbv6m-none-eabi"
|
|||
|
||||
powershell.exe -Command "
|
||||
cd C:\SVN\nt\BA\trunk\Studium\Christoph_Scherr\system\Implementation\crcbench;
|
||||
cargo build --target $TARGET;
|
||||
cargo run --target $TARGET $@
|
||||
cargo build -r --target $TARGET;
|
||||
cargo run -r --target $TARGET $@
|
||||
"
|
||||
|
|
127
src/bench.rs
127
src/bench.rs
|
@ -1,4 +1,5 @@
|
|||
use algorithms::crc::{Crc, Crc32 as Crc32Rust, ffi::Crc32 as Crc32C};
|
||||
use algorithms::hash::{ffi as sha2_ffi, sha2_256_oneshot};
|
||||
use defmt::info;
|
||||
use hal::{
|
||||
delay::Delay,
|
||||
|
@ -6,38 +7,124 @@ use hal::{
|
|||
prelude::*,
|
||||
};
|
||||
|
||||
pub type SomePin = Pin<Output<PushPull>>;
|
||||
|
||||
pub struct MeasurePins<'a> {
|
||||
pub c: &'a mut SomePin,
|
||||
pub rs: &'a mut SomePin,
|
||||
pub led: &'a mut SomePin,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum MeasurementKind {
|
||||
Rust,
|
||||
C,
|
||||
}
|
||||
|
||||
const RUNS: u32 = 5000;
|
||||
|
||||
impl MeasurePins<'_> {
|
||||
pub fn set_led(&mut self, state: PinState) {
|
||||
self.led.set_state(state).expect("could not set led state")
|
||||
}
|
||||
|
||||
pub fn set_for_kind(&mut self, kind: MeasurementKind, state: PinState) {
|
||||
match kind {
|
||||
MeasurementKind::Rust => self.rs.set_state(state),
|
||||
MeasurementKind::C => self.c.set_state(state),
|
||||
}
|
||||
.expect("could not set rs or c pin")
|
||||
}
|
||||
pub fn set_all(&mut self, state: PinState) {
|
||||
self.led.set_state(state).expect("could not set led state");
|
||||
self.rs.set_state(state).expect("could not set rs state");
|
||||
self.c.set_state(state).expect("could not set c state");
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bench(pin: &mut Pin<Output<PushPull>>, delay: &mut Delay) {
|
||||
bench_delay(pin, delay);
|
||||
bench_crc(pin, delay);
|
||||
pub fn bench(pins: &mut MeasurePins, delay: &mut Delay) {
|
||||
bench_crc(pins, delay);
|
||||
bench_sha256(pins, delay);
|
||||
}
|
||||
|
||||
fn bench_delay(pin: &mut Pin<Output<PushPull>>, delay: &mut Delay) {
|
||||
time_exec(pin, || delay.delay_ms(20u32));
|
||||
time_exec(pin, || delay.delay_ms(50u32));
|
||||
}
|
||||
|
||||
fn time_exec<F>(pin: &mut Pin<Output<PushPull>>, mut f: F)
|
||||
where
|
||||
fn time_exec<F>(
|
||||
id: &str,
|
||||
kind: MeasurementKind,
|
||||
pins: &mut MeasurePins,
|
||||
delay: &mut Delay,
|
||||
do_loop: bool,
|
||||
mut f: F,
|
||||
) where
|
||||
F: FnMut(),
|
||||
{
|
||||
info!("Running the requested function 50 times and returning the average");
|
||||
const RUNS: u32 = 50;
|
||||
pin.set_high().expect("could not set pun to high");
|
||||
for _ in 0..RUNS {
|
||||
if do_loop {
|
||||
info!("Running '{}' {} times", id, RUNS);
|
||||
pins.set_for_kind(kind, PinState::High);
|
||||
for _ in 0..RUNS {
|
||||
f();
|
||||
}
|
||||
pins.set_for_kind(kind, PinState::Low);
|
||||
} else {
|
||||
info!("Running '{}' 1 time", id);
|
||||
pins.set_for_kind(kind, PinState::High);
|
||||
f();
|
||||
pins.set_for_kind(kind, PinState::Low);
|
||||
}
|
||||
pin.set_low().expect("could not set pun to low");
|
||||
info!("Measurement of '{}' finished!", id);
|
||||
delay.delay_ms(100_u32);
|
||||
}
|
||||
|
||||
fn bench_crc(pin: &mut Pin<Output<PushPull>>, delay: &mut Delay) {
|
||||
fn bench_crc(pins: &mut MeasurePins, delay: &mut Delay) {
|
||||
const DATA: &[u8] = b"hello world AAAAAAAAAAAAAAAAAAAAAAA";
|
||||
delay.delay_ms(50_u32);
|
||||
time_exec(pin, || {
|
||||
time_exec("crc32_rs", MeasurementKind::Rust, pins, delay, true, || {
|
||||
Crc32Rust::checksum(DATA);
|
||||
});
|
||||
delay.delay_ms(50_u32);
|
||||
time_exec(pin, || {
|
||||
time_exec("crc32_c_ffi", MeasurementKind::C, pins, delay, true, || {
|
||||
Crc32C::checksum(DATA);
|
||||
});
|
||||
time_exec(
|
||||
"crc32_c_native",
|
||||
MeasurementKind::C,
|
||||
pins,
|
||||
delay,
|
||||
false,
|
||||
|| {
|
||||
Crc32C::checksum_n_times(RUNS, DATA);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn bench_sha256(pins: &mut MeasurePins, delay: &mut Delay) {
|
||||
const DATA: &[u8] = b"hello world AAAAAAAAAAAAAAAAAAAAAAA";
|
||||
time_exec(
|
||||
"sha256_rs",
|
||||
MeasurementKind::Rust,
|
||||
pins,
|
||||
delay,
|
||||
true,
|
||||
|| {
|
||||
sha2_256_oneshot(DATA).unwrap();
|
||||
},
|
||||
);
|
||||
time_exec(
|
||||
"sha256_c_ffi",
|
||||
MeasurementKind::C,
|
||||
pins,
|
||||
delay,
|
||||
true,
|
||||
|| {
|
||||
sha2_ffi::sha2_256_oneshot(DATA).unwrap();
|
||||
},
|
||||
);
|
||||
time_exec(
|
||||
"sha256_c_native",
|
||||
MeasurementKind::C,
|
||||
pins,
|
||||
delay,
|
||||
false,
|
||||
|| {
|
||||
sha2_ffi::sha2_256_oneshot_n_times(RUNS, DATA);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
32
src/main.rs
32
src/main.rs
|
@ -19,6 +19,8 @@ use hal::{
|
|||
rcc::Config,
|
||||
};
|
||||
|
||||
use crate::bench::MeasurePins;
|
||||
|
||||
mod bench;
|
||||
mod error_handlers; // defines a handler for evil hardfaults
|
||||
|
||||
|
@ -33,9 +35,17 @@ fn main() -> ! {
|
|||
// Acquire the GPIOA peripheral. This also enables the clock for GPIOA in
|
||||
// the RCC register.
|
||||
let gpioa = dp.GPIOA.split(&mut rcc);
|
||||
let gpiob = dp.GPIOB.split(&mut rcc);
|
||||
|
||||
// Configure PA5 as output.
|
||||
let mut led = gpioa.pa5.into_push_pull_output().downgrade();
|
||||
// This is D4 on CN19 for the NCLEO L053R8 according to the user manual:
|
||||
// "UM1724"
|
||||
let mut measurepin_0 = gpiob.pb5.into_push_pull_output().downgrade();
|
||||
// This is D5 on CN19 for the NCLEO L053R8
|
||||
let mut measurepin_1 = gpiob.pb4.into_push_pull_output().downgrade();
|
||||
let mut led = gpioa.pa5.into_push_pull_output().downgrade(); // this is the led
|
||||
|
||||
measurepin_0.set_low().unwrap();
|
||||
led.set_low().unwrap();
|
||||
|
||||
// setup timer for measuring time of benchmarks
|
||||
cp.SYST.set_reload(0x00ffffff); // max
|
||||
|
@ -47,13 +57,19 @@ fn main() -> ! {
|
|||
debug!("Asserting that libalgorithms is correctly loaded");
|
||||
assert!(algorithms::ffi_is_loaded(), "ffi is not loaded?");
|
||||
|
||||
info!("Starting the Rust vs C benchmark");
|
||||
bench::bench(&mut led, &mut delay);
|
||||
info!("Benchmark done, nothing else to do");
|
||||
let mut measurepins = bench::MeasurePins {
|
||||
c: &mut measurepin_0,
|
||||
rs: &mut measurepin_1,
|
||||
led: &mut led,
|
||||
};
|
||||
|
||||
info!("Starting the Rust vs C benchmark");
|
||||
bench::bench(&mut measurepins, &mut delay);
|
||||
info!("Benchmark done");
|
||||
|
||||
measurepins.set_all(PinState::Low);
|
||||
|
||||
led.set_high().unwrap();
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {
|
||||
delay.delay_ms(200u32);
|
||||
delay.delay_ms(5000u32);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue