Обсуждаем контроллеры компании Atmel.
Ответить

Atomic операции

Сб июн 12, 2021 13:47:14

Здравсвуйте.
Можно поинтересоваться, что это за операция и для чего она нужна?
Например. в AVR есть util/atomic.h библиотека.
Где ее используют?
Желательно простым языком.

Мне нужно ответить на вопрос, равносильна ли подобная библиотека инструкции JBC (8051 архитектура)?
JBC инструкции нет на AVR, и поэтому нужна библиотека util/atomic.h для эмуляции этой операции(отключение прерывания и прочее).

Как я понял, это нужно для исключения одновременного доступа к переферии в процессе опроса или установки параллельных процессов?
Или просто выполнение функции в обход прерывания(его отключение на время выполнения) с высоким приоритетом?
Спасибо.

Re: Atomic операции

Сб июн 12, 2021 16:17:50

Смотрите. МК 8-битный.
И он обрабатывает данные побайтово.
А теперь представьте. У вас есть какая то 16-битная переменная.
В нее по прерыванию записывается какая то фаза луны.
А в основной программе вы на основании этой фазы луны строите какие то биоритмы приливов на Марсе.

И представьте, МК начинает считывать из ОЗУ в свои регистры значение этой переменной. Считал первый байт. А тут прилетает прерывание и МК всё бросает и бежит это прерывание обслуживать. А в прерывании записалась новая фаза луны. Прерывание закончилось и МК возвращается к продолжению основной программы. А основная программа не знает о том, что фаза луны уже новая. И считывает второй байт. В результате у вас один байт от предыдущего значения фазы, а второй - от новой.

Это самый простой сценарий. Сложнее, когда одна и та же переменная модифицируется как из прерывания, так и из основной программы. Например, это какой то массив флагов разных.
Прерывания устанавливают флаги, программа их отслеживает и сбрасывает.
Есть переменная, в ней есть флаг №1. Программа увидела флаг, выполнила нужные действия и должна сбросить флаг.
Для этого МК считывает байт памяти в регистр, сбрасывает бит флага и сохраняет байт обратно в ОЗУ.
А представьте, что программа байт считала.... И тут прилетело прерывание и установило в переменной флаг №2. .... Дальше программа сбрасывает флаг №1 в своей копии этого байта и сохраняет этот байт обратно в ОЗУ, затирая значение с флагом №2. Результат - флаг №2 потерян.

Вот что бы при работе с такими переменными не помешало никакое прерывание - такие участки кода должны быть атомарными - неделимыми.
Для этого в начале кода нужно запретить прерывания (CLI), а в конце - разрешить (SEI).
Вот эта библиотека atomic.h как раз и реализует удобную "обертку", всего лишь вставляя инструкции CLI и SEI в начале и конце участка программы.

Кстати, атомарной может быть не только работа с переменными, а и какой то критичный ко времени ногодрыг. Тот же 1Wire.

ПС. В случае написания программы на Си переменные, которые могут модифицироваться в прерывании или прерывание будет использовать их значения, должны быть объявлены как volatile, иначе оптимизатор может натворить неочевидных и неприятных вещей.

Re: Atomic операции

Пн июн 14, 2021 11:51:26

В дополнение к тому, что написал GoldenAndy, добавлю еще что еще в целом "подвох" бывает в ситуация Чтения-Модификация-Запись. И не всегда отключением прерывания можно решить. В старых мегах, к примеру, где не было регистров PINх, Чтение-Модификация-Запись из регистра PORTx могла привести к проблемам, если внешний уровень на пине менялся в это время.
PORTxn |= 1 << 1 - это пример Чтения-Модификации-Записи. Потому что из одной строки Си, это развернется в 3 инструкции МК и между ними может что-то произойти.

Re: Atomic операции

Пн июн 14, 2021 12:56:42

NStorm, ну тут уже никак не отследить....
Хотя я как то анализировал, инструкцию установки/сброса одного бита в порту компилятор превращает в инструкцию SBI / CBI, которая должна работать атомарно.

Re: Atomic операции

Пн июн 14, 2021 13:54:48

Да, кстати одинарный бит обычно атомарно будет менятся. А вот 2 и более - уже нет. Неправильный пример привел. Для Чтения-Модификации-Записи правильный пример примерно такой:
PORTxn |= (1 << Px0) | (1 << Px1);

Re: Atomic операции

Пн июн 14, 2021 17:05:40

NStorm, тоже зависит от оптимизации.
При оптимизации по размеру только три и более бита меняются на IN, SBR/CBR, OUT (в пределах первых 64 регистров :) )
Но это уже тонкости.
ПС. И кстати, а какие это меги, у которых нету PINx ?
а то я начинал тернистый путь МК с тини2313 и меги8...

Re: Atomic операции

Вт июн 15, 2021 09:53:35

GoldenAndy, пока писал, часть мысли потерял и написал неправильно. Не полностью PINx нет, а нет функционала переключения уровней через запись в PINx. В атмеге8 нет такого, к примеру. А в тини10, к примеру, есть:
11.2.2 Toggling the Pin
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.
Ответить