реклама на сайте
подробности

 
 
6 страниц V  < 1 2 3 4 5 > »   
Reply to this topicStart new topic
> Windows7: прием байтов через COM-порт без потерь, Кто-то имеет личный опыт? чем побороть потерю отдельных байтов?
AlexRayne
сообщение May 23 2017, 20:00
Сообщение #31


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(Ruslan1 @ May 23 2017, 20:13) *
дада, спасибо, буду думать. А как без Synchronize это сделать? неужто через глобальные переменные нельзя?
Просто скажите в каком направлении копать, я копать умею только где не знаю....
(Upd: извиняюсь, уже прочитал совет про евенты и семафоры, значит через них буду. Тогда уже сразу про очереди поищу, чтоб просто мессадж с новым указателем записи передать в ожидающую нитку- надеюсь оно тут есть где-то).

Можно конечно и глобальные.
а передавать сигнал гтовности другой нитке никоим образом не через Synchronize, а нормальными примитивами синхронизации потоков. классический вариант - семафор (у венды есть более облегченная версия - Event, но это малость несоотвествует задаче). надо собрать из вашего кольцевого буфера пакет, положить его в глобальную переменную, и отдать семафор сторонней принимающей нитке, или както просигналить что готово. както так.

Цитата(Ruslan1 @ May 23 2017, 20:13) *
У меня классический кольцевой буфер, в который один процесс что-то записывает по указателю записи, другой процесс -что-то читает по указателю чтения. Само собой, когда-то доходим до конца буфера и должны следующий байт в его начало записать. Я не понял Вашу идею про "никогда". Указатель записи доходит до RX_RINGBUFF_SIZE периодически, каждые RX_RINGBUFF_SIZE байт.

С RX_RINGBUFF_SIZE - у вас все правильно, но переполнение кольцевого буфера вы действительно не контролируете. некрасиво это.
я ушел от кольцевого буфера, ибо гемора с ним много - следить где голова где хвост.
использую линейный буфер - в котором надо накопить целый пакет. как только пакет набрался - отдаю его, а остаток буфера перемащаю в начало.
такая схема позволяет использовать чтение с заданием требуемой длинны, а не как у вас сейчас - ожидание любого события. событий летит много и часто, поэтому лучше использовать блокирующее чтение, и задать длину пакета. буфер в этом случае нужен чтобы проконтроливать качество полученного из порта, и откинуть ненужный мусор если он прилетит.

Сообщение отредактировал AlexRayne - May 23 2017, 20:06
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 24 2017, 07:07
Сообщение #32


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Добавлю в копилку способов передачи данных от потока приёма к основному потоку: PostMessage().
Эта функция помещает сообщение в очередь на обработку и тут же возвращает управление. А уж когда главный поток его заберёт и обработает - это его дело.
Я делал так: в потоке приёма создавал на куче пакет, собирал его, проверял валидность, потом отправлял главному окну указатель на этот пакет при помощи PustMessage(). Главный поток обрабатывал пакет и удалял его.
Всё очень просто, надёжно, никто никого не ждёт, и не надо париться с синхронизацией.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение May 24 2017, 07:35
Сообщение #33


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(Ruslan1 @ May 22 2017, 09:27) *
Здравствуйте!
Есть Windows7 Pro, 32-bit, компьютер- китайский одноплатник на Intel 1037U, 4GB RAM.
СОМ-порты- 4 штуки прямо на материнке.
И есть внешний передатчик, посылающий в COM-порт пакеты.

Заранее спасибо за любые советы (по существу).


Насколько вижу ни Intel 1037U ни его Platform Controller Hub (PCH) не имеют UART-ов.
Значит ваши UART-ы виртуальные через USB.
Я бы посмотрел что у вас еще на USB висит (камера, Wi-Fi...) и поотключал бы их жестким сносом драйверов из системы.
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 24 2017, 12:52
Сообщение #34


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Напишите хоть в чем выявился источник потерь
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение May 24 2017, 12:53
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Цитата(AlexandrY @ May 24 2017, 09:35) *
Насколько вижу ни Intel 1037U ни его Platform Controller Hub (PCH) не имеют UART-ов.
Значит ваши UART-ы виртуальные через USB.
Я бы посмотрел что у вас еще на USB висит (камера, Wi-Fi...) и поотключал бы их жестким сносом драйверов из системы.

Спасибо, интересная идея, не подумал про такое.
Сериальные порты в BIOS Setup уже видны, или по этому признаку не определить через что оно работает? Есть какие-то низкоуровневые тестеры, чтоб подергали железо и сказали через какой чип оно работает и что еще на каком хабе сидит (если это USB)? Машинка используется вот такая. (кстати, эта модель очень понравилась по качеству исполнения)

Но вряд ли дело только в этом, даже если так. Пробовал и с совершенно другим железом -то же самое видел. Думаю, глюки у меня в программе, займусь корректировкой и тестами ближе к выходным, материала и идей тут накидали достаточно, лишь бы время найти sm.gif
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 24 2017, 12:55
Сообщение #36


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(Ruslan1 @ May 24 2017, 16:53) *
Спаисибо, интересная идея, не подумал про такое.
Сериальные порты в BIOS Setup уже видны, или по этому признаку не определить через что оно работает? Есть какие-то низкоуровневые тестеры, чтоб подергали железо и сказали через какой чип оно работает и что еще на каком хабе сидит (если это USB)? Машинка используется вот такая. (кстати, эта модель очень понравилась по качеству исполнения)

Но вряд ли дело только в этом, даже если так. Пробовал и с совершенно другим железом -то же самое видел. Думаю, глюки у меня в программе, займусь корректировкой и тестами ближе к выходным, материала и идей тут накидали достаточно, лишь бы время найти sm.gif

А в диспетчере устройств это хозяйство не разглядеть?
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение May 24 2017, 12:55
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Цитата(AlexRayne @ May 24 2017, 14:52) *
Напишите хоть в чем выявился источник потерь

Я обязательно отпишусь как разберусь/не разберусь, пока руки не дошли, через день-два возьмусь. Приоритеты задач меняются на ходу...
Go to the top of the page
 
+Quote Post
Timmy
сообщение May 25 2017, 10:49
Сообщение #38


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



В коде меня удивляет использование overlapped WaitCommEvent(). Можно ли сразу вызывать WaitForSingleObject() и GetOverlappedResult(), не проверив по коду возврата WaitCommEvent() и GetLastError(), что WaitCommEvent() ушла в асинхронный режим, как это всегда делается в примерах от Микрософт?
Go to the top of the page
 
+Quote Post
XVR
сообщение May 25 2017, 11:14
Сообщение #39


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



WaitForSingleObject вызывать можно. Если WaitCommEvent не ушла в wait, то event останется в том состоянии, в котором был. А был он в установленом состоянии.
А вот GetOverlappedResult неизвестно - MSDN на этот счет молчит
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 25 2017, 22:14
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(sonycman @ May 22 2017, 15:48) *
Тоже думаю, что проблема просто в переполнении ФИФО аппаратного приёмника.
Потому, что винда тупо не успевает выгребать данные.

Не думайте ибо этого не может быть.
Даже если-б загрузка CPU была == 100%, драйвер COM-порта, работающий на высоком уровне привилегий, всё равно успевал бы всё выгребать. Тем более на такой низкой скорости. Тем более, что и загрузка CPU никакая.

Цитата(AHTOXA @ May 24 2017, 09:07) *
Я делал так: в потоке приёма создавал на куче пакет, собирал его, проверял валидность, потом отправлял главному окну указатель на этот пакет при помощи PustMessage(). Главный поток обрабатывал пакет и удалял его.

Хмм... А очередь сообщений, связанная с окном и её обработка тредом окна гарантирует, что сообщения из этой очереди будут обрабатываться в том же порядке, в котором они постились в очередь? Тем более если постинг идёт из разных тредов?
Я бы на это не рассчитывал.
Да и вроде в случае межпоточной передачи сообщений, PostMessage аналогичен SendMessage-у.

Цитата(DS @ May 22 2017, 21:49) *
В 7 похоже, есть баг в COM драйвере. Многие программы, нормально работавшие с XP, глючат с ком-портами на 7. Единственное, что надежно под ней работает -USB-COM адаптер, причем с FTDI чипом.

Моя программа, написанная много лет назад под WinXP, сейчас работает одновременно с 3-я компортами на Win8, каждый - на скорости 921600 бод (отладочные потоки 3-х устройств). Сейчас это COM-порты - на PCI-карте, раньше были - на USB-UART-ах (FTDI и CP210x), а также - комбинации того и другого.
До этого всё так же работало на Win10 на другом компе. Работает это целыми днями.
Так что проблема 99.9% не в виндовых дровах. А как всегда - в кривых руках написателей этих "многих программ".
Проблемы возникают только с PL230x на высоких скоростях. На всех опробованных виндах. Вот тут явно дело в дровах Prolific.
Go to the top of the page
 
+Quote Post
V_G
сообщение May 25 2017, 22:37
Сообщение #41


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(XVR @ May 25 2017, 21:14) *
WaitForSingleObject вызывать можно. Если WaitCommEvent не ушла в wait, то event останется в том состоянии, в котором был. А был он в установленом состоянии.
А вот GetOverlappedResult неизвестно - MSDN на этот счет молчит

У меня все работает нормально с WaitCommEvent и без WaitForSingleObject. Два подряд ожидания не есть хорошо: тут может быть потенциальная причина пропуска информации.
После того, как WaitCommEvent дождалась события, я просто делаю ResetEvent, проверяю код события, по EV_RXFLAG делаю обработку, по другим либо возвращаюсь к WaitCommEvent, либо закрываю порт (если в основном потоке устанавливаю специальный флаг, сигнализирующий о необходимости закрытия)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 26 2017, 07:05
Сообщение #42


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(jcxz @ May 26 2017, 03:14) *
Хмм... А очередь сообщений, связанная с окном и её обработка тредом окна гарантирует, что сообщения из этой очереди будут обрабатываться в том же порядке, в котором они постились в очередь?

Да, гарантирует:
Цитата
With the exception of the WM_PAINT message, the WM_TIMER message, and the WM_QUIT message, the system always posts messages at the end of a message queue. This ensures that a window receives its input messages in the proper first in, first out (FIFO) sequence.

Цитата(jcxz @ May 26 2017, 03:14) *
Тем более если постинг идёт из разных тредов?

Без разницы.
Цитата(jcxz @ May 26 2017, 03:14) *
Я бы на это не рассчитывал.

А здесь не надо гадать, надо просто читать документацию.
Цитата(jcxz @ May 26 2017, 03:14) *
Да и вроде в случае межпоточной передачи сообщений, PostMessage аналогичен SendMessage-у.

Нет.

ЗЫ. Совершенно очевидно, что вы не разбираетесь в теме ©.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 26 2017, 10:14
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AHTOXA @ May 26 2017, 09:05) *
Да, гарантирует:
А здесь не надо гадать, надо просто читать документацию.

Читать лень - сейчас это не нужно. Но помнится, что в WinAPI есть функции, позволяющие считывать сообщения из очереди по маске. А значит - в произвольном порядке.

Цитата(AHTOXA @ May 26 2017, 09:05) *
Нет.
ЗЫ. Совершенно очевидно, что вы не разбираетесь в теме ©.

Да ладно! А если внимательнее прочитать описание WinAPI? wink.gif

Цитата(AHTOXA @ May 24 2017, 09:07) *
Я делал так: в потоке приёма создавал на куче пакет, собирал его, проверял валидность, потом отправлял главному окну указатель на этот пакет при помощи PustMessage().

А если надо отправить сообщение не главному окну? Или у Вас всегда приложения только с одним окном? laughing.gif
Go to the top of the page
 
+Quote Post
rudy_b
сообщение May 26 2017, 10:19
Сообщение #44


Знающий
****

Группа: Свой
Сообщений: 888
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Тут есть стандартная проблема - после приема пришедшего байта, прежде, чем сбрасывать событие, необходимо проверить не пришел-ли еще один байт и, если пришел - выбрать и его. Если этого не сделать а просто сбросить событие - он будет потерян. Т.е. его приход вызовет второе событие, но оно будет сброшено вместе с первым.

Вероятность лишнего сброса события есть всегда. Нужна атомарная команда сброса события при условии отсутствия принятых байт, но ее нет и все зависит от реализации ОС.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 26 2017, 10:33
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(rudy_b @ May 26 2017, 12:19) *
Вероятность лишнего сброса события есть всегда. Нужна атомарная команда сброса события при условии отсутствия принятых байт, но ее нет и все зависит от реализации ОС.

Проблем нет никаких при грамотном построении алгоритма:
Принимающий тред пишет байты в кольцевой буфер. После каждого обновления содержимого буфера (или не после каждого, а при достижении некоего уровня + по таймауту) посылает нотификацию (оконным сообщением) треду, в котором находится управляющее окно. Управляющее окно, получив нотификацию, читает кольцевой буфер из приёмного треда.
Естественно - парсинг потока байт на пакеты и уж тем более - обработку пакетов, желательно делать уже в треде управляющего окна. Не надо смешивать уровни обработки протокола.
PS: И желательно, без реальной необходимости, избегать передачи указателей на блоки данных в куче между тредами. Как тут советуют некоторые товарищи....
Go to the top of the page
 
+Quote Post

6 страниц V  < 1 2 3 4 5 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 12th July 2025 - 22:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01528 секунд с 7
ELECTRONIX ©2004-2016