diff --git a/bsp_z7/main.c b/bsp_z7/main.c index 4e28bc4..dc0758d 100644 --- a/bsp_z7/main.c +++ b/bsp_z7/main.c @@ -15,6 +15,8 @@ #include "xscutimer.h" #include "xuartps_hw.h" +#include + /* * Configure the hardware as necessary to run this demo. */ @@ -172,11 +174,21 @@ void vApplicationIdleHook(void) { management options. If there is a lot of heap memory free then the configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up RAM. */ - // xFreeHeapSpace = xPortGetFreeHeapSize(); + // xFreeHeapSpace = xPortGetFreeHeapSize(); // xMinimumEverFreeHeapSpace = xPortGetMinimumEverFreeHeapSize(); // /* Remove compiler warning about xFreeHeapSpace being set but never used. // */ (void)xFreeHeapSpace; (void)xMinimumEverFreeHeapSpace; +#ifdef LOW_LEVEL_TESTS +#define ERROR_MSG "\nPanic occured in the code executing the tests.\nWe'll consider this a failure:\n\ntest result: ❌ FAILED HORRIBLY\n" + // During low level tests, panics do not halt the execution but delete the current task. + // If this happens in the initial task, only the idle task remains. In this case, we + // simply end the execution. + + write(2, ERROR_MSG, sizeof(ERROR_MSG)); + + done_error(); +#endif } void vApplicationTickHook(void) { diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index f85ca3c..bd7090c 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -1,9 +1,15 @@ -#![no_std] +#![cfg_attr( + not(test), + no_std +)] + + #![feature(never_type)] //TODO os errors in API calls mod dh; pub mod fsrc; +#[cfg(not(test))] mod panic; #[cfg(feature = "low_level_tests")] @@ -36,7 +42,7 @@ extern "C" fn rust_main() { // we are already in a task (init task started by C), so we can use all APIs safely, // but start a new init task anyway to be able to control that task's stack here sifln!("Rust startup 🚀"); - THREAD_INIT.take_no_init().unwrap().spawn(init_task); + THREAD_INIT.take_no_init().unwrap_or_else(|| {loop{}}).spawn(init_task); // delete self, init task will take over thread::current().delete(); } @@ -188,10 +194,6 @@ static THREAD_3: StaticReadOnceLock< Duration::from_millis(200), )); -extern "C" { - fn done() -> !; -} - fn init_task() -> ! { sifln!("Mission enter"); @@ -208,10 +210,9 @@ fn init_task() -> ! { Duration::from_millis(500), 0.5, ); - + debugger.run().unwrap(); - panic!("done"); // let test1 = TEST1.take().unwrap(); // let test2 = TEST2.take().unwrap(); @@ -239,3 +240,10 @@ fn init_task() -> ! { sifln!("=====================Mission delete"); osal::thread::current().delete(); } + +#[test] +fn panic_test() { + println!("print"); + let test1 = TEST1.take().unwrap(); + panic!("oh noes"); +} diff --git a/mission_rust/src/low_level_tests/mod.rs b/mission_rust/src/low_level_tests/mod.rs index 872654b..8aff260 100644 --- a/mission_rust/src/low_level_tests/mod.rs +++ b/mission_rust/src/low_level_tests/mod.rs @@ -1,8 +1,8 @@ //! Low level tests which need to be run with FreeRTOS present //! -//! They can not be run as standard rust tests as the depend on the C code. +//! They can not be run as standard rust tests as they depend on the C code. //! As such this module is to be linked -//! as part of the main library into the low level C code. +//! as part of the main library with the low level C code. //! //! Entry into the tests is provided by the extern "C" function //! rust_low_level_tests() to be called from C. It is assumed to be running in an init Thread @@ -64,6 +64,8 @@ fn run_tests(tests: &mut [(fn(), &'static str)]) -> ! { let stack = TEST_RUNNER_STACK.take_no_init().unwrap(); let thread_data = TEST_RUNNER_THREAD_DATA.take_no_init().unwrap(); + panic!("oh noes"); + let number_of_tests = tests.len(); sifln!(); @@ -79,7 +81,10 @@ fn run_tests(tests: &mut [(fn(), &'static str)]) -> ! { let mut failed = 0; for test in tests { - // std::io::stdout().flush().unwrap(); + // Note for the pedantic: Static FreeRTOS can not delete tasks, only + // suspend them. So it is not formally correct to resuse the task data + // and stack. But as the suspended task will not be restarted, it does work + // in this (testing!) context. let test_function = test.0 as *const core::ffi::c_void; unsafe { osal::ffi::freertos_create_task_static( diff --git a/mission_rust/src/panic.rs b/mission_rust/src/panic.rs index 1f06dc2..0e44433 100644 --- a/mission_rust/src/panic.rs +++ b/mission_rust/src/panic.rs @@ -12,7 +12,6 @@ extern "C" { fn freertos_task_notify(task: *const core::ffi::c_void, value: u32); } -#[cfg(not(test))] #[panic_handler] fn panic(panic: &PanicInfo<'_>) -> ! { // unsafe { this breaks in ISR