capsules_core/test/
alarm_edge_cases.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 an Alarm implementation is working by trying a few edge
6//! cases on the delay, including delays of 1 and 0 delays. Depends
7//! on a working UART and debug! macro.
8//!
9//! Author: Philip Levis <plevis@google.com>
10//! Last Modified: 6/17/2020
11use core::cell::Cell;
12use kernel::debug;
13use kernel::hil::time::{Alarm, AlarmClient, ConvertTicks, Ticks};
14
15pub struct TestAlarmEdgeCases<'a, A: 'a> {
16    alarm: &'a A,
17    counter: Cell<usize>,
18    alarms: [u32; 20],
19}
20
21impl<'a, A: Alarm<'a>> TestAlarmEdgeCases<'a, A> {
22    pub fn new(alarm: &'a A) -> TestAlarmEdgeCases<'a, A> {
23        TestAlarmEdgeCases {
24            alarm,
25            counter: Cell::new(0),
26            alarms: [
27                100, 200, 25, 25, 25, 25, 500, 0, 448, 15, 19, 1, 0, 33, 5, 1000, 27, 1, 0, 1,
28            ],
29        }
30    }
31
32    pub fn run(&self) {
33        debug!("Starting alarm edge case tests.");
34        self.set_next_alarm();
35    }
36
37    fn set_next_alarm(&self) {
38        let counter = self.counter.get();
39        let delay = self.alarm.ticks_from_ms(self.alarms[counter % 20]);
40        let now = self.alarm.now();
41        let start = now.wrapping_sub(A::Ticks::from(10));
42
43        debug!(
44            "{}: Setting alarm to {} + {} = {}",
45            now.into_u32(),
46            start.into_u32(),
47            delay.into_u32(),
48            start.wrapping_add(delay).into_u32()
49        );
50        self.alarm.set_alarm(start, delay);
51        self.counter.set(counter + 1);
52    }
53}
54
55impl<'a, A: Alarm<'a>> AlarmClient for TestAlarmEdgeCases<'a, A> {
56    fn alarm(&self) {
57        let now = self.alarm.now();
58        debug!("Alarm fired at {}.", now.into_u32());
59        self.set_next_alarm();
60    }
61}