И какое число было в temp? Ситуация дописывания в буффер после вызова Write и до завершения передачи исключена? Не может так быть, что вы на самом деле заказали [поспешили, ага] отсылку строки длиной 176 байт, но "за время пути собака смогла подрасти" на 10 байт (другой поток подгадил, к примеру - они это любят) и пост-мортем вы видите не то, что должно быть по вашему убеждению? Оттрассируйте длину строки на момент передачи. Проверьте этот-же код на RS232 порту другого типа - FTDI, CP2101, PL2303, честный RS232 - чтобы исключить проблемы в системных драйверах. На той стороне что видно - "обрез" или все данные?
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Вы пытаетесь синхронизировать приём по событию завершения передачи? Ну тут последние байты могут быть ещё вообще даже не "в линии" а в буфферах порта. Да и будучи переданными, кмк, у них есть целая вечность до того как доберутся до вашего приёмного буффера и вас известят о сём событии. Синхронизировать надо по событию завершения приёма. Но там судя по всему у вас есть свои нюансы. А если длина пакета недетерминирована - читайте по байту, подсовывая Read-у каждый раз инкрементированный указатель в буффере приёма пока не встретится символ-терминатор. Нету терминатора - отсылайте strlen(buffer) + 1 и ждите появления в принимаемом потоке нуля. После чего быстренько обрабатываете пакет, возвращаете указатель чтения на начало буффера и вновь заряжаете Read.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
unsigned char bufrd[BUFSIZE], bufwr[BUFSIZE]; //приёмный и передающий буферы
//----------
HANDLE COMport; //дескриптор порта
//структура OVERLAPPED необходима для асинхронных операций, при этом для операции чтения и записи //нужно объявить разные структуры //эти структуры необходимо объявить глобально, иначе программа не будет работать правильно OVERLAPPED overlapped; //будем использовать для операций чтения (см. поток ReadThread) OVERLAPPED overlappedwr; //будем использовать для операций записи (см. поток WriteThread) //----------
//главная функция потока, реализует приём байтов из COM-порта { COMSTAT comstat; //структура текущего состояния порта, в данной программе используется //для определения количества принятых в порт байтов DWORD btr, temp, mask, signal; //переменная temp используется в качестве заглушки
//создать сигнальный объект-событие для асинхронных операций overlapped.hEvent = CreateEvent(NULL, true, true, NULL);
//установить маску на срабатывание по событию приёма байта в порт SetCommMask(COMport, EV_RXCHAR); while(условие) //пока поток не будет прерван, выполняем цикл { //ожидать события приёма байта (это и есть перекрываемая операция) WaitCommEvent(COMport, &mask, &overlapped);
signal = WaitForSingleObject(overlapped.hEvent, INFINITE); //приостановить поток до прихода байта if(signal == WAIT_OBJECT_0) //если событие прихода байта произошло { if(GetOverlappedResult(COMport, &overlapped, &temp, true)) //проверяем, успешно ли завершилась //перекрываемая операция WaitCommEvent if((mask & EV_RXCHAR)!=0) //если произошло именно событие прихода байта { ClearCommError(COMport, &temp, &comstat); //нужно заполнить структуру COMSTAT btr = comstat.cbInQue; //и получить из неё количество принятых байтов if(btr) //если действительно есть байты для чтения { ReadFile(COMport, bufrd, btr, &temp, &overlapped); //прочитать байты из порта в буфер программы } } } } CloseHandle(overlapped.hEvent); //перед выходом из потока закрыть объект-событие }
//----------
зачем после
WaitCommEvent(COMport, &mask, &overlapped);
нужна
signal = WaitForSingleObject(overlapped.hEvent, INFINITE);
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
Автора спрашивать надо - по мне так атавизм от предыдуших попыток поработать в блокируюшем режиме. Вообще смысл использования OVERLAPPED режима в том, что мы заказали операцию с портом и пошли заниматься своими делами, потом вернулись проверили событие завершения - т.е. даже лишних потоков заводить не надо - всё в одном. А вот этих самых "делов" может быть всё что угодно - а если сразу суспендим исполнение в WaitFor*Object*(..., INFINITE) после запроса записи/чтения - к чему заморочки с OVERLAPPED? Открываем в блокирующем режиме и получаем то же самое.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Так при записи мы пишем в файловый поток и ждем сигнального события что данные ушли и можно писать новые. При чтении же все наоборот, мы ждем сигнала о том что в буфере есть данные и читаем иx.
_________________ Иван Сусанин - первый полупроводник
В данном случае перекрываемую операцию активирует функция WaitCommEvent. Она запускает ожидание события порта, заданного маской, и, если событие не наступает немедленно, передаёт управление обратно программе и возвращает FALSE, а система устанавливает объект-событие в несигнальное состояние.
_________________ Иван Сусанин - первый полупроводник
Не должно. Данный конкретный вызов Wait* в цитируемом коде относится не к Read а к WaitCommEvent. Read там вообще не использует overlapped возможности - тупо читает столько байт, сколько имеется в очереди.
СЦБист писал(а):
правда ли что WaitCommEvent(handle, &mask, &Overlap_1);
сбрасывает Overlap_1.hEvent в не сигнальное состояние.
"If the overlapped operation cannot be completed immediately, the function returns FALSE and the GetLastError function returns ERROR_IO_PENDING, indicating that the operation is executing in the background. When this happens, the system sets the hEvent member of the OVERLAPPED structure to the not-signaled state before WaitCommEvent returns, and then it sets it to the signaled state when one of the specified events or an error occurs. The calling process can use one of the wait functions to determine the event object's state and then use the GetOverlappedResult function to determine the results of the WaitCommEvent operation. "
Т.е. если операция ещё не завершена - то система выставит событие в несигнальное состояние. И [система] включит его как только заказанное событие возникнет. Т.е. как следует из контекста - сбрасывается оно только для того чтобы иметь возможность поведать миру о наступлении события про которое спросили посредством WaitCommEvent.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
В более идеальном мире чем тот, что окружает нас - совершенно излишняя предосторожность - потому как перед чтением мы осведомляемся о количестве наличиных в очереди байт - т.е. блокировка не возможна. Но в качестве эдакого ASSERT-а - да, не помешает.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
Для копирования строчек с контролем размера есть стандартная strncpy. В нынешней реализации если попытаетесь записать ровно 1000 байт - вылетите за пределы массива и - либо подгадите нулём buffer_write, либо наползёте на голову структуры read.overlapped.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
while (!_readingThreadDisable) { uint mask; // Запускаем ожидание события прихода данных WaitCommEvent(_hPortHanle, out mask, GetNativeOvPtr(_nativeOvRd));
// Приостанавливаем поток пока объект-событие не перейдет в сигнальное состояние // по приходу данных в порт var signal = WaitForSingleObject(_nativeOvRd.EventHandle, Infinite);
if (_readingThreadDisable) break;
uint temp; // Проверяем корректность события вызвавшего возобновление работы потока if (signal != WaitObject0 || !GetOverlappedResult(_hPortHanle, ref _nativeOvRd, out temp, true) || (mask & EvRxChar) == 0) continue;
ComStat comstat; uint flags; // Считываем количество байт в приемном буфере ClearCommError(_hPortHanle, out flags, out comstat); var bytesNum = comstat.cbInQue;
if (bytesNum <= 0) continue; var dataBuffer = new byte[bytesNum];
// Считываем данные из приемного буфера if (!ReadFile(_hPortHanle, dataBuffer, bytesNum, out temp, ref _nativeOvRd)) continue;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения