AVR: основное () / помехи ISR - PullRequest
       23

AVR: основное () / помехи ISR

0 голосов
/ 23 января 2019

Я использую I2C на ATmega168 (slave) в C (компилирование с помощью avr-gcc), но это может быть общий вопрос о прерываниях.

В моей программе на C есть глобальная переменнаявведите uint8_t i2c_buffer[32], чтобы сохранить некоторые данные датчика и конфигурации.К этому массиву также обращается I2C-ISR всякий раз, когда мастер шины выполняет чтение или запись в ведомое устройство.Поскольку связь осуществляется аппаратно, передача в оперативную память (моя буферная переменная I2C) запускается прерыванием.

Я понимаю, что небрежный доступ к переменной из ISR и основной процедуры может привести к повреждению данных из-за гонки.условие между ISR и моей основной рутиной, но я не уверен, как справиться с этим должным образом.Мне сказали отключить прерывания, пока main обращается к рассматриваемой переменной.Это защитит переменную от повреждения, но не приведет ли это к потере данных с другой стороны?Что, если мастер попытается отправить данные, пока прерывания отключены?

Я полагаю, поскольку интерфейс I2C все еще включен, входящий байт будет, по крайней мере, записан в TWDR.Это верно?Если да: есть ли способ вызвать ISR сразу после того, как основная подпрограмма закончила доступ к переменной?

И: сохраняется ли эта проблема, если один экземпляр (ISR или основной) только читает и не пишет вконкретные части буфера?

1 Ответ

0 голосов
/ 23 января 2019

В общем случае вам необходимо создать критический раздел в основном процессе (основной программе).Вам нужно отключить прерывания, когда ваша основная программа обращается к общей переменной.

У вас есть готовое стандартное решение:

 #include <util/atomic.h>

 /* ....*/ 

 ATOMIC_BLOCK(ATOMIC_FORCEON)
 {
     /* potentially non atomic opeartions */
 }
...