Работа с COM портом - C++
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Работа с COM портом - C++
Добрый день !
У меня возник такой вопрос :
Принимается поток байтов ком портом.
Вопрос. Когда принятую строку символов можно считывать ?
Что является признаком того, что строка принята в полном составе, и ее можно считать функцией
ReadFile
У меня возник такой вопрос :
Принимается поток байтов ком портом.
Вопрос. Когда принятую строку символов можно считывать ?
Что является признаком того, что строка принята в полном составе, и ее можно считать функцией
ReadFile
- Реклама
Re: Работа с COM портом - C++
Всегда и сразу.СЦБист писал(а):Когда принятую строку символов можно считывать ?
Как правило, 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;
У меня есть приемный буфер определенного размера.
Пускай 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++
Я это понял так: "ее можно считать успешным результатом вызова функции ReadFile"mas123 писал(а):Вот этого не понял...СЦБист писал(а):и ее можно считать функцией
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Re: Работа с COM портом - C++
на словах не шибко понял. может на примере кода сможете показать? Буду очень признателен.Jack_A писал(а):[
Я это понял так: "ее можно считать успешным результатом вызова функции ReadFile"
Про тайм-ауты тоже хочу знать, на что они влияют и как ими пользоваться.
- Реклама
Re: Работа с COM портом - C++
Задайся вопросом: кто должен найти маркер окончания строки?СЦБист писал(а):Мне нужно считать полноценную строку, а не огрызки.
Есть некая волшебная функция "найти строку"? Нет, значит придется самому искать.
Найти можно только читая принятый поток в поисках маркера. Другого варианта нет.
И что тебе это даст? Данные могут приходить когда угодно - зависит от скорости передачи, от "желания" источника передать данные.....СЦБист писал(а):Считывать нужно в какой-то определенный момент.
Тут есть такое понятие как тайм-аут.
Формируешь кольцевой буфер. Постоянно читаешь из файла (сколько можно) и добавляешь данные в этот буфер.
После каждого успешного чтения ищешь маркер "конец строки" от текущего указателя чтения по последний принятый байт.
При нахождении строки - извлекаешь её, смещаешь указатель чтения... И так далее.
Либо читай по одному байту, анализируй его на "окончание". Если не конец - добавляешь байт в буфер строки и читаешь дальше...
Это будет более тормозно, но проще в реализации.
Re: Работа с COM портом - C++
Иван Сусанин - первый полупроводник 
- СЦБист
- Это не хвост, это антенна
- Сообщения: 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;
Данные у меня приходят по запросу а не когда угодно.
Про кольцевой буфер не понял с какой целью его лепить.
Размер буфера я указываю тут
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++
Складывать данные в этот буфер, в процессе поиска конца строки.СЦБист писал(а):Про кольцевой буфер не понял с какой целью его лепить.
Ибо можно вычитать не только символы из конца строки, плюс маркер окончания, но и начало новой строки - чтобы это начало не потерять.
Либо запрашивай по одному байту и анализируй на "конец строки". Тогда можно без кольцевого буфера.
Разумеется. При отсутствии данных будет выход из функции по таймауту. Иначе можно зависнуть на ожидании.СЦБист писал(а):что делать с тайм-аутами ? нужно их выставлять ?
Это и есть "когда угодно".СЦБист писал(а):Данные у меня приходят по запросу а не когда угодно.
Запрос может уйти в любой момент, запрос может "не дойти" до получателя, получатель может ответить в разное время, ответ может "не дойти" до компа.
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Re: Работа с COM портом - C++
Походу никто этого раньше не делал.
По поводу конца строки. Нету у нее не конца не начала.
Наверное придется делать параллельный поток и искать ответ в другом месте.
По поводу конца строки. Нету у нее не конца не начала.
Наверное придется делать параллельный поток и искать ответ в другом месте.
Re: Работа с COM портом - C++
Да-да-да, никто и никогда не передавал данные через различные соединения. Все эти Ethernet, RS-232, RS-485 и многие другие - это вымысел.СЦБист писал(а):Походу никто этого раньше не делал.
Все эти протоколы (как самодельные, так и промышленные) - сплошной обман.
Э-э-э, поясни? Если у строки нет конца - т что ты собираешься искать?СЦБист писал(а):По поводу конца строки. Нету у нее не конца не начала.
Удачи. Когда найдешь ответ - перечитай снова эту тему с самого начала.СЦБист писал(а):и искать ответ в другом месте.
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Re: Работа с COM портом - C++
Добрый день !
Кто в курсах , функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи ?
Кто в курсах , функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи ?
Re: Работа с COM портом - C++
Если не ошибаюсь то это зависит от режима синхронный или асинхронный. В асинхронном после отправки в буфер.
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Re: Работа с COM портом - C++
мне нужно точно знать
функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи
?
режим передачи асинхронный ясен пень.
функция WriteFile завершится после отправки всех символов строки в линию, или после окончания записи этой строки в буфер передачи
режим передачи асинхронный ясен пень.
- Meteor
- Друг Кота
- Сообщения: 3961
- Зарегистрирован: Пн июл 13, 2009 14:37:39
- Откуда: Московская область, наукоград.....
- Контактная информация:
Re: Работа с COM портом - C++
Если передача относительно редкая, то можно опрашивать с наперед заданным периодом, запрашивая число байт в порту. После того как в очередной раз не будет принято ни одного байта - конец приема строки.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Re: Работа с COM портом - C++
тест показал что WriteFile завершится лишь когда все символы уйдут в линию.
Re: Работа с COM портом - C++
СЦБист писал(а):режим передачи асинхронный ясен пень.
Одно с другим не согласуется.СЦБист писал(а):тест показал что WriteFile завершится лишь когда все символы уйдут в линию.
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Re: Работа с COM портом - C++
столкнулся с такой бедой. может кто-то уже с этим сталкивался.
передаю посылку как-то так.
в буфере buffer_write 186 символов
если после строки
WaitForSingleObject(Overlap.hEvent, INFINITE);
посмотреть к-во байт в приемном буфере , то их там будет 176.
почему WaitForSingleObject(Overlap.hEvent, INFINITE); не сработало после отправки всех
186 символов ?
передаю посылку как-то так.
Код: Выделить всё
OVERLAPPED Overlap;
Overlap.hEvent = CreateEvent(NULL, true, true, NULL);
WriteFile(handle, buffer_write, strlen(buffer_write), &numbytes_ok, &Overlap);
WaitForSingleObject(Overlap.hEvent, INFINITE);если после строки
WaitForSingleObject(Overlap.hEvent, INFINITE);
посмотреть к-во байт в приемном буфере , то их там будет 176.
почему WaitForSingleObject(Overlap.hEvent, INFINITE); не сработало после отправки всех
186 символов ?
Re: Работа с COM портом - C++
После сработки события вызовите GetOverlappedResult - она скажет сколько данных на самом деле принялось/отослалось. И если идёт отправка - то почему вы отметили, что буфер приёмный? У приёма свой экземпляр OVERLAPPED должен быть и отдельное событие нужно создавать и Read вызывать.СЦБист писал(а):посмотреть к-во байт в приемном буфере
186 - это размер буффера, либо длина С-строки там хранящейся?СЦБист писал(а):в буфере buffer_write 186 символов
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- СЦБист
- Это не хвост, это антенна
- Сообщения: 1337
- Зарегистрирован: Сб июн 09, 2012 02:14:11
- Откуда: ХАРЬКОВ
Re: Работа с COM портом - C++
я еще делал так
186 это размер строки strlen(buffer_write)
_____________________
думал отправлять строку по символам .
то результат малость в лучшую сторону , но все равно недобор на
несколько байтов.
как устранить ?
все делал как тут
http://www.piclist.ru/S-COM-THREAD-RUS/ ... D-RUS.html
Код: Выделить всё
if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(handle, &Overlap, &temp, true))) _____________________
думал отправлять строку по символам .
Код: Выделить всё
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



