avr_tester/
lib.rs

1//! Framework for testing [AVR] binaries, powered by [simavr]:
2//!
3//! ```no_run
4//! use avr_tester::*;
5//!
6//! // Assuming `firmware` implements a ROT-13 encoder:
7//!
8//! #[test]
9//! fn test() {
10//!     let mut avr = AvrTester::atmega328p()
11//!         .with_clock_of_16_mhz()
12//!         .load("../../firmware/target/avr-none/release/firmware.elf");
13//!
14//!     // Let's give our firmware a moment to initialize:
15//!     avr.run_for_ms(1);
16//!
17//!     // Now, let's send the string:
18//!     avr.uart0().write("Hello, World!");
19//!
20//!     // ... give the AVR a moment to retrieve it & send back, encoded:
21//!     avr.run_for_ms(1);
22//!
23//!     // ... and, finally, let's assert the outcome:
24//!     assert_eq!("Uryyb, Jbeyq!", avr.uart0().read::<String>());
25//! }
26//! ```
27//!
28//! See more: <../tests/examples>.
29//!
30//! [AVR]: https://en.wikipedia.org/wiki/AVR_microcontrollers
31//! [simavr]: https://github.com/buserror/simavr
32
33mod builder;
34mod components;
35mod duration_ext;
36mod pins;
37mod read;
38mod spi;
39mod twi;
40mod uart;
41mod utils;
42mod write;
43
44pub use self::builder::*;
45pub use self::components::*;
46pub use self::duration_ext::*;
47pub use self::pins::*;
48pub use self::read::*;
49pub use self::spi::*;
50pub use self::twi::*;
51pub use self::uart::*;
52pub use self::utils::*;
53pub use self::write::*;
54pub use avr_simulator::{AvrDuration, TwiPacket, TwiSlave};
55use avr_simulator::{AvrSimulator, AvrState};
56use std::cell::RefCell;
57use std::collections::BTreeMap;
58use std::marker::PhantomData;
59use std::path::Path;
60use std::rc::Rc;
61
62type TwiId = u8;
63
64/// The Tester; use [`AvrTester::atmega328p()`] etc. to construct it.
65pub struct AvrTester {
66    sim: Option<AvrSimulator>,
67    clock_frequency: u32,
68    remaining_clock_cycles: Option<u64>,
69    components: Components,
70    twis: BTreeMap<TwiId, Rc<RefCell<TwiManager>>>,
71}
72
73impl AvrTester {
74    pub(crate) fn new(
75        mcu: &str,
76        clock_frequency: u32,
77        firmware: impl AsRef<Path>,
78        remaining_clock_cycles: Option<u64>,
79    ) -> Self {
80        Self {
81            sim: Some(AvrSimulator::new(mcu, clock_frequency, firmware)),
82            clock_frequency,
83            remaining_clock_cycles,
84            components: Components::new(),
85            twis: Default::default(),
86        }
87    }
88
89    #[doc(hidden)]
90    pub fn test() -> Self {
91        todo!();
92    }
93
94    /// Runs a full single instruction, returning the number of cycles it took
95    /// to execute that instruction (e.g. `MUL` takes two cycles or so).
96    ///
97    /// Note that the number returned here is somewhat approximate (see
98    /// [`AvrDuration`]), but it's guaranteed to be at least one cycle.
99    ///
100    /// See also:
101    ///
102    /// - [`Self::run_for_s()`],
103    /// - [`Self::run_for_ms()`],
104    /// - [`Self::run_for_us()`].
105    pub fn run(&mut self) -> AvrDuration {
106        let step = self.sim().step();
107
108        self.components
109            .run(&mut self.sim, self.clock_frequency, step.tt);
110
111        if let Some(remaining_clock_cycles) = &mut self.remaining_clock_cycles {
112            *remaining_clock_cycles =
113                remaining_clock_cycles.saturating_sub(step.tt.as_cycles());
114
115            if *remaining_clock_cycles == 0 {
116                panic!("Test timed-out");
117            }
118        }
119
120        match step.state {
121            AvrState::Running => {
122                //
123            }
124
125            AvrState::Crashed => {
126                panic!(
127                    "AVR crashed (e.g. the program stepped on an invalid \
128                     instruction)"
129                );
130            }
131
132            AvrState::Sleeping => {
133                panic!(
134                    "AVR went to sleep (this panics, because AvrTester doesn't \
135                     provide any way to wake up the microcontroller yet)"
136                );
137            }
138
139            state => {
140                panic!("Unexpected AvrState: {:?}", state);
141            }
142        }
143
144        step.tt
145    }
146
147    /// Runs firmware for given number of cycles (when given [`u64`]) or given
148    /// [`AvrDuration`].
149    ///
150    /// See also:
151    ///
152    /// - [`Self::run_for_s()`],
153    /// - [`Self::run_for_ms()`],
154    /// - [`Self::run_for_us()`].
155    pub fn run_for(&mut self, n: impl IntoCycles) {
156        let mut cycles = n.into_cycles();
157
158        while cycles > 0 {
159            cycles = cycles.saturating_sub(self.run().as_cycles());
160        }
161    }
162
163    /// Runs firmware for given number of AVR microseconds, considering the
164    /// clock specified through [`AvrTesterBuilder::with_clock()`].
165    ///
166    /// See:
167    ///
168    /// - [`Self::run_for_s()`],
169    /// - [`Self::run_for_ms()`].
170    ///
171    /// See also: [`Self::run()`].
172    pub fn run_for_us(&mut self, n: u64) {
173        self.run_for(AvrDuration::micros(self, n));
174    }
175
176    /// Runs firmware for given number of AVR milliseconds, considering the
177    /// clock specified through [`AvrTesterBuilder::with_clock()`].
178    ///
179    /// See:
180    ///
181    /// - [`Self::run_for_s()`],
182    /// - [`Self::run_for_us()`].
183    ///
184    /// See also: [`Self::run()`].
185    pub fn run_for_ms(&mut self, n: u64) {
186        self.run_for(AvrDuration::millis(self, n));
187    }
188
189    /// Runs firmware for given number of AVR seconds, considering the clock
190    /// specified through [`AvrTesterBuilder::with_clock()`].
191    ///
192    /// See:
193    ///
194    /// - [`Self::run_for_ms()`],
195    /// - [`Self::run_for_us()`].
196    ///
197    /// See also: [`Self::run()`].
198    pub fn run_for_s(&mut self, n: u64) {
199        self.run_for(AvrDuration::secs(self, n));
200    }
201
202    /// Returns an object providing access to the analog and digital pins, such
203    /// as `ADC1`, `PD4` etc.
204    ///
205    /// Note that the returned object contains all possible pins for all of the
206    /// existing AVRs, while the AVR of yours probably supports only a subset of
207    /// those pins - trying to access a pin that does not exist for your AVR
208    /// will panic.
209    pub fn pins(&mut self) -> Pins {
210        Pins::new(self)
211    }
212
213    /// Returns an object providing access to SPI0 (i.e. the default one).
214    ///
215    /// Note that if your AVR doesn't have SPI0, operating on it will panic.
216    #[doc(alias = "spi")]
217    pub fn spi0(&mut self) -> Spi {
218        Spi::new(self.sim(), 0)
219    }
220
221    /// Returns an object providing access to SPI1.
222    ///
223    /// Note that if your AVR doesn't have SPI1, operating on it will panic.
224    pub fn spi1(&mut self) -> Spi {
225        Spi::new(self.sim(), 1)
226    }
227
228    /// Returns an object providing access to TWI0 (i.e. the default one), also
229    /// known as I2C.
230    ///
231    /// Note that if your AVR doesn't have TWI0, operating on it will panic.
232    #[doc(alias = "i2c")]
233    pub fn twi0(&mut self) -> Twi {
234        Twi::new(self, 0)
235    }
236
237    /// Returns an object providing access to TWI1.
238    ///
239    /// Note that if your AVR doesn't have TWI1, operating on it will panic.
240    pub fn twi1(&mut self) -> Twi {
241        Twi::new(self, 1)
242    }
243
244    /// Returns an object providing access to UART0 (i.e. the default one).
245    ///
246    /// Note that if your AVR doesn't have UART0, operating on it will panic.
247    #[doc(alias = "uart")]
248    pub fn uart0(&mut self) -> Uart {
249        Uart::new(self.sim(), '0')
250    }
251
252    /// Returns an object providing access to UART1.
253    ///
254    /// Note that if your AVR doesn't have UART1, operating on it will panic.
255    pub fn uart1(&mut self) -> Uart {
256        Uart::new(self.sim(), '1')
257    }
258
259    /// Returns an object providing acccess to components (aka _peripherals_)
260    /// attached to the AVR.
261    pub fn components(&mut self) -> &mut Components {
262        &mut self.components
263    }
264
265    fn sim(&mut self) -> &mut AvrSimulator {
266        self.sim.as_mut().expect(
267            "AvrSimulator had been deallocated - has some component crashed?",
268        )
269    }
270}
271
272/// Asynchronous equivalent of [`AvrTester`].
273///
274/// See [`avr_rt()`] for more details.
275pub struct AvrTesterAsync {
276    _pd: PhantomData<()>,
277}
278
279impl AvrTesterAsync {
280    fn new() -> Self {
281        Self {
282            _pd: Default::default(),
283        }
284    }
285
286    /// Asynchronous equivalent of [`AvrTester::run()`].
287    ///
288    /// See [`avr_rt()`] for more details.
289    pub async fn run(&self) -> AvrDuration {
290        ResumeFuture::new().await
291    }
292
293    /// Asynchronous equivalent of [`AvrTester::run_for()`].
294    ///
295    /// See [`avr_rt()`] for more details.
296    pub async fn run_for(&self, n: impl IntoCycles) {
297        let cycles = n.into_cycles();
298
299        let fut = ComponentRuntime::with(|rt| {
300            SleepFuture::new(AvrDuration::new(rt.clock_frequency(), cycles))
301        });
302
303        fut.await;
304    }
305
306    /// Asynchronous equivalent of [`AvrTester::run_for_us()`].
307    ///
308    /// See [`avr_rt()`] for more details.
309    pub async fn run_for_us(&self, n: u64) {
310        let fut = ComponentRuntime::with(|rt| {
311            SleepFuture::new(
312                AvrDuration::new(rt.clock_frequency(), 0).with_micros(n),
313            )
314        });
315
316        fut.await;
317    }
318
319    /// Asynchronous equivalent of [`AvrTester::run_for_ms()`].
320    ///
321    /// See [`avr_rt()`] for more details.
322    pub async fn run_for_ms(&self, n: u64) {
323        let fut = ComponentRuntime::with(|rt| {
324            SleepFuture::new(
325                AvrDuration::new(rt.clock_frequency(), 0).with_millis(n),
326            )
327        });
328
329        fut.await;
330    }
331
332    /// Asynchronous equivalent of [`AvrTester::run_for_s()`].
333    ///
334    /// See [`avr_rt()`] for more details.
335    pub async fn run_for_s(&self, n: u64) {
336        let fut = ComponentRuntime::with(|rt| {
337            SleepFuture::new(
338                AvrDuration::new(rt.clock_frequency(), 0).with_secs(n),
339            )
340        });
341
342        fut.await;
343    }
344
345    /// Asynchronous equivalent of [`AvrTester::pins()`].
346    ///
347    /// See [`avr_rt()`] for more details.
348    pub fn pins(&self) -> PinsAsync {
349        PinsAsync::new()
350    }
351
352    /// Asynchronous equivalent of [`AvrTester::spi0()`].
353    ///
354    /// See [`avr_rt()`] for more details.
355    pub fn spi0(&self) -> SpiAsync {
356        SpiAsync::new(0)
357    }
358
359    /// Asynchronous equivalent of [`AvrTester::spi1()`].
360    ///
361    /// See [`avr_rt()`] for more details.
362    pub fn spi1(&self) -> SpiAsync {
363        SpiAsync::new(1)
364    }
365
366    /// Asynchronous equivalent of [`AvrTester::uart0()`].
367    ///
368    /// See [`avr_rt()`] for more details.
369    pub fn uart0(&mut self) -> UartAsync {
370        UartAsync::new('0')
371    }
372
373    /// Asynchronous equivalent of [`AvrTester::uart1()`].
374    ///
375    /// See [`avr_rt()`] for more details.
376    pub fn uart1(&mut self) -> UartAsync {
377        UartAsync::new('1')
378    }
379}
380
381/// Returns [`AvrTesterAsync`] for usage inside **components**.
382///
383/// See [`Components`] for more details.
384pub fn avr_rt() -> AvrTesterAsync {
385    AvrTesterAsync::new()
386}
387
388macro_rules! constructors {
389    ( $( $name:ident ),* $(,)? ) => {
390        impl AvrTester {
391            $(
392                pub fn $name() -> AvrTesterBuilder {
393                    AvrTesterBuilder::new(stringify!($name))
394                }
395            )*
396        }
397    }
398}
399
400constructors! {
401    // sim_mega8.c
402    atmega8, atmega81,
403
404    // sim_mega16.c
405    atmega16,
406
407    // sim_mega16m1.c
408    atmega16m1,
409
410    // sim_mega32.c
411    atmega32,
412
413    // sim_mega32u4.c
414    atmega32u4,
415
416    // sim_mega48.c
417    atmega48, atmega48p, atmega48pa,
418
419    // sim_mega64m1.c
420    atmega64m1,
421
422    // sim_mega88.c
423    atmega88, atmega88p, atmega88pa,
424
425    // sim_mega128.c
426    atmega128, atmega128l,
427
428    // sim_mega128rfa1.c
429    atmega128rfa1,
430
431    // sim_mega128rfr2.c
432    atmega128rfr2,
433
434    // sim_mega164.c
435    atmega164, atmega164p, atmega164pa,
436
437    // sim_mega168.c
438    atmega168, atmega168p, atmega168pa,
439
440    // sim_mega169.c
441    atmega169p,
442
443    // sim_mega324.c
444    atmega324, atmega324p,
445
446    // sim_mega324a.c
447    atmega324a, atmega324pa,
448
449    // sim_mega328.c
450    atmega328, atmega328p,
451
452    // sim_mega328pb.c
453    atmega328pb,
454
455    // sim_mega644.c
456    atmega644, atmega644p,
457
458    // sim_mega1280.c
459    atmega1280,
460
461    // sim_mega1281.c
462    atmega1281,
463
464    // sim_mega1284.c
465    atmega1284p, atmega1284,
466
467    // sim_mega2560.c
468    atmega2560, atmega2561,
469
470    // sim_tiny13.c
471    attiny13, attiny13a,
472
473    // sim_tiny24.c
474    attiny24,
475
476    // sim_tiny25.c
477    attiny25,
478
479    // sim_tiny44.c
480    attiny44,
481
482    // sim_tiny45.c
483    attiny45,
484
485    // sim_tiny84.c
486    attiny84,
487
488    // sim_tiny85.c
489    attiny85,
490
491    // sim_tiny2313.c
492    attiny2313, attiny2313v,
493
494    // sim_tiny2313a.c
495    attiny2313a,
496
497    // sim_tiny4313.c
498    attiny4313,
499}