Recover from process faults
And add cat test task to test faulting
-use core::{slice, num::ParseIntError};
+use core::{num::ParseIntError, slice};
use crate::stdlib;
}
b => {
inbuf[i] = b;
- stdlib::write(&inbuf[i .. i + 1]);
+ stdlib::write(&inbuf[i..i + 1]);
i += 1;
}
}
"r" => {
let astr = parts.next().ok_or(CommandError::NeedArgument)?;
let mut aparts = astr.split('.');
- let from = aparts.next().map(|s| u32::from_str_radix(s, 16)).ok_or(CommandError::BadAddress)??;
+ let from = aparts
+ .next()
+ .map(|s| u32::from_str_radix(s, 16))
+ .ok_or(CommandError::BadAddress)??;
print_hex_u32(from);
stdlib::print(": ");
match aparts.next() {
"q" => {
stdlib::exit();
}
- "dog" => {
- let tid = stdlib::spawn(dog);
+ "dog" | "cat" => {
+ let tid = stdlib::spawn(if cmd == "cat" { cat } else { dog });
if tid == 0xFFFFFFFF {
- stdlib::print("Failed to launch dog\r\n");
+ stdlib::print("Failed to launch ");
+ stdlib::print(cmd);
+ stdlib::print("\r\n");
} else {
- stdlib::print("spawned dog at tid ");
+ stdlib::print("spawned ");
+ stdlib::print(cmd);
+ stdlib::print(" at tid ");
print_hex_u32(tid);
stdlib::print("\r\n");
}
Ok(())
- },
+ }
"ps" => {
stdlib::ps();
Ok(())
stdlib::kernel_panic();
Ok(())
}
- _ => {
- Err(CommandError::BadCommand)
- }
+ _ => Err(CommandError::BadCommand),
}
}
}
}
+fn cat(_base: u32, _size: u32) -> ! {
+ stdlib::sleep(1000);
+ unsafe {
+ let p = 0x4000 as *const u32;
+ let b = *p;
+ stdlib::sleep(b);
+ }
+ stdlib::exit();
+}
+
fn dog(_base: u32, _size: u32) -> ! {
for _ in 0..10 {
stdlib::print("woof\r\n");
stdlib::sleep(1500);
}
stdlib::exit();
-}
\ No newline at end of file
+}
use core::arch::global_asm;
+use cortex_m::peripheral::SCB;
+
use crate::console::flush;
use crate::kprintf;
-use crate::task::TaskRegisters;
+use crate::task::{TaskRegisters, with_task_manager};
fn print_regs(regs: &TaskRegisters) {
kprintf!(
movs r2, 2 // shift the thread mode flag right so it's a
rors r1, r2 // bool and it's the second argument
push {{lr}} // save LR
+
bl hardfault_handler // call the handler
- // TODO: kill process and continue
+
+ pop {{r0}}
+ add sp, #68 // pop everything off the stack. Restoring the
+ // registers is irrelevant; the process is crashing.
+ bx r0 // exit the handler
"#
);
#[no_mangle]
-unsafe fn hardfault_handler(regs: &mut TaskRegisters, thread_mode: bool) -> ! {
+unsafe fn hardfault_handler(regs: &mut TaskRegisters, thread_mode: bool) {
kprintf!(
"\r\nHardFault! ({})\r\n",
if thread_mode { "thread" } else { "handler" }
let scb = &(*cortex_m::peripheral::SCB::PTR);
kprintf!("ICSR: {:08X}\r\n", scb.icsr.read());
flush();
- cortex_m::interrupt::disable();
- loop {}
+ if thread_mode {
+ // kill the process and invoke the scheduler
+ with_task_manager(|tm| {
+ tm.exit_current_task();
+ });
+ SCB::set_pendsv();
+ } else {
+ // Can't go nowhere from here
+ cortex_m::interrupt::disable();
+
+ loop {}
+ }
}