Browse Source

Add lot's of debugging logging

double-buffering
Noah Hüsser 3 years ago
parent
commit
662e8ef143
  1. 159
      .vscode/launch.json
  2. 1
      probe/src/debug_probe.rs
  3. 45
      probe/src/flash/builder.rs
  4. 1
      probe/src/flash/download.rs
  5. 25
      probe/src/flash/flasher.rs
  6. 7
      probe/src/flash/loader.rs
  7. 4
      probe/src/flash/memory.rs

159
.vscode/launch.json

@ -0,0 +1,159 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'coresight'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=coresight"
],
"filter": {
"name": "coresight",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'probe'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=probe"
],
"filter": {
"name": "probe",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'memory'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=memory"
],
"filter": {
"name": "memory",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'stlink'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=stlink"
],
"filter": {
"name": "stlink",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'daplink'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=daplink"
],
"filter": {
"name": "daplink",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'probe-rs-debug'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=probe-rs-debug"
],
"filter": {
"name": "probe-rs-debug",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'cli'",
"cargo": {
"args": [
"build",
"--bin=cli",
"--package=cli"
],
"filter": {
"name": "cli",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'cli'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=cli",
"--package=cli"
],
"filter": {
"name": "cli",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

1
probe/src/debug_probe.rs

@ -168,6 +168,7 @@ impl MasterProbe {
}
}
#[derive(Debug)]
pub struct CpuInformation {
pub pc: u32,
}

45
probe/src/flash/builder.rs

@ -4,10 +4,14 @@ const PAGE_ESTIMATE_SIZE: u32 = 32;
const _PAGE_READ_WEIGHT: f32 = 0.3;
const DATA_TRANSFER_B_PER_S: f32 = 40.0 * 1000.0; // ~40KB/s, depends on clock speed, theoretical limit for HID is 56,000 B/s
#[derive(Debug, Clone)]
#[derive(Derivative, Clone)]
#[derivative(Debug)]
pub struct FlashPage {
#[derivative(Debug(format_with="fmt_hex"))]
address: u32,
#[derivative(Debug(format_with="fmt_hex"))]
size: u32,
#[derivative(Debug(format_with="fmt"))]
data: Vec<u8>,
program_weight: f32,
pub erased: Option<bool>,
@ -15,6 +19,14 @@ pub struct FlashPage {
cached_estimate_data: Vec<u8>,
}
fn fmt(data: &Vec<u8>, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(f, "[{} bytes]", data.len())
}
fn fmt_hex<T: std::fmt::LowerHex>(data: &T, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(f, "0x{:08x}", data)
}
impl FlashPage {
pub fn new(page_info: &PageInfo) -> Self {
Self {
@ -39,8 +51,12 @@ impl FlashPage {
}
}
#[derive(Derivative)]
#[derivative(Debug)]
pub struct FlashSector {
#[derivative(Debug(format_with="fmt_hex"))]
address: u32,
#[derivative(Debug(format_with="fmt_hex"))]
size: u32,
max_page_count: usize,
pages: Vec<FlashPage>,
@ -77,7 +93,7 @@ impl FlashSector {
}
pub fn is_pages_to_be_programmed(&self) -> bool {
self.pages.iter().any(|p| if let Some(true) = p.dirty { false } else { true })
self.pages.iter().any(|p| if let Some(true) = p.dirty { true } else { false })
}
pub fn set_all_pages_dirty(&mut self) {
@ -216,6 +232,7 @@ impl<'a> FlashBuilder<'a> {
return Ok(())
}
log::debug!("Smart Flash enabled: {:?}", smart_flash);
// If smart flash was set to false then mark all pages as requiring programming.
if !smart_flash {
Self::mark_all_pages_for_programming(&mut sectors);
@ -242,6 +259,8 @@ impl<'a> FlashBuilder<'a> {
}
}
log::debug!("Full Chip Erase enabled: {:?}", chip_erase);
log::debug!("Double Buffering enabled: {:?}", self.enable_double_buffering);
if Some(true) == chip_erase {
if flash.double_buffering_supported() && self.enable_double_buffering {
self.chip_erase_program_double_buffer(&mut flash, &sectors)?;
@ -252,6 +271,7 @@ impl<'a> FlashBuilder<'a> {
if flash.double_buffering_supported() && self.enable_double_buffering {
self.sector_erase_program_double_buffer(&mut flash, &mut sectors)?;
} else {
// WORKING: We debug this atm.
self.sector_erase_program(&mut flash, &sectors)?;
};
}
@ -267,6 +287,7 @@ impl<'a> FlashBuilder<'a> {
sectors: &mut Vec<FlashSector>,
keep_unwritten: bool
) -> Result<(), FlashBuilderError> {
log::debug!("Building sectors and pages");
let mut flash_address = self.flash_operations[0].address;
// Get sector info and make sure all data is valid.
@ -374,6 +395,11 @@ impl<'a> FlashBuilder<'a> {
Self::fill_unwritten_sector_pages(flash, sectors)?;
}
log::debug!("Sectors are:");
for sector in sectors {
log::debug!("{:#?}", sector);
}
Ok(())
}
@ -664,19 +690,32 @@ impl<'a> FlashBuilder<'a> {
}
/// Program by performing sector erases.
fn sector_erase_program(&self, flash: &mut Flasher, sectors: &Vec<FlashSector>) -> Result<(), FlashBuilderError> {
fn sector_erase_program(
&self,
flash: &mut Flasher,
sectors: &Vec<FlashSector>
) -> Result<(), FlashBuilderError> {
let number_of_sectors_to_be_programmed = sectors
.iter()
.filter(|s| s.is_pages_to_be_programmed())
.count();
log::debug!("Flashing {} sectors.", number_of_sectors_to_be_programmed);
let mut i = 0;
for sector in sectors {
if sector.is_pages_to_be_programmed() {
log::debug!("Erasing sector {}", i);
flash.run_erase(|active| {
active.erase_sector(sector.address)
})?;
log::debug!("Programming sector {}", i);
for page in &sector.pages {
flash.run_program(|active| {
active.program_page(page.address, page.data.as_slice())
})?;
}
}
i+=1;
}
Ok(())
}

1
probe/src/flash/download.rs

@ -169,7 +169,6 @@ impl<'a> FileDownloader {
}
}
loader.add_data(ph.p_paddr as u32, &buffer[ph.p_offset as usize..][..ph.p_filesz as usize])?;
}
}

25
probe/src/flash/flasher.rs

@ -52,6 +52,14 @@ pub struct FlashAlgorithm {
pub trait Operation {
fn operation() -> u32;
fn operation_name(&self) -> &str {
match Self::operation() {
1 => "Erase",
2 => "Program",
3 => "Verify",
_ => "Unknown Operation",
}
}
}
pub struct Erase;
@ -136,6 +144,7 @@ impl<'a> Flasher<'a> {
mut address: Option<u32>,
clock: Option<u32>
) -> Result<ActiveFlasher<'b, O>, FlasherError> {
log::debug!("Initializing the flash algorithm.");
let algo = self.session.target.info.flash_algorithm;
if address.is_none() {
@ -143,12 +152,19 @@ impl<'a> Flasher<'a> {
}
// TODO: Halt & reset target.
log::debug!("Halting core.");
let cpu_info = self.session.target.core.halt(&mut self.session.probe);
log::debug!("{:?}", &cpu_info);
// TODO: Possible special preparation of the target such as enabling faster clocks for the flash e.g.
// Load flash algorithm code into target RAM.
log::debug!("Loading algorithm into RAM at address 0x{:08x}", algo.load_address);
self.session.probe.write_block32(algo.load_address, algo.instructions)?;
log::debug!("Preparing Flasher for region:");
log::debug!("{:#?}", &self.region);
log::debug!("Double buffering enabled: {}", self.double_buffering_supported);
let mut flasher = ActiveFlasher {
session: self.session,
region: self.region,
@ -158,10 +174,11 @@ impl<'a> Flasher<'a> {
// Execute init routine if one is present.
if let Some(pc_init) = algo.pc_init {
log::debug!("Running init routine.");
let result = flasher.call_function_and_wait(
pc_init,
address,
clock,
clock.or(Some(0)),
Some(O::operation()),
None,
true
@ -261,6 +278,7 @@ impl<'a, O: Operation> ActiveFlasher<'a, O> {
}
pub fn uninit<'b, 's: 'b>(&'s mut self) -> Result<Flasher<'b>, FlasherError> {
log::debug!("Running uninit routine.");
let algo = self.session.target.info.flash_algorithm;
if let Some(pc_uninit) = algo.pc_uninit {
@ -291,6 +309,8 @@ impl<'a, O: Operation> ActiveFlasher<'a, O> {
}
fn call_function(&mut self, pc: u32, r0: Option<u32>, r1: Option<u32>, r2: Option<u32>, r3: Option<u32>, init: bool) -> Result<(), FlasherError> {
log::debug!("Calling routine {}({:?}, {:?}, {:?}, {:?}, init={})", pc, r0, r1, r2, r3, init);
let algo = self.session.target.info.flash_algorithm;
let regs = self.session.target.info.basic_register_addresses;
@ -319,6 +339,7 @@ impl<'a, O: Operation> ActiveFlasher<'a, O> {
}
pub fn wait_for_completion(&mut self) -> u32 {
log::debug!("Waiting for routine call completion.");
let regs = self.session.target.info.basic_register_addresses;
while self.session.target.core.wait_for_core_halted(&mut self.session.probe).is_err() {}
@ -362,6 +383,7 @@ impl <'a> ActiveFlasher<'a, Erase> {
}
pub fn erase_sector(&mut self, address: u32) -> Result<(), FlasherError> {
log::debug!("Erasing sector at address 0x{:08x}.", address);
let algo = self.session.target.info.flash_algorithm;
let result = self.call_function_and_wait(
@ -372,6 +394,7 @@ impl <'a> ActiveFlasher<'a, Erase> {
None,
false
)?;
log::debug!("Done erasing sector. Result is {}", result);
if result != 0 {
Err(FlasherError::EraseSector(result, address))

7
probe/src/flash/loader.rs

@ -194,6 +194,11 @@ impl<'a, 'b> FlashLoader<'a, 'b> {
builders.sort_unstable_by_key(|v| v.1.flash_start);
let sorted = builders;
for builder in sorted {
log::debug!(
"Using builder for region (0x{:08x}..0x{:08x})",
builder.0.range.start,
builder.0.range.end
);
// Program the data.
let chip_erase = Some(if !did_chip_erase { self.chip_erase } else { false });
builder.1.program(
@ -202,7 +207,7 @@ impl<'a, 'b> FlashLoader<'a, 'b> {
self.smart_flash,
self.trust_crc,
self.keep_unwritten
);
).unwrap();
did_chip_erase = true;
}

4
probe/src/flash/memory.rs

@ -12,8 +12,8 @@ pub const PROGRAM_PAGE_WEIGHT: f32 = 0.130;
pub const ERASE_SECTOR_WEIGHT: f32 = 0.048;
pub const ERASE_ALL_WEIGHT: f32 = 0.174;
#[derive(Derivative, Debug, Clone)]
#[derivative(PartialEq, Eq, Hash)]
#[derive(Derivative, Clone)]
#[derivative(Debug, PartialEq, Eq, Hash)]
pub struct FlashRegion {
pub range: core::ops::Range<u32>,
pub is_boot_memory: bool,

Loading…
Cancel
Save