Помилка читання / запису I2C при сильному навантаженні переривання


10

У своїй системі я використовую I2C і розумію, що під великим навантаженням переривання (з інших джерел) зв’язок I2C легко порушується. Це очікувана поведінка для I2C? Я б очікував, незважаючи на навантаження на перерву, все одно буде нормально, оскільки I2C - це не зовсім критичний за часом інтерфейс, годинник забезпечений даними.

Оновлення:

Процесор - STM32. Переривання через ADC, я не можу відключити переривання під час подій читання, тому я повинен знайти рішення, де я можу зробити зв’язок i2c більш стабільним. STM32 є головним, а підлеглий - ще одним пристроєм (акселерометром).

Оновлення2:

Коли я підключаю логічний аналізатор до годинника маленьким літаючим кабелем, проблема зникає. Цікаво, що немає навантаження переривання, читання записів працює добре, коли є навантаження переривання, вони не роблять. Однак якщо я приєднаю щуп до годинника, читання записів працює також під навантаженням переривання. Я думаю, десь є питання ємності.


1
Ваше запитання дуже загальне, оскільки все залежить від дизайну вашої системи. Як реально поводиться I2C, залежить від пристроїв на шині. Чи можете ви їх проігнорувати і прийти до пізніше? У FPGA ви можете розробити логіку, щоб подбати про вас багато і уникнути цього. Знову ж, нам потрібна додаткова інформація про мікроконтролер та які ще речі. Зазвичай хорошим рішенням тут є використання RTOS та правильне проектування завдань.
Густаво Литовський

Дві речі, на які слід звернути увагу, зменшення напруги на підключеннях або на живлення для вашого i2c-майстра і підлеглого, або емі або проблеми з ємністю. Що стосується навантаження на переривання, ти маєш на увазі, що твій господар перестає працювати з перериванням? Деякі чіпи не дозволять нескінченно розтягувати годинник.
Перехожий

@GustavoLitovsky ви маєте рацію, але 80% циклів процесора обслуговують переривання АЦП, і часу для читання циклу під час вікна, що не стосується ISR, не вистачає. Тож читання буде перервано незалежно від того, наскільки добре я проектую систему ОС.
Ktc

@Passerby ви можете мати рацію. Проблема зникла, коли я приєднав зонд логічного аналізатора до годинникової лінії.
Ktc

Яке ваше поточне значення для віджимань. Ви спробували змінити їх на інше значення? (Спробуйте 10k або 4k7 або 2k лише для першої здогадки)
Том Л.

Відповіді:


9

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

По-перше: вам потрібно робити якнайменше в перериваннях, лише читати та зберігати дані, не робити жодних обробок, які ви могли б робити за межами ISR. перебуваючи в тому перериванні.

По-друге: досліджуйте DMA, щоб автоматизувати речі, щоб ваші перерви стали майже фоновим автоматизованим процесом.

По-третє: Якщо I2C важливий, покладіть ТАК і на перерву, але переконайтеся, що ви опрацьовуєте пріоритети!

Четверте: Визначте, чому ваша програма I2C не працює, сам I2C може витримати дуже переривчасті терміни, паузи та очікування тощо, тому ваша програма може потребувати змін, щоб дозволити це.

По-п’яте: подивіться, чи можете ви "ланцюжкові" переривання, ви можете виявити, що ви можете обслуговувати зчитування АЦП ефективніше або перевести АЦП в інший режим, де він більше спрацьовує перед тим, як перервати (EG чекайте, коли всі читання будуть доступними, потім читайте все в один хіт, а не 8 окремих переривань для 8 окремих читань каналу АЦП).

По-шосте: Використовуйте осцилоскоп або логічний аналізатор і запасіть штифти IO на платі, щоб відстежити, скільки часу ви витрачаєте на кожен біт коду, щоб побачити, чи можете ви його прискорити. (Під час введення функції / ISR встановіть висоту шпильки, встановіть її знову низько при виході).

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


Дякуємо за пропозиції. Проблема якось вказує на обладнання.
Ktc

4

Раб автобуса, зайнятий іншими речами, має можливість годинникового розтягування, щоб придбати час, поки він не зможе перенести на свій кінець зв'язку. Це робиться, не одразу надсилаючи тактовий імпульс ACK / NACK, підтримуючи зв’язок у проміжному стані, поки він не готовий відповісти.

Розтягування годин - це відповідний спосіб вирішити подібну ситуацію. Пристрій, який не розтягується та робить інші погані речі (зависання / перезавантаження шини, невірна дійсна адреса чи команда тощо), може бути проблематичним і створює додаткове навантаження на майстра, щоб він не розбирався (він повинен повторювати команди , слідкуйте за NACK та ін.)


Ви маєте рацію, але проблема - у господаря. Господар зайнятий іншими речами, а не рабом. Тож не дуже впевнений, що я можу зробити розтяжку годинника.
Ktc

Ви використовуєте бортове обладнання I2C або біт-удари протоколу з ліній GPIO? У стандарті немає визначеного інтервалу часу очікування I2C, тому раби повинні чекати нескінченно часу, коли ведучий закінчить пакет.
Адам Лоуренс

Я використовую API STM32 IC2. Будь ласка, дивіться оновлення, це виглядає як проблема з ємністю.
Ktc

1

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

  • Перерви в чому-небудь зазвичай можуть бути відключені. У будь-якому звичайному контролері є максимум одна або дві не маскуючі переривання, один з яких скидається. Якщо вам не потрібно керувати перериванням через щось (у вашому випадку ADC або I2C), тоді перетворіть цей периферійний код на той, який не використовує переривання, а потім відключіть переривання.

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

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

  • Спробуйте визначити конкретні випадки, коли ви бачите пошкодження даних, та механізм, за яким відбувається пошкодження даних. Це зробити набагато складніше, але при творчому використанні сучасного осцилоскопа / логічного аналізатора ви зможете побачити деякі проблеми. Зокрема, переконайтеся, що проблема пов’язана із тимчасовим та не пам'яттю (що є можливістю поєднання жахливого коду та ліберального компілятора)

EDIT: Деякі конкретні зауваження щодо цього випадку проблеми, з ваших коментарів до питання:

  • Маючи 80% процесора, який використовується для читання АЦП, зазвичай це не варто. Збір даних марний, якщо ви не можете діяти на них або навіть зберегти дані.
  • Навіть якщо ви якимось чином збираєте (корисно) величезну кількість даних, переривання АЦП не повинно бути настільки довгим, щоб повністю придушити периферійну мережу I2C протягом достатнього часу, щоб вона втратила дані. I2C працює на максимум 100/400 кГц. Вам знадобиться дійсно, дуже довгий переривання, щоб перервати його досить довго, щоб зробити його схожим на щось більш серйозне, ніж тремтіння годинника на I2C.

Дякую. Наша система вимагає такого типу складних і довгих ISR, це довга історія. Ти маєш рацію, хоча I2C повинен підтримувати навіть під цим навантаженням переривання, і він не може. Я підозрюю, що проблема полягає в апаратному забезпеченні, дивіться оновлення.
Ktc

На мій досвід, на мій досвід, більшість випадків використання, які, здається, несуть шалено тривалий ІСС, - це фактично ті, які заслуговують на RTOS. І так, за останньою редакцією це здається апаратною проблемою. Спробуйте поставити невеликий конденсатор на лінію, де був ваш логічний аналізатор, і ви, напевно, будете добре. Чому це потрібно, хоча відповісти дещо складніше. Я перевірив би підтяжні резистори I2C (можливо, занадто низький для ємності шини) та перевірив таблиці даних будь-яких буферів / ретрансляторів I2C, які ви можете використовувати.
Chintalagiri Shashank

0

У даній системі може виникати шум, що надходить до годинника та шини даних. Це свідчить про те, що ваш логічний анлайзер усуває проблему. Для практичного та швидкого втілення просто дотримуйтесь підказки, заданої вашим спостереженням. На шині i2c з реалізацією 400 кбіт / сек на основі аналогічного спостереження я підключив 2M, паралельний з 12pf, до землі від тактових даних і точок даних, і виявив, що проблема вирішена. Це видаляє / фільтрує шум поза діапазоном, що цікавить, необхідний для конкретного зв'язку i2c. Будь ласка, спробуйте і порадьте.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.