Last active
October 30, 2024 01:54
-
-
Save kammce/86db7895c798cc719481c9b303845a14 to your computer and use it in GitHub Desktop.
A means to escape from an infinite loop using C++ exceptions and interrupts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void read_sensor_data(hal::i2c& p_device) | |
{ | |
hal::byte status = 0; | |
do { | |
status = hal::write_then_read<1>(p_device, | |
0x11, | |
std::to_array<hal::byte>({ 0xAA }), | |
hal::never_timeout())[0]; | |
} while (status & (1 << 5)); // but the sensor is dead 😱 !!! | |
} | |
void switch_to_emergency_shutdown_and_wait_for_input(); | |
void perform_task_in_250ms(); | |
namespace hal::cortex_m { | |
template<typename T, typename... Args> | |
void throw_from_interrupt(Args... p_args) | |
{ | |
throw T{ p_args... }; | |
} | |
} // namespace hal::cortex_m | |
void app(hal::timer& p_timer) | |
{ | |
using namespace std::chrono_literals; | |
bool switch_to_timed_out_handler = false; | |
while (true) { | |
try { | |
if (switch_to_timed_out_handler) { | |
switch_to_emergency_shutdown_and_wait_for_input(); | |
switch_to_timed_out_handler = false; | |
continue; | |
} | |
p_timer.schedule( | |
[&p_timer]() { | |
hal::cortex_m::throw_from_interrupt<hal::timed_out>(&p_timer); | |
}, | |
250ms); | |
perform_task_in_250ms(); | |
p_timer.cancel(); | |
} catch (hal::timed_out const&) { | |
switch_to_timed_out_handler = true; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace hal::cortex_m { | |
template<typename T, typename... Args> | |
void pause_thread_and_throw(thread_id_t p_thread_id, Args... p_args) | |
{ | |
throw T{ p_args... }; | |
} | |
} // namespace hal::cortex_m | |
void read_sensor_data(hal::i2c& p_device) | |
{ | |
hal::byte status = 0; | |
do { | |
status = hal::write_then_read<1>(p_device, | |
0x11, | |
std::to_array<hal::byte>({ 0xAA }), | |
hal::never_timeout())[0]; | |
} while (status & (1 << 5)); // but the sensor is dead 😱 !!! | |
} | |
void worker_thread() | |
{ | |
using namespace std::chrono_literals; | |
while (true) { | |
try { | |
if (hold_for_input()) { | |
continue; | |
} | |
perform_task_in_250ms(); | |
sleep(time_remaining); | |
} catch (hal::timed_out const&) { | |
} | |
} | |
} | |
void watchdog_thread() | |
{ | |
using namespace std::chrono_literals; | |
while (true) { | |
if (worker_thread_stall_detected()) { | |
hal::freertos::pause_thread_and_throw<hal::timed_out>(thread_id); | |
} | |
sleep(250ms); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment