The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Определение бита четности при передаче через последовательны..."
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(ok) on 05-Мрт-07, 16:47 
Есть задача - организовать обмен данными с неким устройством, которое подключено к последовательному порту компьютера с ОС Linux. При этом устройство общается с компьютером в простой асинхронном режиме, ничего сложного - принимать/отправлять байты (символы) получается, не проблема.

Но есть одна единственная загвоздка - при передаче данных устройству необходимо первый байт посылки принудительно пометить битом четности (т.н. wakeup bit). Кроме того, в некоторых случаях, от устройства тоже возможен прием байта с таким битом, при том, что контроль четности на самом деле отключен. В связи с этим, собственно, вопрос: можно ли каким-то образом при получении байта из порта проверить, а установлен ли бит четности; и наоборот, при посылке байта, принудительно его установить?

Внимательно изучив доступную документацию по работе с послед. портом, особенно вот здесь http://www.opennet.ru/docs/RUS/serial_guide/ - есть такая возможность:

> Пробел (space parity) бита четности устанавливается также как и отсутствие проверки
> на четность (7S1):

>    options.c_cflag &= ~PARENB
>    options.c_cflag &= ~CSTOPB
>    options.c_cflag &= ~CSIZE;
>    options.c_cflag |= CS8;

Догадываюсь, что примерно таким же способом можно установить и mark parity, что-то вроде

    options.c_cflag |= PARENB
    options.c_cflag &= ~CSTOPB
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

Но, в любом случае, остается вопрос: а как проверить бит четности при получении байта из порта?

Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Определение бита четности при передаче через последовательны..."  
Сообщение от pvl email(ok) on 06-Мрт-07, 14:18 
>Но, в любом случае, остается вопрос: а как проверить бит четности при
>получении байта из порта?

скорее всего можно самому посчитать бит четности и проверить потом была ли ошибка по паритету.

но чесно говоря - это вы такую лажу затеяли..
негоже в системные флаги ложить свою инфу.

лучше байтовые флаги юзать совмесно с байтстаффингом


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 06-Мрт-07, 18:36 
>>Но, в любом случае, остается вопрос: а как проверить бит четности при
>>получении байта из порта?
>
>скорее всего можно самому посчитать бит четности и проверить потом была ли
>ошибка по паритету.

Это вариант, надо будет попробовать, спасибо.
У меня и у самого мысли где-то вокруг этого крутились, только никак не мог
сформулировать правильно.

>но чесно говоря - это вы такую лажу затеяли..
>негоже в системные флаги ложить свою инфу.
>
>лучше байтовые флаги юзать совмесно с байтстаффингом

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 17-Мрт-07, 12:57 
В продолжение темы: проверить 9-й бит действительно получается описанным выше способом, за что большое спасибо pvl за идею.

Но осталась проблема с его установкой (9-го бита, или бита четности). Была попытка напрямую в регистре LCR настроек СОМ-порта установить необходимые биты, что бы при посылке любого байта всегда был включен (или отключен) бит паритета, но тесты показали, что это почему-то не работает...

Алгоритм примерно такой:
- надо отправить байт(ы) с mark parity
- читаем текущий LCR, сохраняем, устанавливаем биты для mark parity
- пишем в порт (обычный вызов write)
- восстанавливаем LCR

Но получается, что мои изменения LCR ни к чему не приводят.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Определение бита четности при передаче через последовательны..."  
Сообщение от pvl email(ok) on 19-Мрт-07, 15:29 
>Но осталась проблема с его установкой (9-го бита, или бита четности). Была
>попытка напрямую в регистре LCR настроек СОМ-порта установить необходимые биты, что
>бы при посылке любого байта всегда был включен (или отключен) бит
>паритета, но тесты показали, что это почему-то не работает...
>
>Алгоритм примерно такой:
> - надо отправить байт(ы) с mark parity
> - читаем текущий LCR, сохраняем, устанавливаем биты для mark parity
> - пишем в порт (обычный вызов write)
> - восстанавливаем LCR
>
>Но получается, что мои изменения LCR ни к чему не приводят.

клаасический пример наступания на грабли используя ресурсы на предназначенные для решения задачи.

посмотрите даташит на любую микруху сериальную (совместимую с 16550) например TLC16550.
может оказатся (даже окажется) что паритет считается аппаратно, а когда в управляющем бите стоит отсутствие контроля по паритету то никакой 9-й бит ваще не передается. Я сам 1000000 раз реализовывал уарты хардверные и всегда так делал.

как вариант - комманды которые должны идти с установленным битом паритета - всегда должны быть четными и соответственно наоборот

а все системные переменные это, по большему счету, только копии соответствующих битов в регистре контроллера уарт.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 19-Мрт-07, 23:48 
>клаасический пример наступания на грабли используя ресурсы на предназначенные для решения задачи.
>

Я не совсем понял: регистр LCR - регистр управления линией, имеет биты 3-5, которые отвечают за паритет, причем бит 3 - включает/отключает использование паритета вообще, бит 4 - задает четность/нечетность, а бит 5 (при включенном 3 бите) - задает mark или space parity, т.е. постоянство бита паритета нулю или единице - как раз то, что мне надо, ресурсы именно те, которые надо - непосредственно регистр с управляющими битами, читается и пишется по определенному адресу относительно базового, все как полагается...

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Определение бита четности при передаче через последовательны..."  
Сообщение от someone (??) on 22-Мрт-07, 13:12 
>Это не мы такую лажу затеяли, это протокол общения, зашитый в устройство.

А если не секрет, то как это устройство называется и что делает?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 22-Мрт-07, 14:22 
>>Это не мы такую лажу затеяли, это протокол общения, зашитый в устройство.
>
>А если не секрет, то как это устройство называется и что делает?
>

А это поможет в решении проблемы?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Определение бита четности при передаче через последовательны..."  
Сообщение от someone (??) on 22-Мрт-07, 19:24 
>А это поможет в решении проблемы?
Нет, не поможет. Просто, если в будущем у меня появится перспектива поработать с такими устройствами, сразу от них отказаться. Хотя бы намекни абревиатуру названия этого устройства.
Если по существу твоего вопроса, то отследить значение бита четности или его наличие на _ПК_ нельзя, даже зная заранее скорость взаимодействия с устройством. Объясняю почему. Com-порт на ПК перед началом взаимодействия с внешним устройством устанавливается в определенный режим работы: скорость, контроль четности, количество бит в байте, количество стоп-битов и т.п. Com-порт не предназначен, точнее в него не закладывали такой функционал, чтобы на лету можно было менять режим работы в рамках взаимодействия с одним устройством. Автоопределение там тем более не заложено. Более того, пожет получиться такая ситуация:
1)ты установил ком-порт в нужный режим работы
2)получил первый байт от устройства
3)начинаешь переключать ком-порт в другой режим работы
4)пока ты переключал ком-порт, устройство тебе уже успело передать несколько байт, которые ты успешно профукал (пропустил)
т.е. время переключения режима ком-порта может быть достаточно большим, чтобы пропустить переданные данные во время самого переключения, особенно это справедливо на больших скоростях передачи данных. Например, перед переключением режима ком-порта процессор может отвлечься на выполнение другой задачи, на этом ты потеряешь драгоценные миллисекунды.
Если бы ты программировал микроконтроллеры, то эту задачу можно ещё было бы реализовать с некоторыми оговорками, но на обыкновенном ПК да при условии, что устройство первым начинает обмен (насколько я понял) - утонченное извращение. Реализовать задачу можно, но с очень высокой вероятностью ошибки и пропусками байтов.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Определение бита четности при передаче через последовательны..."  
Сообщение от someone (??) on 22-Мрт-07, 19:54 
в догонку
>Com-порт на ПК перед началом взаимодействия с внешним устройством
>устанавливается в определенный режим работы
и, если данные посылаются внешним устройством в другом режиме, то эти данные либо будут игнорироваться, либо ты будещь получать мусор.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Определение бита четности при передаче через последовательны..."  
Сообщение от vic (??) on 23-Мрт-07, 13:04 
>Если по существу твоего вопроса, то отследить значение бита четности или его
>наличие на _ПК_ нельзя, даже зная заранее скорость взаимодействия с устройством.
>Объясняю почему. Com-порт на ПК перед началом взаимодействия с внешним устройством
>устанавливается в определенный режим работы: скорость, контроль четности, количество бит  в
>байте, количество стоп-битов и т.п. Com-порт не предназначен, точнее в него
>не закладывали такой функционал, чтобы на лету можно было менять режим
>работы в рамках взаимодействия с одним устройством.
Но устройства такие есть, сталкивался с одной АТС, дык смена настроек фрейма там в качестве защиты от подключения левого софта стояла. Т.е. официальный софт именно так и работал - менял фрейм на ходу. Ну мы тоже не лыком шиты.

> Автоопределение там тем более не заложено.
Да.
> Более того, пожет получиться такая ситуация:
>1)ты установил ком-порт в нужный режим работы
>2)получил первый байт от устройства
>3)начинаешь переключать ком-порт в другой режим работы
>4)пока ты переключал ком-порт, устройство тебе уже успело передать несколько байт, которые
>ты успешно профукал (пропустил)
>т.е. время переключения режима ком-порта может быть достаточно большим, чтобы пропустить переданные
>данные во время самого переключения, особенно это справедливо на больших скоростях
>передачи данных. Например, перед переключением режима ком-порта процессор может отвлечься на
>выполнение другой задачи, на этом ты потеряешь драгоценные миллисекунды.
Че та не помню чтобы он так отвлекался чтобы не успеть за 4 ком портами.
Наверно у мну юникс такой был загадочный. Кстати, в линухе после того юникса был сильно удивлен когда на 115200 пропадать байтики стали при простой передачи в два порта, оказывается надо было hdparm'ить жесткие диски (ну это было с ядром 2.2). dma не всегда по установке линуха включался.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "Определение бита четности при передаче через последовательны..."  
Сообщение от someone (??) on 23-Мрт-07, 13:38 
>Че та не помню чтобы он так отвлекался чтобы не успеть за
>4 ком портами.
>Наверно у мну юникс такой был загадочный. Кстати, в линухе после того
>юникса был сильно удивлен когда на 115200 пропадать байтики стали при
>простой передачи в два порта, оказывается надо было hdparm'ить жесткие диски
>(ну это было с ядром 2.2). dma не всегда по установке
>линуха включался.

Одно дело, когда ты работаешь в одном режиме, да, тут данные никуда не денутся, ядро их заболиво получит и положит в буфер, всё красиво. Другое дело, когда в протоколе заложена необходимость переключать режимы (формат кадра), просто можно не успеть вовремя переключиться в нужный режим; а внешнему устройству пофих в каком режиме в данный момент ком-порт, оно будет слать данные как ему нужно, а ком-порт ПК просто на аппаратном уровне эти данные проигнорирует. Сам с этим сталкивался. Я не говорю что задачу не возможно реализовать, я говорю, что весьма вероятны потери. Если на ПК крутится какой-нибудь тяжёлый софт, а не только программулька для взаимодействия через ком-порт, то проблемы обеспечены.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 23-Мрт-07, 15:20 
>>А это поможет в решении проблемы?
>Нет, не поможет. Просто, если в будущем у меня появится перспектива поработать
>с такими устройствами, сразу от них отказаться. Хотя бы намекни абревиатуру
>названия этого устройства.
>Если по существу твоего вопроса, то отследить значение бита четности или его
>наличие на _ПК_ нельзя, даже зная заранее скорость взаимодействия с устройством.
>Объясняю почему. Com-порт на ПК перед началом взаимодействия с внешним устройством
>устанавливается в определенный режим работы: скорость, контроль четности, количество бит в
>байте, количество стоп-битов и т.п. Com-порт не предназначен, точнее в него
>не закладывали такой функционал, чтобы на лету можно было менять режим
>работы в рамках взаимодействия с одним устройством. Автоопределение там тем более
>не заложено. Более того, пожет получиться такая ситуация:
>1)ты установил ком-порт в нужный режим работы
>2)получил первый байт от устройства
>3)начинаешь переключать ком-порт в другой режим работы
>4)пока ты переключал ком-порт, устройство тебе уже успело передать несколько байт, которые
>ты успешно профукал (пропустил)
>т.е. время переключения режима ком-порта может быть достаточно большим, чтобы пропустить переданные
>данные во время самого переключения, особенно это справедливо на больших скоростях
>передачи данных. Например, перед переключением режима ком-порта процессор может отвлечься на
>выполнение другой задачи, на этом ты потеряешь драгоценные миллисекунды.
>Если бы ты программировал микроконтроллеры, то эту задачу можно ещё было бы
>реализовать с некоторыми оговорками, но на обыкновенном ПК да при условии,
>что устройство первым начинает обмен (насколько я понял) - утонченное извращение.
>Реализовать задачу можно, но с очень высокой вероятностью ошибки и пропусками
>байтов.

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

Дальше: утверждаю, что проверить бит четности на _ПК_ при его наличии _можно_, и для этого совсем не надо каждый раз переключать настройки порта (см. совет от pvl выше). Для этого всего лишь надо один раз настроить порт на проверку бита четности (все равно как). При этом принимающая сторона (serial port) будет его проверять и при несовпадении бита четности с реальным значением паритета принятого байта будет слать в тот же поток код ошибки. Все что остается сделать - для каждого принятого байта самому посчитать паритет и по наличию ошибки определить, какой был бит паритета. Эта схема работает без проблем, тестировалась на скорости 19200, да она, скорее всего, в этом случае вообще значения не имеет - проверка идет на программном уровне уже принятых байтов, поэтому даже на очень больших скоростях можно просто сложить все принятые байты в какой-нибудь временный буффер, а анализировать их когда будет удобнее. Если необходимо взаимодействие в реальном режиме времени, будет несколько сложнее, но в любом случае, эта проверка на бит четности совсем не сложная и даже на медленных компах должна выполняться достаточно быстро.

Приблизительно описанная вами проблема возникает при установке необходимого бита четности при отправке с _ПК_ - для этого надо переключать режимы для каждого отправляемого байта. Но даже здесь измерения показали, что для указанной скорости время переключения и _применения_ настроек меньше времени отправки одного байта. Сложность здесь в другом - при переключении настроек порта он пытается применить новые настройки для уже принятых в буффер, но еще не отправленных байтов (при опции TCSANOW), либо ждать их отправки (TCSADRAIN)- но в этом случае время между двумя байтами становится для меня (протокола) недопустимо большим - около 8-10 микросекунд (максимально до пустимо протоколом 5). Можно также флашить буффер (TCSAFLUSH) - но при этом все принятые, но не отправленные байты просто отбрасываются, что, естесственно, плохо.

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

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 23-Мрт-07, 15:47 
>Ну тогда по порядку. Распространяться особо не буду, но скажу, что устройство
>- игральный автомат, протокол - SAS, на сегодняшний день всеми авторитетами
>в игральном мире признан как самый лучший протокол для связи с
>ПК.
>
Уточню - для связи игровых автоматов с ПК
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "Определение бита четности при передаче через последовательны..."  
Сообщение от pvl email(ok) on 23-Мрт-07, 16:03 
>Ну тогда по порядку. Распространяться особо не буду, но скажу, что устройство
>- игральный автомат, протокол - SAS, на сегодняшний день всеми авторитетами
>в игральном мире признан как самый лучший протокол для связи с
>ПК.

так может по просторам безкрайнего пошарится и найти какую нибудь либу для этого дела..

ЗЫ:
а что jerm?? ниче в нем интересного не нашлось??


Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 23-Мрт-07, 16:45 
>так может по просторам безкрайнего пошарится и найти какую нибудь либу для
>этого дела..
>
>ЗЫ:
>а что jerm?? ниче в нем интересного не нашлось??

Для этого SAS'а даже описание платное, поэтому даже его найти на шару в сети оченно сложно. А уж либу, да еще желательно под Линукс - сильно сомневаюсь, хотя еще не искал.

ЗЫ. В jerm'е ничего интересного пока не нашел, терминал себе и терминал... использует тот же стандартный драйвер, точно также делает настройки...

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

16. "Определение бита четности при передаче через последовательны..."  
Сообщение от someone (??) on 23-Мрт-07, 16:50 
>Поэтому я сейчас ищу способ заставить ожидать отправки всех поставленных в очередь
>байтов меньше времени (возможно, с помощью каких-либо сигналов), либо придется писать
>какой-то свой драйвер. Если есть мысли по этому поводу, с радостью
>выслушаю.
Попробуй использовать в своей проге функции inb/outb для взаимодействия с ком-портом, правда прогу придется пускать из-под root'a и самому надо будет реализовать очередь. Если ты программишь под Linux, то для доступа к портам в этом случае потребуется ioperm. С помощью этих же функций можно читать состояние регистров компорта.
А еще можно написать свой модуль ядра и зацепиться за прерывание ком-порта, в обработчике прерывания можно будет побыстрому проверять нужные биты и складывать данные в буфер. При отправки в модуле тоже можно по хитрому организовать очередь и управление компортом. На уровне ядра (модуля) от многих временных задержек можно избавиться.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

17. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 23-Мрт-07, 17:05 
>Попробуй использовать в своей проге функции inb/outb для взаимодействия с ком-портом, правда
>прогу придется пускать из-под root'a и самому надо будет реализовать очередь.
>Если ты программишь под Linux, то для доступа к портам в
>этом случае потребуется ioperm. С помощью этих же функций можно читать
>состояние регистров компорта.
>А еще можно написать свой модуль ядра и зацепиться за прерывание ком-порта,
>в обработчике прерывания можно будет побыстрому проверять нужные биты и складывать
>данные в буфер. При отправки в модуле тоже можно по хитрому
>организовать очередь и управление компортом. На уровне ядра (модуля) от многих
>временных задержек можно избавиться.

Если использовать inb/outb для взаимодействия с ком-портом, то в любом случае придется цепляться за прерывания, самому организовывать очереди и т.д. и т.п. В конце-концов получим драйвер, надо будет делать модуль ядра - очень неохота этим заниматься. (((

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

18. "Определение бита четности при передаче через последовательны..."  
Сообщение от pvl email(ok) on 23-Мрт-07, 17:08 

>Если использовать inb/outb для взаимодействия с ком-портом, то в любом случае придется
>цепляться за прерывания, самому организовывать очереди и т.д. и т.п. В
>конце-концов получим драйвер, надо будет делать модуль ядра - очень неохота
>этим заниматься. (((


да вы батенька хотите и рыбку сьесть и на х"№; сесть.

ничего там сложного нет. кроме того.. по всей видимости задача по другому не решится

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

19. "Определение бита четности при передаче через последовательны..."  
Сообщение от Sigareta (??) on 13-Дек-07, 13:18 
так в конечном итоге решилась проблема?
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

20. "Определение бита четности при передаче через последовательны..."  
Сообщение от Iceman email(??) on 13-Дек-07, 22:22 
>так в конечном итоге решилась проблема?

Решилась - написанием своего драйвера последовательного порта и включением всех необходимых настроек порта вручную.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру