commit:216019724c599d986037f7e1971255e80a1dff28
author:Chip
committer:Chip
date:Sun Oct 1 01:37:35 2023 -0500
parents:f24046721d9c2fa161e3faefe6add3fa039ec8f3
Recover from process faults

And add cat test task to test faulting
diff --git a/src/apps/shell.rs b/src/apps/shell.rs
line changes: +27/-12
index 97d2481..9ea8c6c
--- a/src/apps/shell.rs
+++ b/src/apps/shell.rs
@@ -1,4 +1,4 @@
-use core::{slice, num::ParseIntError};
+use core::{num::ParseIntError, slice};
 
 use crate::stdlib;
 
@@ -40,7 +40,7 @@ fn readline(buf: &mut [u8]) -> Option<&str> {
                 }
                 b => {
                     inbuf[i] = b;
-                    stdlib::write(&inbuf[i .. i + 1]);
+                    stdlib::write(&inbuf[i..i + 1]);
                     i += 1;
                 }
             }
@@ -81,7 +81,10 @@ fn parse_cmdline(cmdline: &str) -> Result<(), CommandError> {
         "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() {
@@ -111,17 +114,21 @@ fn parse_cmdline(cmdline: &str) -> Result<(), CommandError> {
         "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(())
@@ -133,9 +140,7 @@ fn parse_cmdline(cmdline: &str) -> Result<(), CommandError> {
             stdlib::kernel_panic();
             Ok(())
         }
-        _ => {
-            Err(CommandError::BadCommand)
-        }
+        _ => Err(CommandError::BadCommand),
     }
 }
 
@@ -156,10 +161,20 @@ pub fn shell(base: u32, _size: u32) -> ! {
     }
 }
 
+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
+}

diff --git a/src/hardfault.rs b/src/hardfault.rs
line changes: +22/-5
index b2e7f60..1525891
--- a/src/hardfault.rs
+++ b/src/hardfault.rs
@@ -1,8 +1,10 @@
 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!(
@@ -89,13 +91,18 @@ HardFault:
     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" }
@@ -109,7 +116,17 @@ unsafe fn hardfault_handler(regs: &mut TaskRegisters, thread_mode: bool) -> ! {
     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 {}
+    }
 }