2

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

しかし、ハンドラーも変更したい場合、これに他のトリックが含まれていないことを100%確信しているわけではありませんcurrent_screen

それに近づくためのより良い方法はありますか?いくつかの良いイディオム?

4

1 に答える 1

3

ダブルバッファリングを使用できます。

つまり、2 つの関数ポインターの配列と現在のポインターへのインデックスを使用します。非現行ポインターを新しい値に設定してから、インデックスを切り替えます。インデックスは小さい (0 または 1) 設定であるため、アトミックです。

変更中にポインターにアクセスするタスクが、次の変更によって妨げられるほど長く中断されないようにする必要があります。

于 2010-07-17T17:48:00.200 に答える