capsules_core/test/
random_timer.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Test that a Timer implementation is working.
6//!
7//! Test that a Timer implementation is working by trying a few edge
8//! cases on the interval, including intervals of 1 and 0. Depends on
9//! a working UART and debug! macro. Tries repeating as well as
10//! one-shot Timers.
11// Author: Philip Levis <plevis@google.com>
12// Last Modified: 6/22/2020
13
14use core::cell::Cell;
15
16use kernel::debug;
17use kernel::hil::time::{ConvertTicks, Ticks, Timer, TimerClient};
18
19pub struct TestRandomTimer<'a, T: 'a> {
20    timer: &'a T,
21    interval: Cell<u32>,
22    counter: Cell<u32>,
23    iv: Cell<u32>,
24    _id: char,
25}
26
27impl<'a, T: Timer<'a>> TestRandomTimer<'a, T> {
28    pub fn new(timer: &'a T, value: usize, ch: char) -> TestRandomTimer<'a, T> {
29        TestRandomTimer {
30            timer,
31            interval: Cell::new(0),
32            counter: Cell::new(0),
33            iv: Cell::new(value as u32),
34            _id: ch,
35        }
36    }
37
38    pub fn run(&self) {
39        debug!("Starting random timer test Test{}.", self._id);
40        self.set_next_timer();
41    }
42
43    fn set_next_timer(&self) {
44        let iv = self.iv.get();
45        self.iv.set(iv + 1);
46
47        let counter = self.counter.get();
48        if counter == 0 {
49            let mut us: u32 = (iv * 745939) % 115843;
50            if us % 11 == 0 {
51                // Try delays of zero in 1 of 11 cases
52                us = 0;
53            }
54            let new_interval = self.timer.ticks_from_us(us);
55            self.interval.set(new_interval.into_u32());
56            if us % 7 == 0 {
57                let new_counter = 2 + self.interval.get() * 23 % 13;
58                self.counter.set(new_counter);
59                //debug!("Timer{} repeating with interval {}", self._id, self.interval.get());
60                self.timer.repeating(new_interval);
61            } else {
62                //debug!("Timer{} oneshot with interval {}", self._id, self.interval.get());
63                self.timer.oneshot(new_interval);
64            }
65        } else {
66            self.counter.set(counter - 1);
67        }
68    }
69}
70
71impl<'a, T: Timer<'a>> TimerClient for TestRandomTimer<'a, T> {
72    fn timer(&self) {
73        debug!(
74            "Timer{} fired with interval {}, count {},  fired at {}.",
75            self._id,
76            self.interval.get(),
77            self.counter.get(),
78            self.timer.now().into_u32()
79        );
80        self.set_next_timer();
81    }
82}