Делать лучшее из плохого алгоритма "контрольной суммы" - PullRequest
9 голосов
/ 05 апреля 2011

Я работаю над существующим драйвером, который управляет 8-битным MCU через последовательный порт. Существует много разных версий микропрограмм для микроконтроллера, но все они используют общий метод обеспечения целостности канала. Этот метод не очень надежен, и я ищу идеи о том, как драйвер мог бы изменить свое поведение, чтобы получить максимальную отдачу от него.

Команды - это gcode с номером строки и контрольной суммой:

N3 T0*57
N4 G92 E0*67
N5 G28*22
N6 G1 F1500.0*82
N7 G1 X2.0 Y2.0 F3000.0*85
N8 G1 X3.0 Y3.0*33

Номер строки должен быть последовательным (но может быть сброшен с помощью M110). Если контрольная сумма не совпадает или номер строки не совпадает, микропрограмма ответит Resend: nnn, где nnn - последний успешный N плюс 1. «Контрольная сумма» чрезвычайно примитивна:

        // Calc checksum.
        byte checksum = 0;
        byte count = 0;
        while(instruction[count] != '*')
                checksum = checksum^instruction[count++];

Основная проблема заключается в том, что основной механизм ошибок - это отброшенных байтов из-за удержания прерываний, приводящих к переполнениям в 1-байтовом FIFO MCU. Фактическая последовательная шина составляет несколько см между последовательным мостом USB FTDI (или аналогичным) и MCU, поэтому битовые ошибки маловероятны. Я ни разу не заметил ошибки в ответе от прошивки.

Как видите, алгоритм, приведенный выше, обнаружит один отброшенный байт, но если вы отбросите два одинаковых байта (где угодно!), Результат все равно будет совпадать. Таким образом, F3000.0 (скорость подачи 3000 мм / мин) может быть преобразовано в F30.0 и все равно совпадать. Кроме того, набор символов очень мал, поэтому некоторые биты никогда не будут задействованы.

Может ли драйвер сделать данную строку более надежной?

  • Добавить или отбросить конечные (или даже ведущие) нули
  • Добавить или удалить пробелы
  • Изменение порядка слов (X1 Y1 совпадает с Y1 X1)
  • Добавить или удалить пробелы
  • Вносить «незначительные» изменения в значения в пределах некоторого допуска (например, F2999.9 вместо F3000)
  • Сброс номера строки, чтобы получить определенный N для данной строки
  • Разбить одну команду на несколько эквивалентных команд (например, G1 X2 становится G1 X1 G1 X2 при условии, что X = 0 изначально)
  • Устранить (или добавить) лишние слова (например, T0 не имеет смысла для большинства команд, и если вы отправите F3000, как только это подразумевается в будущем, так что его можно отправлять или нет)

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

Ответы [ 3 ]

5 голосов
/ 06 апреля 2011

Одна вещь, которую вы можете попробовать, - настроить UART на хосте так, чтобы он отправлял 2 стоповых бита вместо 1 (что вы, вероятно, используете в настоящее время). Приемник MCU ничего не заметит, за исключением того, что между символами есть дополнительное время простоя. Это примерно на 10% больше времени для извлечения символа из регистра приема до того, как следующий символ будет сдвинут.

Как правило, UART не ищет более 1 стопового бита при получении данных, даже если UART сконфигурирован для 2 стоповых битов (нет причин применять дополнительные стоповые биты при получении), поэтому факт, что MCU будет по-прежнему отправлять только один стоп-бит, не должно вызывать проблем при получении ответов от устройства.

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

Это длинный путь, но это дешевое изменение, которое не требует никаких изменений, кроме конфигурации последовательного порта на стороне хоста.

4 голосов
/ 06 апреля 2011

Мы, возможно, не все знакомы с G-кодом, ссылка всегда полезна для технологии, специфичной для домена.

Я бы сказал, что простая контрольная сумма, вероятно, адекватно соответствует длине данных, формату и производительности процессора. Если вы уже выбрасываете символы, вы вряд ли захотите увеличить нагрузку на процессор с помощью CRC?

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

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

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

Еще одна возможная проблема - это устройство FTDI . Я видел проблемы с несколькими драйверами FTDI, конфликтующими и вызывающими выпадение данных. Решением в этом случае было использование утилиты FTDI FTClean для удаления драйверов, а затем переустановка последней версии драйвера. FTClean, кажется, отсутствует на их сайте, хотя вы можете получить его косвенно через поиск Google. На сайте FTDI есть другой инструмент для удаления, который, я думаю, заменил FTClean. Вы получаете те же проблемы с реальным последовательным портом? Также я обнаружил, что последовательные USB-устройства, использующие устройства и драйверы Prolific, особенно подвержены потере данных даже при умеренной скорости передачи данных.

Наконец, я обнаружил ряд проблем с выпадением данных с использованием различных USB-последовательных устройств, которые могут быть решены путем «кадментирования» выходных данных. Некоторые устройства имеют относительно небольшие внутренние буферы. Возможно, вы заметили, что пропадание символов начинается после примерно 128 символов или любого другого размера внутреннего буфера USB-устройства. Вставка коротких задержек (скажем, 10 мс) в поток данных может решить эту проблему. В этом случае вы можете просто сделать это в конце каждой строки. Другой способ «кадентирования» - опросить буфер передачи в приложении для ПК и подождать, пока он не станет пустым, прежде чем добавлять дополнительные данные, а затем только добавлять данные небольшими порциями, в вашем случае, возможно, одной строкой. Я обнаружил, что это обычно решает проблемы потери данных без видимой потери производительности передачи данных.

4 голосов
/ 06 апреля 2011

Если вы не можете изменить прошивку, ваши возможности весьма ограничены для того, что вы можете сделать на ПК, чтобы улучшить надежность ссылки.Всего несколько возможностей:

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

Если вы сможете сменить прошивку, то у вас гораздо больший потенциал для улучшения: внедрить правильный CRC (даже 8-битный CRC будет значительным улучшением, но лучше было бы 16 бит).

Лучше всего было бы реализовать автосогласование в драйвере ПК, чтобы он мог общаться как со «старым», так и «новым» протоколами, и выяснить, какой тип устройстваэто говорит с.

...