我开始在atmega8上的应用程序中实现类似于任务切换的功能。主要思想是指向“当前屏幕”结构的指针。 “当前屏幕”包含用于刷新屏幕,处理按钮和中断的处理程序。
不幸的是我发现更改函数指针是在2个操作中完成的。这意味着当current_screen->handle_signal(...);
部分更改时,某些中断可能会尝试执行current_screen
。由于处理精确的时序,我不能在更改期间禁用和重新启用中断。设置一个关于正在更改的处理程序的标志可以起到作用,因为我不关心在任务更改过程中丢失一些中断(但是处理那些我不能错过的内容会变得有点困难)。
我考虑过在更改过程中将current_screen
复制到current_screen_old
并设置标记,如下所示:
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
但是,如果处理程序也希望更改current_screen
,我不能100%确定这不会包含其他一些技巧。
有没有更好的方法来接近它?一些好的习语?
答案 0 :(得分:3)
您可以使用双缓冲。
也就是说,使用两个函数指针的数组和当前指针的索引。将非当前指针设置为新值,然后切换索引。由于索引很小(0或1),因此设置为原子。
您需要确保在更改期间没有任何访问指针的任务可以暂停足够长的时间,以免受到下一次更改的干扰。