Страница 1 из 3
Работа с COM портом - C++
Добавлено: Вт апр 26, 2016 12:40:48
СЦБист
Добрый день !
У меня возник такой вопрос :
Принимается поток байтов ком портом.
Вопрос. Когда принятую строку символов можно считывать ?
Что является признаком того, что строка принята в полном составе, и ее можно считать функцией
ReadFile
Re: Работа с COM портом - C++
Добавлено: Вт апр 26, 2016 13:22:02
mas123
СЦБист писал(а):Когда принятую строку символов можно считывать ?
Всегда и сразу.
Как правило, FIFO у UART небольшой, вся "строка" там не поместится.
Да и нужно как-то её анализировать на предмет "конца строки".
ЗЫ: понятие "считывать" оооочень расплывчатое...
СЦБист писал(а):Что является признаком того, что строка принята в полном составе,
Обычно, маркером конца строки является... заранее оговорённый маркер конца строки.
Например "\0" или "\r\n"...
Либо, "строка" передаётся в составе "кадра" заранее оговорённого формата.
СЦБист писал(а):и ее можно считать функцией
Вот этого не понял...
Re: Работа с COM портом - C++
Добавлено: Вт апр 26, 2016 14:02:13
СЦБист
Честно говоря я тоже не сильно понял про что тут идет речь.
У меня есть приемный буфер определенного размера.
Пускай 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;
Re: Работа с COM портом - C++
Добавлено: Вт апр 26, 2016 15:34:14
Jack_A
mas123 писал(а):
СЦБист писал(а):и ее можно считать функцией
Вот этого не понял...
Я это понял так: "ее можно считать успешным результатом вызова функции ReadFile"
Re: Работа с COM портом - C++
Добавлено: Вт апр 26, 2016 15:42:04
СЦБист
Jack_A писал(а):[
Я это понял так: "ее можно считать успешным результатом вызова функции ReadFile"
на словах не шибко понял. может на примере кода сможете показать? Буду очень признателен.
Про тайм-ауты тоже хочу знать, на что они влияют и как ими пользоваться.
Re: Работа с COM портом - C++
Добавлено: Вт апр 26, 2016 16:19:11
mas123
СЦБист писал(а):Мне нужно считать полноценную строку, а не огрызки.
Задайся вопросом: кто должен найти маркер окончания строки?
Есть некая волшебная функция "найти строку"? Нет, значит придется самому искать.
Найти можно только читая принятый поток в поисках маркера. Другого варианта нет.
СЦБист писал(а):Считывать нужно в какой-то определенный момент.
Тут есть такое понятие как тайм-аут.
И что тебе это даст? Данные могут приходить когда угодно - зависит от скорости передачи, от "желания" источника передать данные.....
Формируешь кольцевой буфер. Постоянно читаешь из файла (сколько можно) и добавляешь данные в этот буфер.
После каждого успешного чтения ищешь маркер "конец строки" от текущего указателя чтения по последний принятый байт.
При нахождении строки - извлекаешь её, смещаешь указатель чтения... И так далее.
Либо читай по одному байту, анализируй его на "окончание". Если не конец - добавляешь байт в буфер строки и читаешь дальше...
Это будет более тормозно, но проще в реализации.

Re: Работа с COM портом - C++
Добавлено: Вт апр 26, 2016 16:35:22
Myp3ik
Re: Работа с COM портом - C++
Добавлено: Ср апр 27, 2016 11:20:04
СЦБист
Предположим что считываю я информацию с буфера через каждые 1 с.
Про кольцевой буфер не понял с какой целью его лепить.
Размер буфера я указываю тут
BOOL SetupComm(
HANDLE hFile,
DWORD dwInQueue,
DWORD dwOutQueue
);
что делать с тайм-аутами ? нужно их выставлять ?
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
Данные у меня приходят по запросу а не когда угодно.
Re: Работа с COM портом - C++
Добавлено: Чт апр 28, 2016 13:54:10
mas123
СЦБист писал(а):Про кольцевой буфер не понял с какой целью его лепить.
Складывать данные в этот буфер, в процессе поиска конца строки.
Ибо можно вычитать не только символы из конца строки, плюс маркер окончания, но и начало новой строки - чтобы это начало не потерять.
Либо запрашивай по одному байту и анализируй на "конец строки". Тогда можно без кольцевого буфера.
СЦБист писал(а):что делать с тайм-аутами ? нужно их выставлять ?
Разумеется. При отсутствии данных будет выход из функции по таймауту. Иначе можно зависнуть на ожидании.
СЦБист писал(а):Данные у меня приходят по запросу а не когда угодно.
Это и есть "когда угодно".
Запрос может уйти в любой момент, запрос может "не дойти" до получателя, получатель может ответить в разное время, ответ может "не дойти" до компа.
Re: Работа с COM портом - C++
Добавлено: Чт апр 28, 2016 14:12:19
СЦБист
Походу никто этого раньше не делал.
По поводу конца строки. Нету у нее не конца не начала.
Наверное придется делать параллельный поток и искать ответ в другом месте.
Re: Работа с COM портом - C++
Добавлено: Чт апр 28, 2016 14:33:30
mas123
СЦБист писал(а):Походу никто этого раньше не делал.
Да-да-да, никто и никогда не передавал данные через различные соединения. Все эти Ethernet, RS-232, RS-485 и многие другие - это вымысел.
Все эти протоколы (как самодельные, так и промышленные) - сплошной обман.
СЦБист писал(а):По поводу конца строки. Нету у нее не конца не начала.
Э-э-э, поясни? Если у строки нет конца - т что ты собираешься искать?
СЦБист писал(а):и искать ответ в другом месте.
Удачи. Когда найдешь ответ - перечитай снова эту тему с самого начала.

Re: Работа с COM портом - C++
Добавлено: Ср май 04, 2016 13:31:02
СЦБист
Добрый день !
Кто в курсах , функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи ?
Re: Работа с COM портом - C++
Добавлено: Пт май 06, 2016 06:43:04
radteh
Если не ошибаюсь то это зависит от режима синхронный или асинхронный. В асинхронном после отправки в буфер.
Re: Работа с COM портом - C++
Добавлено: Пт май 06, 2016 12:09:31
СЦБист
мне нужно точно знать
функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи

?
режим передачи асинхронный ясен пень.
Re: Работа с COM портом - C++
Добавлено: Пн май 09, 2016 13:35:40
Meteor
Если передача относительно редкая, то можно опрашивать с наперед заданным периодом, запрашивая число байт в порту. После того как в очередной раз не будет принято ни одного байта - конец приема строки.
Re: Работа с COM портом - C++
Добавлено: Пн май 09, 2016 13:41:21
СЦБист
тест показал что WriteFile завершится лишь когда все символы уйдут в линию.
Re: Работа с COM портом - C++
Добавлено: Вт май 10, 2016 11:21:55
Мурик
СЦБист писал(а):режим передачи асинхронный ясен пень.
СЦБист писал(а):тест показал что WriteFile завершится лишь когда все символы уйдут в линию.
Одно с другим не согласуется.
Re: Работа с COM портом - C++
Добавлено: Вт май 10, 2016 13:00:27
СЦБист
столкнулся с такой бедой. может кто-то уже с этим сталкивался.
передаю посылку как-то так.
Код: Выделить всё
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 символов ?
Re: Работа с COM портом - C++
Добавлено: Вт май 10, 2016 14:19:22
Siarzhuk
СЦБист писал(а):посмотреть к-во байт в приемном буфере
После сработки события вызовите GetOverlappedResult - она скажет сколько данных на самом деле принялось/отослалось. И если идёт отправка - то почему вы отметили, что буфер приёмный? У приёма свой экземпляр OVERLAPPED должен быть и отдельное событие нужно создавать и Read вызывать.
СЦБист писал(а):в буфере buffer_write 186 символов
186 - это размер буффера, либо длина С-строки там хранящейся?
Re: Работа с COM портом - C++
Добавлено: Вт май 10, 2016 14:33:39
СЦБист
я еще делал так
Код: Выделить всё
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