I started implementing something similar to task switching in my app on atmega8. The main idea is that there's a pointer to a "current screen" structure. The "current screen" contains handlers for refreshing the screen, handling buttons and interrupts.
Unfortunately I discovered that changing a function pointer is done in done in 2 operations. That means some interrupt may try to do current_screen->handle_signal(...);
while current_screen
is partly changed. Due to handling precise timing, I cannot just disable and reenable interrupts during that change. Setting a flag about the handler being changed could do the trick, since I don't care that much about missing some interrupts in the middle of the task change (but then handling those I cannot miss becomes a bit harder).
I thought about copying current_screen
to current_screen_old
during the change and setting a flag, like this:
current_screen_old = current_screen; // safe to call current_screen->handler
during_update = 1; // safe to call current_screen_old->handler
current_screen = new_value;
during_update = 0; // safe to call current_screen->handler again
But I'm not 100% sure this doesn't contain some other tricks if the handler wants to change current_screen
too.
Is there some better way to approach it? Some good idioms?