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}