Перехват прерывания от СОМ-порта
4410
13
Здравствуйте, уважаемые знатоки!
Пожалуйста, подскажите!!! --->

Не получается перехватывать прерывание от СОМ-порта... Написана новая функция-обработчик, подставлена вместо старой, соответствующим образом проинициализированы управляющие регистры контроллера СоМ-порта...выбран "диагностический режим" (порт замнут на себя - принимает то, что на него выдано...)
ОДНАКО...
программа построена таким образом --> после записи в выходной регистр порта символа --> сначала программа немного ждёт (~1...2 сек - пробовали по-разному) - вдруг сработает прерывание... а потом, если прерывание по приёму символа не срабатывеат, программа просто проверяет состояние регистров асинхронного адаптера (оказывается, что регистр передачи пуст, регистр приёма - содержит только что переданный символ... и остальные флаги свидетельствуют об успешном принятии символа...) НО ПРЕРЫВАНИЕ НЕ СРАБОТАЛО! (ни по передаче, ни по приёму, ни по ошибкам приёма-передачи!!!)
Программа написана на Borland C v3.1

При запуске программы из Windows - можно предположить, что состояние статусных регистров считывается верно, но при запуске из-под DOS в регистрах LSR (Line Status Register), MSR (Modem Status Register) читаются все единицы: 1111 1111 !!!

Что делать?:хммм:
Что можно предпринять? :хммм:
...петлю на голову ? :help.gif:

Большое спасибо!!!
Дуб
В чем пишите? Какая ОСь? Попросил бы и код, но не уверен что знаю то на чем пишите =)
Mad_Dollar
Дорогой товарищ!! Спасибо за ответ!!
... а то совсем уже горько стало...

Программа должна работать под "Win'дами", т.е. под WIN98/95 или даже под DOS (автоматизация промышленных процессов, нужна именно такая конфигурация...)

Текст программы -- в прикреплённом файле.

//P.S.: При запуске из-под Windows и из-под DOS --> разные результаты, как было описано выше... С чем это может быть связано? (может быть, что-нибудь по скоростям не совпадает...?)

Большое Спасибо!!! %)
Дуб
Разница здесь лишь в орг. структуре ДОса и ВЕНДы. Из под венды Вы своим кодом никогда не получите полного доступа к ком-порту исключительно из той архитектуры псевдомультизадачности, которая в ней воплощена.

Если ваша программа должна работать из под винды и причем, насколько я понимаю в режиме монопольного доступа к порту - вам нужно писать свой vxd-драйвер. Если вас устроит работа под дос у вас вполне правильный код, только он подойдет под 6,22 версию.

Если вы работает под ВЕНДОЙ используйте функции АПИ, предоставляемые ВЕНДОЙ.

Ваш код в принципе помоему нигде работать не будет, за исключением ДОСа 6,22 (может и младше). Если пишите с привязкой к платформе, то используйте винапи (сейчас нет под руками справочника, сорри), если пишете под никс - то открывайте порт как файл.

Вывод и мое имхо: если пишите вин-приложение - то и используйте апи винды, вместе с циклом обработки сообщений. Если пишите под никс - используте стандартные функции ioctrl, вы сейчас открываете порт через биос насколько я понимаю?
Дуб
А вообще - лучше читать мсдн, если все-таки будете работать из под венды - там есть и готовые примеры.
Mad_Dollar
Доброго Вам времени!
Спасибо большое!

Ох! : в той же архитектуре, в тем же способом запускаемых программах успешно работают обработчики прерываний от системноого таймера, клавиатуры... ! А вот прерывание от СОМ-порта не перехватывается !!! (т.е. if поставить контрольную точку на входе в новый подставляемый обработчик ---> окажется, что мы туда не заходим !!!) Т.е. ... что-то конечно напортачено...

Необходима возможность работы программы из-под DOS, но возможен запуск в качестве процесса Windows95/98 (если можно так выразиться %) )

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

Большое спасибо!
Дуб
А теперь задумайтесь. Виндовс хоть и псевдо, но мультизадачная система. В досе все понятно было - вы имели прямой полный доступ к устройствам системы, в виндовс же, дабы 1) унифицировать апи обращений к устройствам 2) по соображениям реализации мультизадачности - прямой доступ к портам ввода-вывода и дискам невозможен.

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

При работе виндовс, если вы не знаете, есть несколько уровней работы прогаммы/драйвера, так вот прямой доступ к физической памяти, портам в/в, дискам может производится только из режима "ринг 0". Более подробно об организации виндовс написал Руссинович, книгу в дежавю-формате могу выслать на мыло, почитайте.

А вам обязательно работать с прерыванием? Вам простой конечный обмен с тту-устройством не подойдет?
Mad_Dollar
Дорогой товарищ, спасибо!

Почитать Руссиновича -- было бы здорово!

Если возможно, то мой адрес такой :улыб:: ilanskiy@email.ru


>> А вам обязательно работать с прерыванием? Вам простой конечный обмен с тту-устройством не подойдет?

<< Да! Это единственный способ асинхронного общения одновременно запущенных на разных машинах процессов!... и стремление приблизиться к ~квази-многозадачной организации ...:улыб:Вобщем, очень нужно научиться писать собственный обработчик прерываний от COM-порта и научиться их перехватывать!:хммм:
Спасибо!
Дуб
<< Да! Это единственный способ асинхронного общения одновременно запущенных на разных машинах процессов!... и стремление приблизиться к ~квази-многозадачной организации ...:улыб:Вобщем, очень нужно научиться писать собственный обработчик прерываний от COM-порта и научиться их перехватывать!:хммм:Спасибо!
А может, стоит-таки пересмотреть архитектуру системы?
Как будете определять коллизии? Что будет, если запросы наложатся во времени?
Вот у меня/, например, была задача отдавать и принимать данные от ~15 устройств. Висели они на общей шине и слушали, что скажет персоналка-хост. ТОЛЬКО услышав свой адрес, плевались в ответ пакетом с данными. Хост опрашивал устройства последовательно с интервалом примерно в полсекунды. Короче, такая тормозная пародия на USB:улыб:Написано все это было на Дельфи, работало под виндами и без всяких заморочек с прерываниями.
GPRS_User
Уважаемый откликнувшийся!
Спасибо за такой интересный пример!:улыб:Хорошая у вас система !!

НО мне без прерывания головы не сносить:хммм:...

Наверное, Ваш ХОСТ был САМ СЕБЕ ХОСТ ! т.е. сам управлял запуском последовательного опроса устройств, а в моём несчастном случае запрос от программы на одном компьютере в программу на другом компьютере - настоящая асинхронная вещь... Моменты общения не синхронизированы ни с какими временными процессами и обусловлены особенностями технологической задачи (например ~~~ необходимо дождаться, когда оператор, совершив подготовительные действия, нажмёт на определённую кнопку ~~~ и тогда немедленно подать сигнал по СОМ-порту...)

Ох!:хммм:
Спасибо!
Дуб
У меня есть несколько программулин давным-давно писанных на VB6 для работы с сом портом через API WIN. Могу скинуть, если что...
Дуб
Ну, у меня тоже операторы на устройствах кнопочки тыкали.
Просто при следующем сеансе обмена с хостом устройство сообщало, что установлены параметры такие-то, тыкнута кнопочка такая-то. Вот, собственно, и все.
Задержка получалась большая, но в моих условиях вполне допустимая.

А вообще, в вашем случае, имхо может помочь функции winapi SetCommMask() с флагом EV_RXCHAR и WaitCommEvent()

Вы, кстати, не ответили, как будете коллизии определять. :улыб:
GPRS_User
Спасибо всем!!
&gt;&gt;&gt; Насчёт определения коллизий - то ... система должна получиться ~~ линейная и предсказуемая... вобщем, пока не до них:улыб:... не до коллизий ... сейчас, можно сказать другие коллизии - ум за разум...т.е. ни того, ни другого...:хммм:

На безрыбье и рак рыба... --&gt;
Получилась такая вещь: срабатывает прерывание от СОМ-порта (всё по алгоритму...) ... НО ТОЛЬКО ОДИН РАЗ после загрузки ОС Windows98... Во второй раз и в следующие разы прерывание уже не сработает... Если снова перезагрузиться - опять при первом запуске программы всё пройдёт... :хммм: Как-будто во второй раз срабатывает вектор прерывания с другим номером...
//// оказалось, что для порта СОМ1 нужно подставлять обработчик прерывания ни в вектор 0xC, а в вектор 0xB ... (а, соответственно, для СОМ2 - вектор 0xC) ...

Ух...

Спасибо.
Дуб
Попробуйти убрать com порт из Windows.
Какие-то настройки там сделать.
У меня была такая бойда - если с ком-порта льется какая-то фигня при загрузке WindowsXP, то устройство определяется как не рабочая мышь и доступ перекрывется. Решилось выкидывнием драйвера мыши (но у меня Embedded система была так что так можно).
Формально доступ к последовательному порту под Windows эмулируется, возможно Windows меняет настройки Fifo и вы не видете прерываний. Попробуйте какой-нибудь терминальной программой посмотреть что происходит - типа Term95 была такая под DOS