Подвисающий I2C

Oct 04, 2019 21:51


Одна из серьёзных проблем опенсорса, особенно опенсорс-эмбеддеда - многое разрабатывается в университетах, поэтому и отлаживается в условиях университетской лаборатории, в которой в прыжке есть двадцать плат по одному датчику на каждой.

В результате совершенно в общем-то довольно понятные в продакшене вещи часто реализуются примерно никогда.

Сегодня, скажем, добавили в драйвер I2C в RIOT OS буквально пять строчек: при инициализации I2C пощупать уровень SDA, если он 0, то подёргать туда-обратно SCL, пока SDA не станет 1.

Зачем?

Да элементарно: если ваша плата почему-то перезагрузилась в момент опроса датчика на I2C, оный датчик запросто может оказаться в состоянии, в котором он притягивает SDA к нулю и смиренно ждёт продолжения SCL, чтобы отдать оставшиеся битики, которые у него успели попросить перед перезагрузкой. Ждать он готов вечно, а вот тот же nRF52 такое состояние шины определяет - и передавать по ней ничего не спешит.

Результат - RIOT'овский драйвер I2C, который просто в цикле while ждёт EVENTS_STOPPED или EVENTS_ERROR (и нет, таймаута там тоже нет), в этом случае тупо глухо виснет навсегда. Вотчдог не помогает, потому что после перезагрузки всё снова встаёт в ту же позу.
Previous post Next post
Up