sim: Return exit status from sim run
Instead of just printing a message, return an exit status so that scripts running the sim can more easily tell if the tests passed. Jira: MCUB-45
This commit is contained in:
parent
274f7874db
commit
361be7ade7
276
sim/src/main.rs
276
sim/src/main.rs
|
@ -12,6 +12,7 @@ use docopt::Docopt;
|
|||
use rand::{Rng, SeedableRng, XorShiftRng};
|
||||
use rustc_serialize::{Decodable, Decoder};
|
||||
use std::mem;
|
||||
use std::process;
|
||||
use std::slice;
|
||||
|
||||
mod area;
|
||||
|
@ -79,128 +80,181 @@ fn main() {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut status = RunStatus::new();
|
||||
|
||||
let align = args.flag_align.map(|x| x.0).unwrap_or(1);
|
||||
|
||||
let (mut flash, areadesc) = match args.flag_device {
|
||||
None => panic!("Missing mandatory argument"),
|
||||
Some(DeviceName::Stm32f4) => {
|
||||
// STM style flash. Large sectors, with a large scratch area.
|
||||
let flash = Flash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 16 * 1024,
|
||||
64 * 1024,
|
||||
128 * 1024, 128 * 1024, 128 * 1024],
|
||||
align as usize);
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
|
||||
areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
|
||||
areadesc.add_image(0x060000, 0x020000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
Some(DeviceName::K64f) => {
|
||||
// NXP style flash. Small sectors, one small sector for scratch.
|
||||
let flash = Flash::new(vec![4096; 128], align as usize);
|
||||
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
|
||||
areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
|
||||
areadesc.add_image(0x060000, 0x001000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
Some(DeviceName::K64fBig) => {
|
||||
// Simulating an STM style flash on top of an NXP style flash. Underlying flash device
|
||||
// uses small sectors, but we tell the bootloader they are large.
|
||||
let flash = Flash::new(vec![4096; 128], align as usize);
|
||||
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_simple_image(0x020000, 0x020000, FlashId::Image0);
|
||||
areadesc.add_simple_image(0x040000, 0x020000, FlashId::Image1);
|
||||
areadesc.add_simple_image(0x060000, 0x020000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
Some(DeviceName::Nrf52840) => {
|
||||
// Simulating the flash on the nrf52840 with partitions set up so that the scratch size
|
||||
// does not divide into the image size.
|
||||
let flash = Flash::new(vec![4096; 128], align as usize);
|
||||
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_image(0x008000, 0x034000, FlashId::Image0);
|
||||
areadesc.add_image(0x03c000, 0x034000, FlashId::Image1);
|
||||
areadesc.add_image(0x070000, 0x00d000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
let device = match args.flag_device {
|
||||
None => panic!("Missing mandatory device argument"),
|
||||
Some(dev) => dev,
|
||||
};
|
||||
|
||||
let (slot0_base, slot0_len) = areadesc.find(FlashId::Image0);
|
||||
let (slot1_base, slot1_len) = areadesc.find(FlashId::Image1);
|
||||
let (scratch_base, _) = areadesc.find(FlashId::ImageScratch);
|
||||
status.run_single(device, align);
|
||||
|
||||
// Code below assumes that the slots are consecutive.
|
||||
assert_eq!(slot1_base, slot0_base + slot0_len);
|
||||
assert_eq!(scratch_base, slot1_base + slot1_len);
|
||||
if status.failures > 0 {
|
||||
warn!("{} Tests ran with {} failures", status.failures + status.passes, status.failures);
|
||||
process::exit(1);
|
||||
} else {
|
||||
warn!("{} Tests ran successfully", status.passes);
|
||||
process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// println!("Areas: {:#?}", areadesc.get_c());
|
||||
struct RunStatus {
|
||||
failures: usize,
|
||||
passes: usize,
|
||||
}
|
||||
|
||||
// Install the boot trailer signature, so that the code will start an upgrade.
|
||||
// TODO: This must be a multiple of flash alignment, add support for an image that is smaller,
|
||||
// and just gets padded.
|
||||
let primary = install_image(&mut flash, slot0_base, 32784);
|
||||
|
||||
// Install an upgrade image.
|
||||
let upgrade = install_image(&mut flash, slot1_base, 41928);
|
||||
|
||||
// Set an alignment, and position the magic value.
|
||||
c::set_sim_flash_align(align);
|
||||
let trailer_size = c::boot_trailer_sz();
|
||||
|
||||
// Mark the upgrade as ready to install. (This looks like it might be a bug in the code,
|
||||
// however.)
|
||||
mark_upgrade(&mut flash, scratch_base - trailer_size as usize);
|
||||
|
||||
let (fl2, total_count) = try_upgrade(&flash, &areadesc, None);
|
||||
info!("First boot, count={}", total_count);
|
||||
assert!(verify_image(&fl2, slot0_base, &upgrade));
|
||||
|
||||
let mut bad = 0;
|
||||
// Let's try an image halfway through.
|
||||
for i in 1 .. total_count {
|
||||
info!("Try interruption at {}", i);
|
||||
let (fl3, total_count) = try_upgrade(&flash, &areadesc, Some(i));
|
||||
info!("Second boot, count={}", total_count);
|
||||
if !verify_image(&fl3, slot0_base, &upgrade) {
|
||||
warn!("FAIL at step {} of {}", i, total_count);
|
||||
bad += 1;
|
||||
}
|
||||
if !verify_image(&fl3, slot1_base, &primary) {
|
||||
warn!("Slot 1 FAIL at step {} of {}", i, total_count);
|
||||
bad += 1;
|
||||
impl RunStatus {
|
||||
fn new() -> RunStatus {
|
||||
RunStatus {
|
||||
failures: 0,
|
||||
passes: 0,
|
||||
}
|
||||
}
|
||||
error!("{} out of {} failed {:.2}%",
|
||||
bad, total_count,
|
||||
bad as f32 * 100.0 / total_count as f32);
|
||||
|
||||
for count in 2 .. 5 {
|
||||
info!("Try revert: {}", count);
|
||||
let fl2 = try_revert(&flash, &areadesc, count);
|
||||
assert!(verify_image(&fl2, slot0_base, &primary));
|
||||
fn run_single(&mut self, device: DeviceName, align: u8) {
|
||||
let mut failed = false;
|
||||
|
||||
let (mut flash, areadesc) = match device {
|
||||
DeviceName::Stm32f4 => {
|
||||
// STM style flash. Large sectors, with a large scratch area.
|
||||
let flash = Flash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 16 * 1024,
|
||||
64 * 1024,
|
||||
128 * 1024, 128 * 1024, 128 * 1024],
|
||||
align as usize);
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
|
||||
areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
|
||||
areadesc.add_image(0x060000, 0x020000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
DeviceName::K64f => {
|
||||
// NXP style flash. Small sectors, one small sector for scratch.
|
||||
let flash = Flash::new(vec![4096; 128], align as usize);
|
||||
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
|
||||
areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
|
||||
areadesc.add_image(0x060000, 0x001000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
DeviceName::K64fBig => {
|
||||
// Simulating an STM style flash on top of an NXP style flash. Underlying flash device
|
||||
// uses small sectors, but we tell the bootloader they are large.
|
||||
let flash = Flash::new(vec![4096; 128], align as usize);
|
||||
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_simple_image(0x020000, 0x020000, FlashId::Image0);
|
||||
areadesc.add_simple_image(0x040000, 0x020000, FlashId::Image1);
|
||||
areadesc.add_simple_image(0x060000, 0x020000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
DeviceName::Nrf52840 => {
|
||||
// Simulating the flash on the nrf52840 with partitions set up so that the scratch size
|
||||
// does not divide into the image size.
|
||||
let flash = Flash::new(vec![4096; 128], align as usize);
|
||||
|
||||
let mut areadesc = AreaDesc::new(&flash);
|
||||
areadesc.add_image(0x008000, 0x034000, FlashId::Image0);
|
||||
areadesc.add_image(0x03c000, 0x034000, FlashId::Image1);
|
||||
areadesc.add_image(0x070000, 0x00d000, FlashId::ImageScratch);
|
||||
(flash, areadesc)
|
||||
}
|
||||
};
|
||||
|
||||
let (slot0_base, slot0_len) = areadesc.find(FlashId::Image0);
|
||||
let (slot1_base, slot1_len) = areadesc.find(FlashId::Image1);
|
||||
let (scratch_base, _) = areadesc.find(FlashId::ImageScratch);
|
||||
|
||||
// Code below assumes that the slots are consecutive.
|
||||
assert_eq!(slot1_base, slot0_base + slot0_len);
|
||||
assert_eq!(scratch_base, slot1_base + slot1_len);
|
||||
|
||||
// println!("Areas: {:#?}", areadesc.get_c());
|
||||
|
||||
// Install the boot trailer signature, so that the code will start an upgrade.
|
||||
// TODO: This must be a multiple of flash alignment, add support for an image that is smaller,
|
||||
// and just gets padded.
|
||||
let primary = install_image(&mut flash, slot0_base, 32784);
|
||||
|
||||
// Install an upgrade image.
|
||||
let upgrade = install_image(&mut flash, slot1_base, 41928);
|
||||
|
||||
// Set an alignment, and position the magic value.
|
||||
c::set_sim_flash_align(align);
|
||||
let trailer_size = c::boot_trailer_sz();
|
||||
|
||||
// Mark the upgrade as ready to install. (This looks like it might be a bug in the code,
|
||||
// however.)
|
||||
mark_upgrade(&mut flash, scratch_base - trailer_size as usize);
|
||||
|
||||
let (fl2, total_count) = try_upgrade(&flash, &areadesc, None);
|
||||
info!("First boot, count={}", total_count);
|
||||
if !verify_image(&fl2, slot0_base, &upgrade) {
|
||||
error!("Image mismatch after first boot");
|
||||
// This isn't really recoverable, and more tests aren't likely to reveal much.
|
||||
self.failures += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
let mut bad = 0;
|
||||
// Let's try an image halfway through.
|
||||
for i in 1 .. total_count {
|
||||
info!("Try interruption at {}", i);
|
||||
let (fl3, total_count) = try_upgrade(&flash, &areadesc, Some(i));
|
||||
info!("Second boot, count={}", total_count);
|
||||
if !verify_image(&fl3, slot0_base, &upgrade) {
|
||||
warn!("FAIL at step {} of {}", i, total_count);
|
||||
bad += 1;
|
||||
}
|
||||
if !verify_image(&fl3, slot1_base, &primary) {
|
||||
warn!("Slot 1 FAIL at step {} of {}", i, total_count);
|
||||
bad += 1;
|
||||
}
|
||||
}
|
||||
error!("{} out of {} failed {:.2}%",
|
||||
bad, total_count,
|
||||
bad as f32 * 100.0 / total_count as f32);
|
||||
if bad > 0 {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
for count in 2 .. 5 {
|
||||
info!("Try revert: {}", count);
|
||||
let fl2 = try_revert(&flash, &areadesc, count);
|
||||
if !verify_image(&fl2, slot0_base, &primary) {
|
||||
warn!("Revert failure on count {}", count);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
info!("Try norevert");
|
||||
let fl2 = try_norevert(&flash, &areadesc);
|
||||
if !verify_image(&fl2, slot0_base, &upgrade) {
|
||||
warn!("No revert failed");
|
||||
failed = true;
|
||||
}
|
||||
|
||||
/*
|
||||
// show_flash(&flash);
|
||||
|
||||
println!("First boot for upgrade");
|
||||
// c::set_flash_counter(570);
|
||||
c::boot_go(&mut flash, &areadesc);
|
||||
// println!("{} flash ops", c::get_flash_counter());
|
||||
|
||||
verify_image(&flash, slot0_base, &upgrade);
|
||||
|
||||
println!("\n------------------\nSecond boot");
|
||||
c::boot_go(&mut flash, &areadesc);
|
||||
*/
|
||||
if failed {
|
||||
self.failures += 1;
|
||||
} else {
|
||||
self.passes += 1;
|
||||
}
|
||||
}
|
||||
|
||||
info!("Try norevert");
|
||||
let fl2 = try_norevert(&flash, &areadesc);
|
||||
assert!(verify_image(&fl2, slot0_base, &upgrade));
|
||||
|
||||
/*
|
||||
// show_flash(&flash);
|
||||
|
||||
println!("First boot for upgrade");
|
||||
// c::set_flash_counter(570);
|
||||
c::boot_go(&mut flash, &areadesc);
|
||||
// println!("{} flash ops", c::get_flash_counter());
|
||||
|
||||
verify_image(&flash, slot0_base, &upgrade);
|
||||
|
||||
println!("\n------------------\nSecond boot");
|
||||
c::boot_go(&mut flash, &areadesc);
|
||||
*/
|
||||
}
|
||||
|
||||
/// Test a boot, optionally stopping after 'n' flash options. Returns a count of the number of
|
||||
|
|
Loading…
Reference in New Issue