реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Обнаружение ошибок чётности и др. при приёме ч/з COM порт, В винде
forever failure
сообщение Mar 8 2010, 05:17
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



Всем доброго.
Ув. эксперты, поскажите, есть ли в виндовых осях возможность обнаруживать ошибки контроля чётности и другие (CE_FRAME, CE_OVERRUN) при получении данных побайтно по последовательному порту ? Пробую тестовую программу - внешним устройством (контроллером) посылается поток байт - часть с ошибкой чётности (точнее, просто с перевёрнутой чётностью), часть - без ошибок. Принимающая часть (программа под виндой) распознаёт только ошибку в самом первом испорченном байте, остальные почему-то молча пропускает - это при приёме через встроенный железный COM порт. При прохождении через виртуальный COM порт (переходник USB<->COM FT232) ещё хуже - не только пропускаются ошибочные байты, но и метятся ошибочными безошибочные данные.
Приём и проверка выполняется вот таким кодом:
CODE
static int read_byte (HANDLE handle, uint8_t * byte)
{
uint8_t b;
DWORD ret;

if (!ReadFile (handle, &b, 1, &ret, 0))
return -1;

if (0 == ret)
return 0;

DWORD err;
ClearCommError (handle, &err, 0);

if (err)
{
fprintf (stderr, "\nComm Error: ");
fprintf (stderr, CE_FRAME & err ? "F" : "-");
fprintf (stderr, CE_RXPARITY & err ? "P" : "-");
fprintf (stderr, CE_IOE & err ? "I" : "-");
fprintf (stderr, CE_OVERRUN & err ? "O" : "-");
fprintf (stderr, CE_RXOVER & err ? "B" : "-");
fprintf (stderr, " = %02X ", b);
return -2;
}

*byte = b;
return 1;
}


Есть код аналогичного назначения под Linux - там всё чётко работает - обнаруживаются все заваленные байты, а правильно отправленные (безошибочные) байты не маркируются как ошибочные, при работе и через реальный и через виртуальный последовательный порт. Можно было бы достичь того же результата в винде ?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 8 2010, 07:12
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(forever failure @ Mar 8 2010, 08:17) *
Есть код аналогичного назначения под Linux - там всё чётко работает - обнаруживаются все заваленные байты, а правильно отправленные (безошибочные) байты не маркируются как ошибочные

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Guest_@Ark_*
сообщение Mar 8 2010, 07:46
Сообщение #3





Guests






Цитата
Принимающая часть (программа под виндой) распознаёт только ошибку в самом первом испорченном байте, остальные почему-то молча пропускает - это при приёме через встроенный железный COM порт. При прохождении через виртуальный COM порт (переходник USB<->COM FT232) ещё хуже - не только пропускаются ошибочные байты, но и метятся ошибочными безошибочные данные.

Дело в том, что при получении ошибки приема одного байта в непрерывном потоке (не важно какой - по четности, или по отсутствию стоп-бита), дальнейшее декодирование потока не может быть признано достоверным. Так как не факт, что оно будет начинаться именно со стартового бита следующего байта, а не где-нибудь с середины. Причем, при таком неправильном приеме, могут случайно получиться и "правильные" байты с правильной четностью и корректным стоп-битом. Но нет ни каких гарантий, что это именно то, что передавалось...
По этому, после получения ошибки, не только буфер FIFO, но и весь дальнейший поток нужно проигнорировать - до появления паузы длительностью не менее передачи одного байта. Только после этого можно начать достоверный прием, с заведомо правильного стартового бита.
Go to the top of the page
 
+Quote Post
forever failure
сообщение Mar 8 2010, 09:34
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



Тогда можно было-бы переформулировать вопрос:
Если после вызова ClearCommError был получен результат, указывающий на ошибку, означает ли это, что ошибка была обнаружена при приёме хотя бы одного из всех полученных с момента предыдущего вызова ClearCommError байт? В этом случае можно было бы не парится с каждобайтной проверкой, а вызывать её раз в иногда, после получения очередного блока данных смотреть - не было ли ошибок в ходе приёма.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 8 2010, 10:21
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(forever failure @ Mar 8 2010, 12:34) *
Если после вызова ClearCommError был получен результат, указывающий на ошибку, означает ли это, что ошибка была обнаружена при приёме хотя бы одного из всех полученных с момента предыдущего вызова ClearCommError байт?

Именно так дело и обстоит если не приказали блокировать порт при возникновении ошибки.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 8 2010, 10:26
Сообщение #6


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(forever failure @ Mar 8 2010, 13:34) *
В этом случае можно было бы не парится с каждобайтной проверкой, а вызывать её раз в иногда, после получения очередного блока данных смотреть - не было ли ошибок в ходе приёма.

Только в том случае, если блоки разделяются паузой (соответственно, тайм-аутом при приеме).
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 8 2010, 10:33
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(_Pasha @ Mar 8 2010, 13:26) *
Только в том случае, если блоки разделяются паузой (соответственно, тайм-аутом при приеме).

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
forever failure
сообщение Mar 8 2010, 10:36
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



Ну я тоже так же и предполагал.
Благодарю за то, что развеяли мои сомнения, в общем на этом можно считать вопрос решённым.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 8 2010, 10:42
Сообщение #9


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zltigo @ Mar 8 2010, 14:33) *
С чего-бы это вдруг.

Я говорил про ленивый и неспешный контроль ошибок. В других случаях, например, при отслеживании символов-разделитей пакета, без означенного прерывания - никак. Никто и не спорит.
Go to the top of the page
 
+Quote Post
galjoen
сообщение Mar 8 2010, 14:26
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(zltigo @ Mar 8 2010, 10:12) *
железо 550 совместимого порта принципиально не способно в потоке, при включенном FIFO локализовать ошибку в конкретном байте.

Почему? Там ведь вроде как 2 FIFO. Одно на данные, а другое на их ошибки.
Другое дело, что в большинстве случаев то, к какому конкретно байту относится ошибка не имеет значения - всё равно перепередавать весь блок. Да и вообще, из ошибок актуальна только строка нулей, а вместо остальных CRC лучше работает.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 8 2010, 16:31
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(galjoen @ Mar 8 2010, 17:26) *
Почему? Там ведь вроде как 2 FIFO. Одно на данные, а другое на их ошибки.

А может 3 FIFO? Или 4 FIFO? Там действительно 2 FIFO - одно для приема и второе для передачи. Давайте, Вы посмотрите документацию, и тогда не придется фантазировать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
galjoen
сообщение Mar 8 2010, 17:25
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640



Цитата(zltigo @ Mar 8 2010, 19:31) *
Давайте, Вы посмотрите документацию, и тогда не придется фантазировать.

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

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

А так же в FIFO-режиме там в регистре LSR в 7-м бите имеется ошибка RFE, про которую написано:
Цитата
В FIFO-режиме данный разряд устанавливается в 1 при появлении ошибки чётности, кадрирования или сигнала BREAK, которые связаны с одним или несколькими символами в FIFO-буфере приёмника.

Вот этот бит не позволят локализовать ошибки...
Go to the top of the page
 
+Quote Post
Guest_@Ark_*
сообщение Mar 8 2010, 18:35
Сообщение #13





Guests






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

Нет. Не позволяет. Сам асинхронный принцип приема этого не позволяет. После получения ошибки приема байта, не только буфер приема, но и весь дальнейший поток должен быть поставлен под сомнение, вплоть до появления паузы при приеме. Причины этого я уже описал выше. И при этом, уже не важно - есть или нет ошибки при приеме байтов, следующих непосредственно за испорченным. Все их нужно считать недостоверными.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 8 2010, 19:02
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(galjoen @ Mar 8 2010, 20:25) *
Вот, что я вычитал в самом начале документа:

Таки да - в классическом нейшиналовском 16550D такое поминается!


Цитата(@Ark @ Mar 8 2010, 21:35) *
вплоть до появления паузы при приеме.

Гарантированные "Паузы" есть - это стоп-старт биты. При ошибках внутренняя логика UART рестартует и осуществляет поиск нового фрейма. Таким образом достоверность байта следующего за сбойным по анализу трех бит (start-parity-stop) гарантируется железом.


Цитата(galjoen @ Mar 8 2010, 20:25) *
Вот этот бит не позволят локализовать ошибки...

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Guest_@Ark_*
сообщение Mar 8 2010, 19:13
Сообщение #15





Guests






Цитата
Цитата(zltigo)
При ошибках внутренняя логика UART рестартует и осуществляет поиск нового фрейма. Таким образом достоверность байта следующего за сбойным по анализу трех бит (start-parity-stop) гарантируется железом.

Именно по этой причине:
Цитата
Принимающая часть (программа под виндой) распознаёт только ошибку в самом первом испорченном байте, остальные почему-то молча пропускает - это при приёме через встроенный железный COM порт.
При прохождении через виртуальный COM порт (переходник USB<->COM FT232) ещё хуже - не только пропускаются ошибочные байты, но и метятся ошибочными безошибочные данные.

То есть все сделано правильно - так, чтобы гарантировать достоверность приема. Зачем автору темы потребовалось обходить это - мне не совсем понятно.
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 22:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.01484 секунд с 7
ELECTRONIX ©2004-2016