Безопасное «переключение задач» на чипах ATmega - PullRequest
2 голосов
/ 17 июля 2010

Я начал реализовывать нечто похожее на переключение задач в моем приложении на 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.

Есть ли лучший способ приблизиться к нему?Некоторые хорошие идиомы?

1 Ответ

3 голосов
/ 17 июля 2010

Вы можете использовать двойную буферизацию.

То есть использовать массив из двух указателей на функции и индекс для текущего.Установите нетоковый указатель на новое значение, затем переключите индекс.Поскольку индекс мал (0 или 1), он является атомарным.

Необходимо убедиться, что ни одна задача, обращающаяся к указателю во время изменения, не может быть приостановлена ​​на достаточно длительное время, чтобы помешать следующему изменению.

...