Ошибка чтения / записи I2C при большой нагрузке прерывания

10

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

Обновить:

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

Update2:

Когда я подключаю к часам логический анализатор с помощью небольшого летающего кабеля, проблема исчезает. Интересно, что нет прерывания загрузки, чтение и запись работает хорошо, когда есть прерывание загрузки, они не делают. Однако, если я присоединяю зонд к часам, чтение-запись работает и при прерывании. Я думаю, что где-то есть проблема с емкостью.

Ktc
источник
1
Ваш вопрос очень общий, потому что все зависит от дизайна вашей системы. То, как I2C обращается, действительно зависит от устройств на шине. Можете ли вы игнорировать их и прийти к позже? В FPGA вы могли бы разработать логику, чтобы заботиться о вас и избегать этого. Опять же, нам нужна дополнительная информация о микроконтроллере и о том, что у вас есть. Обычно хорошим решением здесь является использование RTOS и правильное проектирование задач.
Густаво Литовский
Две вещи, на которые нужно обратить внимание: падение напряжения на подтягивающих устройствах или при подаче питания на главный и подчиненный i2c, а также проблемы с емкостью или емкостью. Что касается нагрузки прерывания, вы имеете в виду, что ваш мастер останавливается для обработки прерывания? Некоторые чипы не позволяют бесконечно растягивать часы.
Прохожий
@GustavoLitovsky Вы правы, но 80% циклов ЦП обслуживают прерывание АЦП, и у вас недостаточно времени, чтобы выполнить цикл чтения во время окна без ISR. Таким образом, чтение будет прервано независимо от того, насколько хорошо я проектирую систему ОС.
Ktc
@ Passerby вы можете быть правы. Проблема исчезла, когда я подключил зонд логического анализатора к линии синхронизации.
Ktc
Каково ваше текущее значение для подтягиваний. Вы пытались изменить их на другое значение? (Попробуйте 10k, 4k7 или 2k только для первого предположения)
Том Л.

Ответы:

9

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

Во-первых: вам нужно делать как можно меньше в прерываниях, только читать и хранить данные, не выполнять никакой обработки, которую вы могли бы выполнять за пределами ISR, математика может занять МНОГО циклов ЦП, а ЦП не может делать ничего другого. в то время как в этом прерывании.

Второе: исследуйте DMA, чтобы автоматизировать вещи, чтобы ваши прерывания стали почти фоновым автоматизированным процессом.

Третье: если важен I2C, включите ТА и в прерывание, но убедитесь, что вы решаете приоритеты!

В-четвертых: выясните, почему ваша процедура I2C дает сбой, сам I2C может выдерживать очень прерывистые периоды времени, паузы, ожидания и т. Д., Поэтому ваша процедура может нуждаться в изменении, чтобы позволить это.

Пятое. Посмотрите, можете ли вы «цеплять» прерывания, вы можете обнаружить, что можете более эффективно обслуживать считывания АЦП или перевести АЦП в другой режим, где он выполняет больше работы перед прерыванием (например, дождитесь, пока все показания не будут доступны, затем читать все в одном обращении, а не 8 отдельных прерываний для 8 отдельных операций чтения канала АЦП).

Шестое: используйте осциллограф или логический анализатор и запасные выводы ввода-вывода на плате, чтобы отслеживать, сколько времени вы тратите на каждый бит кода, чтобы увидеть, сможете ли вы его ускорить. (Установите высокий пин при входе в функцию / ISR, снова установите низкий при выходе).

Седьмое: Решите, если вам действительно нужно читать АЦП так много, будет ли хуже работать? Это нелогично, но иногда работает медленнее, на самом деле дает более хорошие результаты, выполняя работу по усреднению сигнала для вас и сокращая пики / переходные процессы, которые могут вызвать проблемы или потребовать дополнительной обработки для удаления. Мы улучшили процедуру PID управления двигателем, просто выполнив ее на 1/4 скорости, высвободив нагрузку из процессорного времени.

Джон У
источник
Спасибо за предложения. Проблема как-то указывает на железо.
Ktc
4

У ведомого автобуса, который занят другими вещами, есть возможность растягивать часы, чтобы выиграть время, пока он не сможет продолжить свою связь. Он делает это, не посылая немедленно тактовый импульс ACK / NACK, поддерживая связь в промежуточном состоянии, пока не будет готов ответить.

Растягивание часов - подходящий способ справиться с подобной ситуацией. Устройство, которое не растягивается и выполняет другие плохие действия (зависание / перезапуск шины, NACK-адрес, действительный адрес или команда и т. Д.), Может быть проблематичным и накладывать дополнительную нагрузку на мастер, чтобы он не разбирался (он должен повторять команды , следить за NACKs и т. д.)

Адам Лоуренс
источник
Вы правы, но проблема в хозяине. Хозяин занят другими вещами, а не рабом. Так что не уверен, что смогу растянуть часы.
Ktc
Используете ли вы встроенное аппаратное обеспечение I2C или используете протокол GPIO? В стандарте нет определенного интервала времени ожидания I2C, поэтому ведомые должны неопределенно долго ждать, пока мастер завершит пакет.
Адам Лоуренс
Я использую API-интерфейсы STM32 IC2. Пожалуйста, смотрите обновление, похоже, проблема с емкостью.
Ktc
1

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

  • Прерывания для чего-либо обычно могут быть отключены. В любом обычном контроллере имеется не более одного или двух немаскируемых прерываний, одно из которых сбрасывается. Если вам не нужен управляемый прерываниями контроль чего-либо (в вашем случае АЦП или I2C), то превратите этот периферийный код в код, не использующий прерывания, а затем отключите прерывания.

  • Обработчики прерываний не должны быть длинными. Постарайтесь сделать как можно меньше из самого вектора прерывания. Экстремальный минималистический подход к прерываниям состоит в том, чтобы просто установить флаг из подпрограммы обработчика прерываний и, скажем, с помощью основного цикла выполнить всю тяжелую работу с этого момента. То, что требует ваше конкретное приложение и архитектура прошивки, может быть не таким простым, как это, но действительно стоит приложить усилия, чтобы увидеть, сколько действительно нужно сделать из прерываний.

  • Если у вас есть периферийный DMA, используйте его вместо прерывания на каждый байт. Как правило, было бы проще поставить АЦП на DMA, а не на I2C, но разные чипы имеют разные реализации. Я не удивлюсь, если бы существовал чистый способ отменить обмен I2C на DMA. DMA позволяет сократить количество прерываний и освобождает ядро ​​процессора от необходимости обрабатывать каждый блок данных.

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

РЕДАКТИРОВАТЬ: Некоторые конкретные заметки, касающиеся этого случая проблемы, из ваших комментариев к вопросу:

  • Использование 80% ЦП для чтения АЦП, как правило, не стоит делать. Сбор данных бесполезен, если вы не можете на него воздействовать или даже сохранять данные.
  • Даже если вы каким-то образом собираете (с пользой) огромный объем данных, прерывания АЦП не должны быть такими длинными, чтобы полностью подавить периферийное устройство I2C на время, достаточное для потери данных. I2C работает максимум на 100/400 кГц. Вам понадобится действительно очень длинное прерывание, чтобы прерывание было достаточно долгим, чтобы оно выглядело как нечто более серьезное, чем дрожание тактовой частоты на I2C.
Чинталагири Шашанк
источник
Спасибо. Наша система требует такого типа сложного и длинного ISR, это долгая история. Вы правы, хотя, I2C должен выдерживать даже при такой нагрузке прерывания, и это не может. Я подозреваю, что проблема в аппаратном обеспечении, см. Обновление.
Ktc
По моему опыту, большинство случаев использования, которые, по-видимому, требуют безумно длинного ISR, на самом деле заслуживают RTOS. И да, по вашим последним изменениям это кажется аппаратной проблемой. Попробуйте вставить небольшой конденсатор в линию, где находился ваш логический анализатор, и вы, вероятно, будете в порядке. Почему это необходимо, однако, несколько сложнее ответить. Я бы проверил подтягивающие резисторы I2C (может быть слишком низко для вашей шины) и проверил таблицы любых буферов / репитеров I2C, которые вы можете использовать.
Чинталагири Шашанк
0

В данной системе может быть шум, поступающий на часы и шины данных. Тот факт, что ваш логический анализатор устраняет проблему, показывает это. Для практической и быстрой реализации просто следуйте подсказке, данной вашим наблюдением. На шине i2c с реализацией 400 кбит / с, основанной на аналогичных наблюдениях, я подключил 2M параллельно с 12pf к земле из точек синхронизации и данных и обнаружил, что проблема решена. Это удаляет / фильтрует шум вне интересующей полосы, необходимой для конкретной связи i2c. Пожалуйста, попробуйте и посоветуйте.

user41360
источник