blob: 1e55bb38b776a99c001cb0cd8e32c3d0981a84a7 [file] [log] [blame]
//! Heapless debugging functions for Tock troubleshooting
mod low_level_debug;
use crate::drivers::Drivers;
pub use low_level_debug::*;
use crate::retrieve_drivers_unsafe;
pub fn println() {
let buffer = [b'\n'];
let Drivers { console_driver, .. } = unsafe { retrieve_drivers_unsafe() };
let mut console = console_driver.create_console();
let _ = console.write(&buffer);
}
pub fn print_as_hex(value: usize) {
let mut buffer = [b'\n'; 11];
write_as_hex(&mut buffer, value);
let Drivers { console_driver, .. } = unsafe { retrieve_drivers_unsafe() };
let mut console = console_driver.create_console();
let _ = console.write(buffer);
}
#[cfg(target_arch = "arm")]
pub fn print_stack_pointer() {
let stack_pointer;
unsafe { asm!("mov $0, sp" : "=r"(stack_pointer) : : : "volatile") };
let mut buffer = [b'\n'; 15];
buffer[0..4].clone_from_slice(b"SP: ");
write_as_hex(&mut buffer[4..15], stack_pointer);
let Drivers { console_driver, .. } = unsafe { retrieve_drivers_unsafe() };
let mut console = console_driver.create_console();
let _ = console.write(buffer);
}
#[cfg(target_arch = "riscv32")]
pub fn print_stack_pointer() {}
#[inline(always)]
/// Dumps address
/// # Safety
/// dereferences pointer without check - may lead to access violation.
pub unsafe fn dump_address(address: *const usize) {
let mut buffer = [b' '; 28];
write_as_hex(&mut buffer[0..10], address as usize);
buffer[10] = b':';
write_as_hex(&mut buffer[12..22], *address);
for index in 0..4 {
let byte = *(address as *const u8).offset(index);
let byte_is_printable_char = byte >= 0x20 && byte < 0x80;
if byte_is_printable_char {
buffer[23 + index as usize] = byte;
}
}
buffer[27] = b'\n';
let Drivers { console_driver, .. } = retrieve_drivers_unsafe();
let mut console = console_driver.create_console();
let _ = console.write(&buffer);
}
/// Dumps arbitrary memory regions.
/// # Safety
/// dereferences pointer without check - may lead to access violation.
pub unsafe fn dump_memory(start_address: *const usize, count: isize) {
let range = if count < 0 { count..0 } else { 0..count };
for offset in range {
dump_address(start_address.offset(offset));
}
}
fn write_as_hex(buffer: &mut [u8], value: usize) {
write_formatted(buffer, value, 0x10_00_00_00, 0x10);
}
fn write_formatted(buffer: &mut [u8], value: usize, start: usize, base: usize) {
let mut scanning = start;
let mut remainder = value;
let mut position = 2;
buffer[0..2].clone_from_slice(b"0x");
while scanning > 0 {
let digit = remainder / scanning;
buffer[position] = render_digit(digit as u8) as u8;
remainder %= scanning;
scanning /= base;
position += 1;
}
}
fn render_digit(digit: u8) -> char {
if digit < 10 {
(b'0' + digit) as char
} else {
(b'a' + digit - 10) as char
}
}