安全的“任务切换”在 ATmega 芯片上

发布于 2024-09-10 04:30:38 字数 800 浏览 5 评论 0原文

我开始在 atmega8 上的应用程序中实现类似于任务切换的功能。主要思想是有一个指向“当前屏幕”结构的指针。 “当前屏幕”包含用于刷新屏幕、处理按钮和中断的处理程序。

不幸的是,我发现更改函数指针需要两次操作才能完成。这意味着在 current_screen 部分更改时,某些中断可能会尝试执行 current_screen->handle_signal(...); 操作。由于要处理精确的计时,我不能在该更改期间禁用并重新启用中断。设置一个关于正在更改的处理程序的标志可以解决这个问题,因为我不太关心在任务更改过程中错过一些中断(但是处理那些我不能错过的中断会变得有点困难)。

我考虑过在更改期间将 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

但我不能 100% 确定这不包含其他一些技巧,如果处理程序也想更改 current_screen

有没有更好的方法来处理它?有哪些好的成语?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌辣 2024-09-17 04:30:38

您可以使用双缓冲。

也就是说,使用一个由两个函数指针和当前函数指针的索引组成的数组。将非当前指针设置为新值,然后切换索引。由于索引很小(0 或 1),因此它是原子的。

您需要确保在更改期间访问指针的任务不会被挂起足够长的时间,以免受到下一次更改的干扰。

You can use double buffering.

That is, use an array of two function pointers and an index to the current one. Set the non-current pointer to the new value, then toggle the index. Since the index is small (0 or 1) setting it is atomic.

You need to make sure that no task accessing the pointer during a change can be suspended long enough to be disturbed by the next change.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文