Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux (Lazarus плюс Synaser и бит четности Space и Mark)

Модератор: Модераторы разделов

SidorLuty
Сообщения: 99
ОС: Debian 5.0 Lenny

Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение SidorLuty »

Описание проблемы.
Есть сеть RS-485 со множеством приборов. Мастер - только компьютер. Адрес и конец обмена выдаются с нулевым битом четности (Space), а обмен ведется с единичным битом четности (Mark). Корректность данных и команд контролируется контрольной суммой в конце команды от мастера и в конце данных от прибора. Есть исходники программ на Delphi. Очень легко все перевел на Lazarus в Windows. Получиласть такая же графическая оболочка, как и на Delphi (немного с построеним графиков заморочки были, т.к. компонент TChart сильно от дельфийского отличается). Но в итоге - практически аналогичная программа под Windows. Затевалось это все для портирования в Linux. И тут .... ЗАСАДА!!! В стандартном варианте Synaser для Linux ПРОСТО НЕЛЬЗЯ сделать бит четности Space/Mark. Никак!!!

Решение.
Начал рыть интернет. Наткнулся на статью Томаса Лочматтера "Linux and MARK/SPACE Parity" http://www.lothosoft.ch/thomas/libmip/markspaceparity.php Хорошо, думаю, путь понятен. Теперь надо надыбать конкретные биты во флаге c_cflag. Ну, с #define CMSPAR 010000000000 - понятно, переводим восьмеричное в hex и все. А вот с битами PARENB PARODD опять была засада - поиск #define PARODD (#define PARENB) давал такое количество вариантов, что голова кругом шла. Пришлось все варианты перепробовать. И вот окончательный результат

uses
... SynaSer, SynaUtil, SynaFPC, ....

const

CMSPAR= $40000000; { mark or space (stick) parity }
PARENB= $00000100; { enable parity on output }
PARODD= $00000200; { use odd parity if set, else even }

type
...
procedure ParitySpace;
procedure ParityMark;
...

var
ser: TBlockSerial;
...
...

implementation

procedure TForm1.ParitySpace; {SPACE parity is selected by}
begin
ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag or CMSPAR or PARENB;
ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag and (Not PARODD);
ser.SetCommState;
end;

procedure TForm1.ParityMark; {MARK parity is selected by}
begin
ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag or CMSPAR or PARENB or PARODD;
ser.SetCommState;
end;
...

По окончании работы с программой не забывайте в FormCloseQuery сбрасывать бит CMSPAR.
ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag and (Not CMSPAR);

Проверено - работает замечательно!
Спасибо сказали:
shotdownsystem
Сообщения: 423
ОС: Basic command interpreter

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение shotdownsystem »

а чем termios не угодил ?
puts ("Working, please wait...");while(1);
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение eddy »

SidorLuty, если бы вы пользовались С, а не какими-то нераспространенными ЯП, у вас бы проблем не было.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
SidorLuty
Сообщения: 99
ОС: Debian 5.0 Lenny

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение SidorLuty »

shotdownsystem писал(а):
30.11.2010 13:49
а чем termios не угодил ?

А чем он лучше? Даже если его перевести на паскаль в нем изначально недокументированного бита CMSPAR нет, а без этого Space/Mark в Linux НЕ БУДЕТ! Т.е. если в Windows мы имеем dcb.parity = 0; /*No Parity*/, dcb.parity = 1; /*Odd Parity*/, dcb.parity = 2; /*Even Parity*/, dcb.parity = 3; /*Mark Parity*/, dcb.parity = 4; /*Space Parity*/, то в Linux мы однозначно имеем dcb.parity = 0; /*No Parity*/, dcb.parity = 1; /*Odd Parity*/, dcb.parity = 2; /*Even Parity*/, dcb.parity = 3; /*Even Parity*/, dcb.parity = 4; /*Even Parity*/. Эта же проблема существует и у Mac OS, как у UNIX-подобной системы.

eddy писал(а):
30.11.2010 13:55
SidorLuty, если бы вы пользовались С, а не какими-то нераспространенными ЯП, у вас бы проблем не было.

Ключевая фраза была "Есть исходники программ на Delphi"!!! Возможно, есть аналоги Borland C++ Builder (опыт переноса проектов с Delphi на C++ Builder - самый положительный) для Linux, но мне они неизвестны. Qt Creator, согласитесь, совсем другая штука. И проблемы были бы самые, что ни наесть. А именно - разработка программы с нуля!!! А вот про паскаль первый раз слышу "какой-то нераспространенный ЯП". Да и вообще... Концепция IDE Borland (а Lazarus - аналог) с визуальными (и не очень) компонентами для создания GUI мне гораздо больше нравится, чем концепция Qt Creator.

А поделился я своим опытом для тех, кому это будет необходимо. Зря Вы считаете, что Free Pascal и Lazarus мало людей пользуют. Я лично, пользую тот ЯП, который мне на данный момент удобнее (очень сожалею, что для микроконтроллеров альтернативы C нет, не считая ассемблера, конечно). Кстати, на этой ссылочке, которую я изначально дал, http://www.lothosoft.ch/thomas/libmip/markspaceparity.php как раз приведен пример для C.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение eddy »

SidorLuty писал(а):
30.11.2010 17:04
А чем он лучше?

Код: Выделить всё

man termios
...
       CMSPAR (not in POSIX) Use "stick" (mark/space) parity (supported on certain serial devices): if PARODD is set, the parity bit is always 1; if PARODD is not set,
              then the parity bit is always 0).  [requires _BSD_SOURCE or _SVID_SOURCE]
...


SidorLuty писал(а):
30.11.2010 17:04
Зря Вы считаете, что Free Pascal и Lazarus мало людей пользуют.

В серьезных целях - никто.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
shotdownsystem
Сообщения: 423
ОС: Basic command interpreter

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение shotdownsystem »

SidorLuty писал(а):
30.11.2010 17:04
очень сожалею, что для микроконтроллеров альтернативы C нет, не считая ассемблера, конечно

Я видел бейсик для микроконтроллеров.
ЯП - это инструмент. У каждого инструмента есть свое назначние. Можно конечно и отверткой дырку ковырять, но лучше использовать шлямбур.
Я тоже когда-то с Паскаля-дельфи начинал, но потом его перерос. А QIP (виндовая аська) не на дельфи написана кстати?
puts ("Working, please wait...");while(1);
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение eddy »

shotdownsystem писал(а):
30.11.2010 17:36
Я видел бейсик для микроконтроллеров.

Я, кстати, для МК только С использую :)
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
shotdownsystem
Сообщения: 423
ОС: Basic command interpreter

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение shotdownsystem »

eddy писал(а):
30.11.2010 17:44
shotdownsystem писал(а):
30.11.2010 17:36
Я видел бейсик для микроконтроллеров.

Я, кстати, для МК только С использую :)

Все кого ты не спроси программируют на Си
Встретишь ты кого едва ли тех кто пишет на паскале :fans:
puts ("Working, please wait...");while(1);
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение eddy »

shotdownsystem писал(а):
30.11.2010 17:55
Встретишь ты кого едва ли тех кто пишет на паскале

Уж больно неуклюж язык,
И синтаксис его страдает.
Да и какой же ты мужик,
Коль что-то пишешь на Паскале? :)
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
SidorLuty
Сообщения: 99
ОС: Debian 5.0 Lenny

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение SidorLuty »

eddy писал(а):
30.11.2010 18:15
shotdownsystem писал(а):
30.11.2010 17:55
Встретишь ты кого едва ли тех кто пишет на паскале

Уж больно неуклюж язык,
И синтаксис его страдает.
Да и какой же ты мужик,
Коль что-то пишешь на Паскале? :)

Давай не будем религиозные войны разводить! Я сам на Си и Си++ пишу для МК. И недостатки Си вижу, впрочем, как и достоинства. Так и в паскале (строгость языка, например). А на счет "В серьезных целях - никто." - так это что считать серьезной целью. Лично для меня серьезная цель - это стабильно работающее ПО любого назначения. А писать, лично мне, удобнее на IDE типа Borland. termios.h я смотрел несколько исходников, например - http://www.raspberryginger.com/jbailey/min..._8h-source.html и нигде про CMSPAR. Да и вообще, если паскаль не интересует, то в чем смысл ваших посланий? Мое послание - тем, кто столкнется с этой проблемой в FPC и Lazarus. Доказывать чего либо я не собираюсь, у каждого своя голова.
P.S. Шутки на счет бейсиков для МК хороши, только это не более, чем шутки. Есть и паскали шуточные, например - http://users.iafrica.com/r/ra/rainier/ Но ведь писал про серьезную альтернативу, как, например, Delphi и C++ Builder.
Спасибо сказали:
shotdownsystem
Сообщения: 423
ОС: Basic command interpreter

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение shotdownsystem »

SidorLuty писал(а):
30.11.2010 20:06
P.S. Шутки на счет бейсиков для МК хороши, только это не более, чем шутки. Есть и паскали шуточные, например - http://users.iafrica.com/r/ra/rainier/ Но ведь писал про серьезную альтернативу, как, например, Delphi и C++ Builder.

Ну расскажите про шутки этим ребятам: http://www.picbasic.ru/. И для АВРов тоже есть Бейсик.
Я тоже против религиозых войн, но так исторически сложилось, что системным ЯП стал Си.
puts ("Working, please wait...");while(1);
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение eddy »

SidorLuty писал(а):
30.11.2010 20:06
termios.h я смотрел несколько исходников, например - http://www.raspberryginger.com/jbailey/min..._8h-source.html и нигде про CMSPAR

Это потому, что termios.h сам включает несколько файлов. Погрепали бы получше:

Код: Выделить всё

grep -R CMSPAR /usr/include
/usr/include/asm/termbits.h:#define CMSPAR      010000000000    /* mark or space (stick) parity */
/usr/include/bits/termios.h:# define CMSPAR   010000000000        /* mark or space (stick) parity */
/usr/include/asm-generic/termbits.h:#define CMSPAR      010000000000    /* mark or space (stick) parity */

RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
SidorLuty
Сообщения: 99
ОС: Debian 5.0 Lenny

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение SidorLuty »

shotdownsystem писал(а):
01.12.2010 11:18
Ну расскажите про шутки этим ребятам: http://www.picbasic.ru/. И для АВРов тоже есть Бейсик.
Я тоже против религиозых войн, но так исторически сложилось, что системным ЯП стал Си.

Эти ребята и так все прекрасно знают про шутки. Для начинающих возможно и имеет смысл, но я бы для начинающих именно ассемблер порекомендовал, а потом сразу Си. Холивар http://lurkmore.ru/%D0%A5%D0%BE%D0%BB%D0%B...%B2%D0%B0%D1%80 на тему ЯП не поддерживаю. Что сие означает "но так исторически сложилось, что системным ЯП стал Си. http://lurkmore.ru/C "? Что за системы? ОС? Я знаю ОС написанную полностью на ассемблере (MenuetOS http://lurkmore.ru/MenuetOS ). А мне вообще по-боку на чем пишется ОС. Или под системой имеется ввиду программирование железа (систем ПК)? Все современные реализации Паскаль http://lurkmore.ru/Pascal позволяют делать с системой все тоже, что и Си, только более строго, не допускают детских ошибок неявных преобразований типов, например. "но так исторически сложилось, что системным ЯП стал Си", а вот разработчик Total Commander, к примеру, историю не учил и все лепит его на Delphi! На курсы истории его отправить, что ли? Может хватит про ЯП? Достало еще в 90-е гг.
Спасибо сказали:
shotdownsystem
Сообщения: 423
ОС: Basic command interpreter

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение shotdownsystem »

SidorLuty писал(а):
01.12.2010 11:55
Я знаю ОС написанную полностью на ассемблере (MenuetOS http://lurkmore.ru/MenuetOS ). А мне вообще по-боку на чем пишется ОС. Или под системой имеется ввиду программирование железа (систем ПК)? Все современные реализации Паскаль http://lurkmore.ru/Pascal позволяют делать с системой все тоже, что и Си, только более строго, не допускают детских ошибок неявных преобразований типов, например. "но так исторически сложилось, что системным ЯП стал Си", а вот разработчик Total Commander, к примеру, историю не учил и все лепит его на Delphi! На курсы истории его отправить, что ли? Может хватит про ЯП? Достало еще в 90-е гг.

Си более системный язык, Паскаль более прикладной. Программирование УАРТ системная задача.
А задание констант для стандартных устройств снижает ценность ПО
puts ("Working, please wait...");while(1);
Спасибо сказали:
shotdownsystem
Сообщения: 423
ОС: Basic command interpreter

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение shotdownsystem »

SidorLuty писал(а):
01.12.2010 11:55
Для начинающих возможно и имеет смысл, но я бы для начинающих именно ассемблер порекомендовал, а потом сразу Си.

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

SidorLuty писал(а):
01.12.2010 11:55
позволяют делать с системой все тоже, что и Си, только более строго

а ну ка напишите на паскале кроссплатформенное приложение.
puts ("Working, please wait...");while(1);
Спасибо сказали:
SidorLuty
Сообщения: 99
ОС: Debian 5.0 Lenny

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение SidorLuty »

shotdownsystem писал(а):
01.12.2010 12:29
без знания архитектуры и сразу ассемблер - оригинальный подход

Без знания архитектуры только олигофрен в МК полезет. Нормельный прог. хотя бы одним глазом в даташит посмотрит.

shotdownsystem писал(а):
01.12.2010 12:29
а нука напишите на паскале кроссплатофрменое приложение.

Я с этого начал, если Вы внимательно читали первый пост. Lazarus - IDE для Free Pascal.

"А задание констант для стандартных устройств снижает ценность ПО" - проняло! Я по-наивности считал, что ценность ПО определяется надежностью и удобством пользования!

Спасибо сказали:
shotdownsystem
Сообщения: 423
ОС: Basic command interpreter

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение shotdownsystem »

SidorLuty писал(а):
01.12.2010 12:38
Без знания архитектуры только олигофрен в МК полезет. Нормельный прог. хотя бы одним глазом в даташит посмотрит.

если поймет там что-то

SidorLuty писал(а):
01.12.2010 12:38
shotdownsystem писал(а):
01.12.2010 12:29
а нука напишите на паскале кроссплатофрменое приложение.

Я с этого начал, если Вы внимательно читали первый пост. Lazarus - IDE для Free Pascal.
"А задание констант для стандартных устройств снижает ценность ПО" - проняло! Я по-наивности считал, что ценность ПО определяется надежностью и удобством пользования!

Windows, linux - скучно. Давайте по взрослому - os-9, например.
ценность ПО определяется множеством факторов:надежность, удобство, читабельность кода, маштабируемость - понятия субъективные; есть еще и численные характеристики.
puts ("Working, please wait...");while(1);
Спасибо сказали:
SidorLuty
Сообщения: 99
ОС: Debian 5.0 Lenny

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение SidorLuty »

shotdownsystem писал(а):
01.12.2010 12:44
Windows, linux - скучно. Давайте по взрослому - os-9, например.

А зачем? Мне-то это зачем? Я даже не знаю какой там GUI. Вот LynxOS это уже интереснее! Но такая задача у меня не стояла. А встанет, может на Си буду ее решать. Сколько раз повторять - мне все равно на чем писать - на Си, на Паскале - главное максимально полная и быстрая реализация поставленной задачи. Увижу, что Модула лучше подходит или ассемблер, буду на них писать, или другой язык какой выучу. Для той задачи, которую я описал выше по срокам и функциональности альтернативы Lazarus не было.

shotdownsystem писал(а):
01.12.2010 12:44
ценность ПО определяется множеством факторов:надежность, удобство, читабельность кода, маштабируемость - понятия субъективные; есть еще и численные характеристики.

Для пользователей сетей наших приборов - только два фактора: 1 - возможность работать месяцами без сбоев и создавать базу данных для каждого прибора (минимальный интервал опроса - 6 с); 2 - возможность выбора даты и времени работы прибора и просмотр в виде графиков с возможностью вывода на печать. Все! Ну и, конечно, графики должны масштабироваться с выбором конкретной точки.
Давайте и мы поставим точку!
Спасибо сказали:
Doublespace
Сообщения: 275
ОС: Debian Lenny,Squeeze,Centos

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение Doublespace »

Понимаю, что вы привязаны к уже имеющемуся коду, но lazarus- это тихий ужас. Там даже examples нормально не компилируются, в свое время поглядел на него, что ни шаг- то граблями в морду.
Спасибо сказали:
Аватара пользователя
xorader
Сообщения: 1030
Статус: собирающий миры
ОС: Debian

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение xorader »

shotdownsystem писал(а):
30.11.2010 17:36
...
Я видел бейсик для микроконтроллеров.
...


-Жуткий кошмар! Нули и единицы повсюду. Кажется, я видел двойку. Настоящую двойку!
- Это просто сон, Бендер. Двоек не бывает.
Molchanov Alexander (aka Xor)
*offtopic* - ololo!
Спасибо сказали:
artemst
Сообщения: 1
ОС: linux

Re: Личный опыт: Как я решил проблему бита четности Space и Mark в последовательном порте Linux

Сообщение artemst »

SidorLuty писал(а):
29.11.2010 12:43
Описание проблемы.
Есть сеть RS-485 со множеством приборов. Мастер - только компьютер. Адрес и конец обмена выдаются с нулевым битом четности (Space), а обмен ведется с единичным битом четности (Mark). Корректность данных и команд контролируется контрольной суммой в конце команды от мастера и в конце данных от прибора. Есть исходники программ на Delphi. Очень легко все перевел на Lazarus в Windows. Получиласть такая же графическая оболочка, как и на Delphi (немного с построеним графиков заморочки были, т.к. компонент TChart сильно от дельфийского отличается). Но в итоге - практически аналогичная программа под Windows. Затевалось это все для портирования в Linux. И тут .... ЗАСАДА!!! В стандартном варианте Synaser для Linux ПРОСТО НЕЛЬЗЯ сделать бит четности Space/Mark. Никак!!!

Решение.
Начал рыть интернет. Наткнулся на статью Томаса Лочматтера "Linux and MARK/SPACE Parity" http://www.lothosoft.ch/thomas/libmip/markspaceparity.php Хорошо, думаю, путь понятен. Теперь надо надыбать конкретные биты во флаге c_cflag. Ну, с #define CMSPAR 010000000000 - понятно, переводим восьмеричное в hex и все. А вот с битами PARENB PARODD опять была засада - поиск #define PARODD (#define PARENB) давал такое количество вариантов, что голова кругом шла. Пришлось все варианты перепробовать. И вот окончательный результат
....


Всем привет.
Тоже реализую 9-битный протокол передачи. Изучил и первоисточник http://www.lothosoft.ch/thomas/libmip/markspaceparity.php В теории всё понятно. Вот часть кода:

Код:

int main(void) { int FileHandle; unsigned char LedOn[] = {0x01,0x05,0x00,0x07,0xB4}; FileHandle = open("/dev/ttyS0", O_RDWR | O_NOCTTY); if ( FileHandle<0 ) { puts ("error "); FileHandle=-1; return EXIT_FAILURE; } puts(" serial device opened" ); // Set port Settings struct termios newtio; bzero(&newtio, sizeof(newtio)); newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | IGNBRK; newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 1; tcflush(FileHandle, TCIOFLUSH); tcsetattr(FileHandle, TCSANOW, &newtio); // Set non-blocking mode fcntl(FileHandle, F_SETFL, O_NONBLOCK); SendPacket_9bit(FileHandle,LedOn,5); close( FileHandle ); return EXIT_SUCCESS; } void SendPacket_9bit(int mFileHandle, unsigned char *packet, int len) { int err; struct termios tio; bzero(&tio, sizeof(tio)); tcgetattr(mFileHandle, &tio); // Send first byte with mark parity tio.c_cflag |= PARENB; tio.c_cflag |= CMSPAR; tio.c_cflag |= PARODD; err = tcsetattr(mFileHandle, TCSADRAIN, &tio); if(err) puts(" tcsetattr error "); write(mFileHandle, packet, 1); // Send the rest with space parity tio.c_cflag &= ~PARODD; err = tcsetattr(mFileHandle, TCSADRAIN, &tio); if(err) puts(" tcsetattr error "); write(mFileHandle, packet+1, len-1); }


Но опыт показывает что, второе применение функции tcsetattr() после write() почему то безрезультатный. Т.е передаётся первый байт после первого write() в функции SendPacket_9bit, а остальные где то теряются. Всю голову уже поломал, не знаю куда копать
(так же тема продублирована на http://www.linux.org.ru/forum/development/7127056)
Спасибо сказали: