Что вызывает ошибки UART?

8

Я хотел бы знать, почему возникают ошибки UART и когда следует проверять наличие таких ошибок. Здесь есть пост, в котором говорится об обработке отдельных ошибок, таких как переполнение, четность и т. Д. Я понимаю, почему происходит переполнение данных, почему происходит ошибка четности, но я хотел бы знать, что является основной причиной. Мой вопрос больше сфокусирован на том, почему эти ошибки могут возникать (физические причины), и когда нужно делать проверку ошибок как фактор их применения.

Пока что моя программа работает отлично (без проверки ошибок), но я знаю, что шум может все испортить. Как я могу имитировать условия, которые могут вызвать сбой портов UART Rx / Tx?

user791953
источник

Ответы:

8

Существует несколько потенциальных источников шума в любой цепи. Некоторые из наиболее распространенных включают в себя:

  • Плохо регулируемые источники питания;
  • Импульсные источники питания;
  • Недостаточная емкостная развязка силовых шин рядом с микроконтроллером;
  • Индуктивная связь соседних электромагнитных источников (в том числе 50 или 60 Гц от источника питания; даже если цепь питается от батареи, она будет испытывать эти помехи, когда достаточно близко к источнику питания);
  • Источники РЧ вблизи резонансной частоты следа на плате или одной из его гармоник;
  • Прокладка сильноточных трасс на плате возле сигнальных линий;
  • И т.п.

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

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

  • Замораживание (охлаждение контура до минимального номинала его компонентов);
  • Выпечка (нагрев до максимальной оценки);
  • Воздействие EMI :
    • Установите плату поверх шнура питания обогревателя;
    • Введите радио CB в непосредственной близости от платы;
    • Поместите плату рядом с вашим беспроводным маршрутизатором;
    • Используйте длинный соединительный провод (вместо правильно построенного последовательного кабеля) для соединения UART.

Есть много других - на самом деле, есть большие испытательные лаборатории, посвященные квалификации EMC .

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

Скотт Уиндер
источник
6

Одним из распространенных источников ошибок в UART помимо качества уровня сигнала (шум, время нарастания / спада) является искажение тактового сигнала. Если часы передатчика и часы приемника не получены из одного и того же источника (что имеет место в большинстве случаев), то один будет работать быстрее, чем другой. Когда ошибка синхронизации слишком велика, вы можете иногда прочитать неправильный бит.

jippie
источник
Что могло бы вызвать перекос часов, если бы микроконтроллер оставался один в черном ящике посреди того, кто знает, где?
user791953 25.09.13
1
Свободно работающие местные часы. Каждый генератор имеет свою точность. Часы MCU можно разделить на используемую частоту для UART, но иногда они отключаются на небольшой процент. Это, в свою очередь, вызвано тем, что делитель является целым числом.
Джиппи
Например. Частота MCU = 16 МГц, скорость UART = 9600 Бод. Затем UART обычно работает с частотой 153600 Гц. Но 16000000/153600 не является целым числом, поэтому скорость передачи данных будет отключена.
Джиппи
Правильно, это даст небольшой процент ошибок. Думаю, мне повезло, что я не столкнулся с какими-либо ошибками, но если это критические данные, проверки должны выполняться всегда.
user791953 25.09.13
Более низкая скорость передачи, более высокая тактовая частота (увеличивает разрешение выборки и точность синхронизации).
Джиппи
1

Большинство ошибок проистекают из трех причин: (1) сгенерированный сигналом передатчик не соответствует действительным данным; (2) сигнал передатчика не был получен как сгенерированный, или (3) приемник не был готов обрабатывать данные, когда они были получены. Самая распространенная причина, по которой я столкнулся с проблемой № 1, - это передатчик, который переконфигурируется или отключается во время передачи данных. Проблема № 2 может легко возникнуть для сигналов, проходящих через «внешний мир», в результате радиопомех (мобильные телефоны могут быть на удивление неприятными!), Но, как правило, не должна возникать для сигналов, ограниченных одной платой. Проблема № 3 может возникать из-за того, что слишком много байтов поступает быстрее, чем они могут быть обработаны, или из-за того, что приемник реконфигурирован, выключен или запущен во время передачи.

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

Supercat
источник
0

Ошибки кадрирования могут быть вызваны тем, что упоминает @jippie - приемник обнаружил стартовый бит и там, где он ожидает стоповый бит, данные инвертируются. Это также может быть связано с повреждением данных, вызванным помехами в линии, возникающими в стоп-бите. Вы всегда должны проверять это для каждого полученного байта.

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

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

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

Недостаточное выполнение на самом деле не является ошибкой, но указывает отправляющему UART, что его буфер передачи пуст, т.е. он запрашивает новый байт для передачи. Вам не нужно проверять это.

Энди ака
источник
Я понимаю, что это за ошибки и почему они происходят, мой вопрос больше связан с вопросом, когда следует обеспечить их проверку на наличие ошибок.
user791953 25.09.13
@ user791953 - сделано
Энди,
Кстати, опустошение не является проблемой для большинства протоколов, но некоторые протоколы используют незанятую линию для указания конца пакета. В таких случаях недогрузка на передающей стороне может привести к тому, что получатель неправильно решит, что пакет заканчивается, прежде чем он должен.
суперкат
0

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

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

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

Энди Смит
источник
Тайм-ауты должны быть реализованы по крайней мере на одной стороне любого протокола более высокого уровня; во многих случаях лучше всего реализовать их с одной стороны. Одна сторона, ожидающая навсегда данных, которые никогда не поступают, является проблемой только в том случае, если есть что-то полезное, что она могла бы сделать вместо этого. Если X запрашивает у Y какие-то данные, X должен быть готов повторно отправить его запрос, если Y не получил его. Y, однако, не нужно беспокоиться о том, получит ли X свой ответ. Если X не получит его, X снова запросит данные. Тот факт, что X больше не запрашивает данные, означает, что Y не нужно отправлять их повторно.
суперкат
@supercat верно, это хороший шаблон, но я нацеливаюсь на низкоуровневое кодирование строк. у вас всегда будет цикл, который читает данные и пытается выяснить, готово ли полное сообщение, если полное сообщение никогда не будет, оно может повесить подсистему ввода, независимо от того, есть ли что-то еще, кроме ожидания сделанный. в этом случае подсистеме ввода необходимо, по крайней мере, понять, что произошел сбой, сбросить все данные gabage и получить сброс для следующей попытки.
Andyz Smith
Если каждый пакет начинается с байтовой последовательности, которая всегда может быть идентифицирована в любом контексте, и если получатель не имеет ничего полезного, он может делать, пока не получит полный пакет, почему его должно волновать, если пройдет несколько часов после получения частичного пакета? В следующий раз, когда кто-то попытается отправить реальный пакет, получатель увидит маркер начала пакета и откажется от частичного пакета.
суперкат
@supercat, потому что тогда у вас есть цикл, который ищет несколько вещей. он все еще ищет конец частичного пакета и ищет начало нового, не поврежденного пакета. это делает логику намного более сложной с точки зрения практического, если затем, делать, в то время как кодирование.
Andyz Smith
Я не совсем уверен, в чем проблема. Если кто-то использует цикл приема байтов, ему придется выйти из него, если произойдет тайм-аут или начальный байт. Оба поведения должны обрабатываться одинаково, за исключением того факта, что последовательность запуска должна устанавливать флаг, поэтому следующий код, который будет его искать, не будет беспокоить.
суперкат