Использование millis() несинхронизированным образом
Я предполагаю, что millis() является функцией ISR таймера. Если так : При использовании millis (), как указано в справочнике Arduino : unsigned long currentMillis = millis(); Что произойдет, если ISR асинхронно изменит значение, считываемое в функции. Я имею в виду, если я прочитал один байт в currentMillis, но millis изменил значение, прежде чем остальные 7 байтов будут прочитаны.
Ура и ТИА
@EmbSysDev, 👍0
Обсуждение1 ответ
Лучший ответ:
Я предполагаю, что millis() является функцией ISR таймера.
Это функция, которая извлекает значение, которое обновляется и ISR.
Что произойдет, если ISR асинхронно изменит значение , считываемое в функции.
Не может произойти: значение считывается с отключенными прерываниями.
См., например, в ядре AVR:
// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
m = timer0_millis;
SREG = oldSREG;
Я имею в виду, если я прочитал один байт в currentMillis, но миллис изменил значение до того, как были прочитаны оставшиеся 7 байтов.
unsigned long
составляет всего 4 байта. То есть до тех пор, пока кто-то не придет с
64-битной платформой Arduino.
Конечно, 64-битный Arduino с 2 кб оперативной памяти :-), @PMF
@Edgar Bonet ,Просто в качестве отступа ( я на самом деле пишу функцию millis() like для другого uC ) : Допустимо ли, скажем , использовать бит блокировки для предотвращения чтения во время обновления переменной по таймеру вместо отключения прерывания? Большое спасибо !, @EmbSysDev
@EmbSysDev: Нет необходимости “предотвращать чтение во время обновления переменной таймером”: ISR не прерывается, поэтому ничто не может прочитать переменную во время ее обновления. Вам необходимо предотвратить обновление, пока основная программа его читает., @Edgar Bonet
@EdgarBonet: cli() отключает все прерывания, поэтому слишком много вызовов millis() повлияет на все события, основанные на прерываниях.Разве не было бы достаточно отключить только TIM0 ? В функции они, похоже, снова не включают прерывания, выполняется ли это в другом месте(в противном случае прерывание не было бы включено).Имело бы смысл снова включить прерывания перед выходом из millis() ? Спасибо, что уделили мне время !, @EmbSysDev
@EmbSysDev: Вы действительно можете выборочно отключить TIM0, хотя это займет на несколько циклов больше, чем " cli ()". Этот критический раздел очень короткий, поэтому здесь подойдет глобальное отключение прерываний. Повторите “ _ они, похоже, больше не включают прерывания”: именно это делает " SREG = oldSREG;": повторно включите прерывания, но только если они были изначально включены при вызове функции., @Edgar Bonet
- Как справиться с rollover millis()?
- Использование millis() и micros() внутри процедуры прерывания
- ардуино - миллисекунды ()
- Кнопка с таймером переключения и функцией сброса времени + светодиод обратной связи
- Использовать timer0, не влияя на millis() и micros().
- Торговый автомат Arduino для мониторинга ввода монет в слот во время ожидания ввода пользователя
- Влияет ли `millis()` на длинные ISR?
- nodeMCU — Millis() — Простой счетчик — Как долго горит светодиод?
Разработчик встраиваемых систем? загляните в исходный код millis (), прежде чем спрашивать, @Juraj