Jump to content

    
Sign in to follow this  
uvw

Работа с СОМ портом

Recommended Posts

1. поднять приоритет потока приложения повыше . Как можно выше и

не запускать другие приложения.

2. отрихтовать вручную (это для win98 - для XP сам смотри как там..):

пуск-настройка-панель управления-система-устройства-последовательный порт (1?)-свойства-настройка порта-дополнительно-буфер приема =1-OK.

 

 

Настройка вручную порта из виндов не помогает - все равно не успеваю.

Насчет приоритета потока, насколько я понял, все не так просто. Вот здесь есть переводная статья http://www.void.ru/?do=printable&id=701 ,правда по прямому доступу к порту, но основа там разложена хорошо.

 

Проблема в том, что у меня не работает (или я неправильно им пользуюсь) драйвер прямого доступа, хотя делал все по мануалу, включая ассемблерный код.

Share this post


Link to post
Share on other sites

_WM, боьшое спасибо за ценную информацию!

Разобрался(на моем уровне) с потоками. Многие вещи стали понятны. Установка маски и ожидание события действительно очень удобны при работе с потоками. Но все же вопрос ткаой остался, не знаю корректный ли он. Как распределяются ресурсы по потокам? выставляются приоритеты?

На счет ввода/вывода в одном потоке. Свою программу писал под 98 и вывод производился в основном потоке, при нажатиии клавиши. Ввод, по совету _WM, я загнал в отдельный поток. Такая комбинация под 98 работает, под XP не хочет. Может конечно не в этом дело.

Share this post


Link to post
Share on other sites
Как распределяются ресурсы по потокам? выставляются приоритеты?

Попробуй почитать это:

http://club.shelek.com/download.php?id=239

Хотя лично мне в этой книге не все понравилось, но тем не менее

это одна из самых лучших книг.

 

 

  На счет ввода/вывода в одном потоке. Свою программу писал под 98 и вывод производился в основном потоке, при нажатиии клавиши. Ввод, по совету _WM, я загнал в отдельный поток. Такая комбинация под 98 работает, под XP не хочет.

 

У меня было то же самое. :(

Скорее всего, поможет и ввод и вывод организовать в одном потоке.

:)

Share this post


Link to post
Share on other sites
Настройка вручную порта из виндов не помогает - все равно не успеваю.

 

А в цифрах - это сколько получилось ?

Как я понял, нужно 10 ms.

И насколько большой выходит "перебор" ? :blink:

Share this post


Link to post
Share on other sites

2Lukomor

2 вариант - немного не понял. Что значит "с собственным драйвером"? Если это с использованием недокументированных I/O функций WINAPI, то это уже имело место быть в giveio и т.д.

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

11 мс это очень маленький интервал для Win приложения, увеличения приоритетов может не помогут. Логично предположить, что данные внешнему устройству нужно отправлять в обработчике прерывания COM-порта (сразу после получения командного слова). Сделать это можно только написав свой драйвер. Засада может быть одна - сложная (длительная) обработка командного слова в PC. Win не любит, когда драйвер много времени отжирает.

 

Я пробую в виндовское оконное приложение воткнуть команды ассемблера для прямой работы с портом, а чтобы не "орала" защита гружу giveio.

Да я это понял:

В виндовом приложении чтение можно организовать только полингом регистра статуса (LSR). Оно тебе надо? Это ж тормоза 100%, а на большой скорости данные теряться будут.

 

Вариант, по моему, тупиковый :( Даже если ты и получишь доступ из виндового приложения к портам, как ты будешь узнавать, что данные поступили, т.е. в какой момент надо читать 0x3f8? Под ДОС все просто, либо прерывания по приему данных обрабатывай, либо регистр статуса (LSR) опрашивай (в нем есть бит, означающий наличие непрочитанных данных). В винде прерывания только в драйвере обработать можно. В пользовательском приложении(не драйвере) опрос(полинг) LSR может в любой момент прерваться по той же причине, по которой ты не успеваешь в WinAPI (многозадачность). Спасти может только наличие фифо буфера в UART.

 

Пуск->настройка->панель упр->система->оборудование->дисп.устройств->порты COM и LPT. Для выгрузки драйвера удали COM порт как устройство.

Далее не перезагружаясь запускай свою программу. Программа должна проинициализировать COM порт, а потом в цикле писать в 3f8. В общем все как под ДОС. Глупый вопрос, может ты данные не на том пине смотришь?

 

Увеличение приоритета меня порой спасало.

Для увеличение приоритета:

Приложения : SetPriorityClass() с GetCurrentProcessId()

Потока: SetThreadPriority() c GetCurrentThreadId();

Причем важно увеличивать приоритет не только приложения, но и потока в котором делаешь ReadFile()!!!

Share this post


Link to post
Share on other sites

2-Tумблер-&PowerF1&Lukomor

Проблем с разными потоками под XP не испытывал.

Отрываю от сердца самописный пример под ц++дебилдер 6.0

Он, по моему, работал на всем, что только можно.

В одном потоке нон-стопом льет данные в коматоз, в другом потоке из этого же кома принимает. Софтина задумывалась как тестер канала связи. Динамически снижает скорость при появлении ошибок.

Для проверки замкнуть пины RX и TX.

Глючит при закрытии, если не приняла ни одного байта.

Кто будет запускать exe - проверте на вирусы, я антивирусами не пользуюсь.

Исходники предоставляю для ознакомления, просьба ими не раскидываться.

 

 

о п с .... старая версия только есть. завтра с работы нормальную принесу.

Share this post


Link to post
Share on other sites
А в цифрах - это сколько получилось ?

Как я понял, нужно 10 ms.

И насколько большой выходит "перебор" ? :blink:

 

По грубой оценке около 30-40 ms.

Share this post


Link to post
Share on other sites

2_VM

Пуск->настройка->панель упр->система->оборудование->дисп.устройств->порты COM и LPT. Для выгрузки драйвера удали COM порт как устройство.

Далее не перезагружаясь запускай свою программу. Программа должна проинициализировать COM порт, а потом в цикле писать в 3f8. В общем все как под ДОС. Глупый вопрос, может ты данные не на том пине смотришь?

 

Увеличение приоритета меня порой спасало.

Для увеличение приоритета:

Приложения : SetPriorityClass() с GetCurrentProcessId()

Потока: SetThreadPriority() c GetCurrentThreadId();

Причем важно увеличивать приоритет не только приложения, но и потока в котором делаешь ReadFile()!!!

Спасибо за совет, обязательно попробую, но чувствую придется мне писать драйвер. :(

Пин вроде тот - проверял в W98 - передача идет.

 

2All

Никто случайно не знает, где в сети можно найти информацию по написанию драйверов на простеньком уровне? Потому как дело это для меня совсем новое. :blink:

Share this post


Link to post
Share on other sites

Если владеешь C++ поищи Numega Driver Studio (софт коммерческий). Она с документацией идет. Для твоей задачи ненадо глубоко вникать в архитектуру виндов, а нумега ее внутри своих C++ классов скрывает. В общем я с нее начинал и доволен.

 

Но я бы на винапи еще подолбился бы. С драйвером конечно интереснее и надежнее, но разобраться не быстро получится.

Share this post


Link to post
Share on other sites
Здравствуйте, уважаемые!

Если кто сталкивался, помогите плизз. Долбаюсь уже 2 недели, и ничего не получается. Ситуация следующая: Есть некий контроллер и общается он с компьютером через RS232, в Win98 все работает, а вот Операционка Win2000

блокирует прямое обращение к портам. Мне подсказали прогу WinDriver для обхода этой проблемы... но опять-же, для LPT порта там есть стандартная заготовка, которая прекрасно работает... а о СОМ порте ни слова. Сразу оговорюсь, я не являюсь системным программистом и с железом дел никогда не имел... а тут пришлось ;) Искренне надеюсь на Вашу помощь. Заранее спасибо.

З.Ы.

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

ЗЗ.ЫЫ

Работать с этой штукой через CreateFile/ReadFile/WriteFile тоже не получается,

в ReadFile постоянно нули возвращаются, хотя команда сформирована верно и контроллером принята...

 

 

Привет.

Может быть мой ответ устарел

Попробуй проверить свою программу так.

 

Соедени Com порты(Com1 , Com2) своей персоналки через нуль - модемный кабель.

Распайка

2-3

3-2

5-5

6 6

| |

4 4

7 7

| |

8 8

Запусти гипертерминал для Com2 в Win2000 и поставь настройки Com2

такие как в твоей программе для опроса контроллера.

Запусти свою программу для Com1 попробуй опросить контроллер.

Если программа что то кидает на Com1 то ты увидишь это в гипертерминале,

т.е. ты убедишься что у тебя программа что то посылает.

 

 

Так же я тебе могу предложить библиотеку программирования для COm

портов, если ты ее используешь то в программировании много знать не надо

она работает и под win2000 и под win98 (С ,VC, BC, VB)

ее можно скачать на www.webfile.ru

Файл номер 240397, pcommpro20.rar (размер 652 кбайт)

 

 

 

 

Пример:

int port = 2;

 

//настроить COM2 38400 8 бит данных 1 стоповый

ret = sio_ioctl ( 2, B38400, P_NONE | BIT_8 | STOP_1 );

 

if (ret != SIO_OK) {

/* Setting fail */

}

 

 

Нужно еще DTR поднять посмотри функцию в хелпе

 

ret = sio_open (port); //Открыть COM2

if ( ret != SIO_OK ) {

/* Open fail */

}

int len;

char buf[10];

len = sio_read( 2, buf, 10); //прочитать 10 байт с COM2

if (ch < 0) {

/* Fail */

}

Share this post


Link to post
Share on other sites
А в цифрах - это сколько получилось ?

Как я понял, нужно 10 ms.

И насколько большой выходит "перебор" ? :blink:

 

По грубой оценке около 30-40 ms.

 

Сегодня я ноконец померил - и вот что получилось:

 

При работе с одним потоком на прием и передачу - ~6 ms на ответ.

Если поток имеет приоритет NORMAL действительно, его прерывают

и иногда выходит ~30ms. Хотя и редко, это бывает.

Если поставить приоритет этому потоку Тайм_Критикал, то ему

никто особенно не мешает. :) Кроме ~6ms других значений времени

не зафиксировано.

Система была WIN98, PII-300, VC6+API ONLY. :)

Ничего особенно навороченного..

В качестве темплате использовалось готовое приложение

с двумя потоками - основной Нормал+2 и еще рабочий Нормал.

Под WIN-XP измерять буду завтра...

:blush:

Share this post


Link to post
Share on other sites
Под WIN-XP измерять буду завтра...

  :blush:

 

Так вышло, что измерил сейчас.

Получилось то же самое ~6ms на ответ.

Все то же самое.

 

Вполне вероятно, можно обойтись без драйверов

и лазания в порты.

:blush:

Share this post


Link to post
Share on other sites
Под WIN-XP измерять буду завтра...

  :blush:

 

Так вышло, что измерил сейчас.

Получилось то же самое ~6ms на ответ.

Все то же самое.

 

Вполне вероятно, можно обойтись без драйверов

и лазания в порты.

:blush:

2-Тумблер-

Спасибо, я действительно поигрался с приоритетами и потоками, вроде получилось, но проблема была в другом, "поймать" ответ устройства. Ответ приходит через ~11 мкс после запроса, при этом обмен идет через интерфесный девайс. От компьютера до девайса RS232 с управлением RTS, от девайса до устройства 485 интерфейс без управления потоком. Мне надо успеть вручную переключить RTS. Для работы с портом выставляю REALTIME_PRIORITY_CLASS и THREAD_PRIORITY_TIME_CRITICAL. С натягом, но все успеваю.

Share this post


Link to post
Share on other sites
Для работы с портом выставляю REALTIME_PRIORITY_CLASS и THREAD_PRIORITY_TIME_CRITICAL. С натягом, но все успеваю.

 

Извините, если скажу общеизвестное. :)

Приоритет потока - вешь относительная.

Если посмотреть каким-либо процесс вьювером,

можно обнаружить, что абсолютный приоритет

потоков "обычного" приложения не может превысить ~15.

У Кернела - вдвое больше.

Так что резервы еще есть. :blush:

Можно попытаться увеличить приоритет процесса.

Тогда "THREAD_PRIORITY_TIME_CRITICAL" станет еще выше..

:biggrin:

Share this post


Link to post
Share on other sites
Извините, если скажу общеизвестное. :)

Приоритет потока - вешь относительная.

Если посмотреть каким-либо процесс вьювером,

можно обнаружить, что абсолютный приоритет

потоков "обычного" приложения не может превысить ~15.

У Кернела - вдвое больше.

Так что резервы еще есть. :blush:

Можно попытаться увеличить приоритет процесса.

Тогда "THREAD_PRIORITY_TIME_CRITICAL" станет еще выше..

:biggrin:

 

Так REALTIME_PRIORITY_CLASS это вроде и есть приоритет процесса :)

Скажу больше - для приоритета есть еще и динамический диапазон определяемый относительно базового. :blink:

Правда для такого REALTIME приоритета процесса, поток все равно получился 15. Не знаю почему. Глубоко не ковырялся.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this