Работа с COM портом - C++

Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Работа с COM портом - C++

Сообщение СЦБист »

Добрый день !

У меня возник такой вопрос :

Принимается поток байтов ком портом.

Вопрос. Когда принятую строку символов можно считывать ?

Что является признаком того, что строка принята в полном составе, и ее можно считать функцией

ReadFile
Реклама
mas123
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Re: Работа с COM портом - C++

Сообщение mas123 »

СЦБист писал(а):Когда принятую строку символов можно считывать ?
Всегда и сразу.
Как правило, FIFO у UART небольшой, вся "строка" там не поместится.
Да и нужно как-то её анализировать на предмет "конца строки".
ЗЫ: понятие "считывать" оооочень расплывчатое... :)))
СЦБист писал(а):Что является признаком того, что строка принята в полном составе,
Обычно, маркером конца строки является... заранее оговорённый маркер конца строки.
Например "\0" или "\r\n"...
Либо, "строка" передаётся в составе "кадра" заранее оговорённого формата.
СЦБист писал(а):и ее можно считать функцией
Вот этого не понял...
Реклама
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

Честно говоря я тоже не сильно понял про что тут идет речь.

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

Пускай 1200 байт.http://www.vsokovikov.narod.ru/New_MSDN ... upcomm.htm

Считывать информацию из этого буфера я могу функцией http://www.vsokovikov.narod.ru/New_MSDN ... adfile.htm

Ясное дело считывать этот буфер раз за разом смысла нету.

Мне нужно считать полноценную строку, а не огрызки.

Считывать нужно в какой-то определенный момент.

Тут есть такое понятие как тайм-аут.

вот ее структура. не могу понять как ее правильно заполнить и как потом это использовать (((


typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6312
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Работа с COM портом - C++

Сообщение Jack_A »

mas123 писал(а):
СЦБист писал(а):и ее можно считать функцией
Вот этого не понял...
Я это понял так: "ее можно считать успешным результатом вызова функции ReadFile"
Изображение
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

Jack_A писал(а):[
Я это понял так: "ее можно считать успешным результатом вызова функции ReadFile"
на словах не шибко понял. может на примере кода сможете показать? Буду очень признателен.

Про тайм-ауты тоже хочу знать, на что они влияют и как ими пользоваться.
Реклама
mas123
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Re: Работа с COM портом - C++

Сообщение mas123 »

СЦБист писал(а):Мне нужно считать полноценную строку, а не огрызки.
Задайся вопросом: кто должен найти маркер окончания строки?
Есть некая волшебная функция "найти строку"? Нет, значит придется самому искать.
Найти можно только читая принятый поток в поисках маркера. Другого варианта нет.
СЦБист писал(а):Считывать нужно в какой-то определенный момент.
Тут есть такое понятие как тайм-аут.
И что тебе это даст? Данные могут приходить когда угодно - зависит от скорости передачи, от "желания" источника передать данные.....

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

Либо читай по одному байту, анализируй его на "окончание". Если не конец - добавляешь байт в буфер строки и читаешь дальше...
Это будет более тормозно, но проще в реализации. :)
Реклама
Аватара пользователя
Myp3ik
Мучитель микросхем
Сообщения: 450
Зарегистрирован: Вс янв 09, 2011 23:05:37
Откуда: СССР

Re: Работа с COM портом - C++

Сообщение Myp3ik »

Иван Сусанин - первый полупроводник :solder:
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

Предположим что считываю я информацию с буфера через каждые 1 с.

Про кольцевой буфер не понял с какой целью его лепить.

Размер буфера я указываю тут

BOOL SetupComm(
HANDLE hFile,
DWORD dwInQueue,
DWORD dwOutQueue
);


что делать с тайм-аутами ? нужно их выставлять ?

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;



Данные у меня приходят по запросу а не когда угодно.
mas123
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Re: Работа с COM портом - C++

Сообщение mas123 »

СЦБист писал(а):Про кольцевой буфер не понял с какой целью его лепить.
Складывать данные в этот буфер, в процессе поиска конца строки.
Ибо можно вычитать не только символы из конца строки, плюс маркер окончания, но и начало новой строки - чтобы это начало не потерять.
Либо запрашивай по одному байту и анализируй на "конец строки". Тогда можно без кольцевого буфера.
СЦБист писал(а):что делать с тайм-аутами ? нужно их выставлять ?
Разумеется. При отсутствии данных будет выход из функции по таймауту. Иначе можно зависнуть на ожидании.
СЦБист писал(а):Данные у меня приходят по запросу а не когда угодно.
Это и есть "когда угодно".
Запрос может уйти в любой момент, запрос может "не дойти" до получателя, получатель может ответить в разное время, ответ может "не дойти" до компа.
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

Походу никто этого раньше не делал.

По поводу конца строки. Нету у нее не конца не начала.

Наверное придется делать параллельный поток и искать ответ в другом месте.
mas123
Потрогал лапой паяльник
Сообщения: 312
Зарегистрирован: Вс июл 29, 2012 16:25:39

Re: Работа с COM портом - C++

Сообщение mas123 »

СЦБист писал(а):Походу никто этого раньше не делал.
Да-да-да, никто и никогда не передавал данные через различные соединения. Все эти Ethernet, RS-232, RS-485 и многие другие - это вымысел.
Все эти протоколы (как самодельные, так и промышленные) - сплошной обман. :facepalm:
СЦБист писал(а):По поводу конца строки. Нету у нее не конца не начала.
Э-э-э, поясни? Если у строки нет конца - т что ты собираешься искать?
СЦБист писал(а):и искать ответ в другом месте.
Удачи. Когда найдешь ответ - перечитай снова эту тему с самого начала. :))
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

Добрый день !

Кто в курсах , функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи ?
Аватара пользователя
radteh
Друг Кота
Сообщения: 3087
Зарегистрирован: Пт мар 09, 2007 15:01:52
Откуда: Биробиджан

Re: Работа с COM портом - C++

Сообщение radteh »

Если не ошибаюсь то это зависит от режима синхронный или асинхронный. В асинхронном после отправки в буфер.
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

мне нужно точно знать

функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи :o ?


режим передачи асинхронный ясен пень.
Аватара пользователя
Meteor
Друг Кота
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....
Контактная информация:

Re: Работа с COM портом - C++

Сообщение Meteor »

Если передача относительно редкая, то можно опрашивать с наперед заданным периодом, запрашивая число байт в порту. После того как в очередной раз не будет принято ни одного байта - конец приема строки.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

тест показал что WriteFile завершится лишь когда все символы уйдут в линию.
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

Re: Работа с COM портом - C++

Сообщение Мурик »

СЦБист писал(а):режим передачи асинхронный ясен пень.
СЦБист писал(а):тест показал что WriteFile завершится лишь когда все символы уйдут в линию.
Одно с другим не согласуется.
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

столкнулся с такой бедой. может кто-то уже с этим сталкивался.

передаю посылку как-то так.

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

OVERLAPPED Overlap; 

Overlap.hEvent = CreateEvent(NULL, true, true, NULL);

WriteFile(handle, buffer_write, strlen(buffer_write), &numbytes_ok, &Overlap);

WaitForSingleObject(Overlap.hEvent, INFINITE);
в буфере buffer_write 186 символов

если после строки

WaitForSingleObject(Overlap.hEvent, INFINITE);

посмотреть к-во байт в приемном буфере , то их там будет 176.

почему WaitForSingleObject(Overlap.hEvent, INFINITE); не сработало после отправки всех

186 символов ?
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Работа с COM портом - C++

Сообщение Siarzhuk »

СЦБист писал(а):посмотреть к-во байт в приемном буфере
После сработки события вызовите GetOverlappedResult - она скажет сколько данных на самом деле принялось/отослалось. И если идёт отправка - то почему вы отметили, что буфер приёмный? У приёма свой экземпляр OVERLAPPED должен быть и отдельное событие нужно создавать и Read вызывать.
СЦБист писал(а):в буфере buffer_write 186 символов
186 - это размер буффера, либо длина С-строки там хранящейся?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
СЦБист
Это не хвост, это антенна
Сообщения: 1337
Зарегистрирован: Сб июн 09, 2012 02:14:11
Откуда: ХАРЬКОВ

Re: Работа с COM портом - C++

Сообщение СЦБист »

я еще делал так

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

if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(handle, &Overlap, &temp, true))) 
186 это размер строки strlen(buffer_write)


_____________________


думал отправлять строку по символам .

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

char *p = buffer_write;

int N = strlen(buffer_write);

int K = 0;
		
while (K < N)
{
	if(!WriteFile(handle, p, 1, &numbytes_ok, &Overlap))
			

		signal = WaitForSingleObject(Overlap.hEvent, INFINITE);

		 if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(handle, &Overlap, &temp, true))) 

			

		 p++; K++;
}
то результат малость в лучшую сторону , но все равно недобор на

несколько байтов.

как устранить ?


все делал как тут

http://www.piclist.ru/S-COM-THREAD-RUS/ ... D-RUS.html
Ответить

Вернуться в «Интеграция с ПК»