Skip to content

Instantly share code, notes, and snippets.

@kammce
Last active October 30, 2024 01:54
Show Gist options
  • Save kammce/86db7895c798cc719481c9b303845a14 to your computer and use it in GitHub Desktop.
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
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;
}
}
}
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