Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.07.2008, 17:29   #1
Prot
 
Регистрация: 29.07.2008
Сообщений: 4
По умолчанию Всё тот же старый COM, кто поможет?

Напиал простой kernel-mode драйвер, который по запросу user-mode программы, устанавливает или очищает в регистре 3FCh порта COM1 бит номер 0. Т.е. тем самым он управляет состоянием линиии DTR порта. По крайней мере так должно быть. Замеряя уровень сигнала на линии DTR равный -12В и выдавая команду драйверу на изменение состояния линии DTR, уровень не меняется на +12В. Почему ???
P.S. Если предварительно открыть порт стандартными win-средствами (api-функция CreateFile), то все работает. Что же делает стандартный драйвер с портом такого, что после этого, мой драйвер нпчинает реально управлять линией DTR???
Prot вне форума Ответить с цитированием
Старый 29.07.2008, 19:33   #2
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Во-первых, при написании таких вещей под Windows рекомендуется использовать стандартные средства Windows, так как возможно не только ты один пользуешься этим портом.
rpy3uH вне форума Ответить с цитированием
Старый 29.07.2008, 21:26   #3
Prot
 
Регистрация: 29.07.2008
Сообщений: 4
По умолчанию Всё тот же старый COM, кто поможет?

Согласен, но не в данном случае. Мне как раз и надо чтобы другое приложение работало с COM портом, как обычно, стандартными функциями Window. А моё user-mode приложение в это же самое время могло управлять линией DTR. Собственно для этого и писался kernel-mode "драйвер". И моё приложение не использует API CreateFile, т.к. в противном случае, только моё приложение получит монопольный доступ у порту. Вопрос в том почему линия DTR управляется только после открытия порта функцией CreateFile, вызываемой из какого либо приложения, напр. HyperTerminal, а если порт закрыт, то не управляется посредством mov DX,3FCh mov AL,1 out DX,AL
Prot вне форума Ответить с цитированием
Старый 06.09.2008, 15:26   #4
Steve_s
 
Регистрация: 06.09.2008
Сообщений: 4
По умолчанию

У меня немного другая проблема, но тоже по COM порту, так что решил не создавать новую тему.
Я начал писать ASM программу под DOS, которая представляет собой некое подобие терминала. Программа должна работать без использования прерываний от микросхем COM порта (т.е. опрашивая порт сама). Использует только COM1 порт (диапазон ввода/вывода: 03F8-03FF). Написал часть программы, но всё нуждается в проверке и, возможно, исправлении, или дополнении, т.к. пишу такое впервые. Также нужна часть, реализующая отправку и приём AT команд.
Вот мои наработки:

Код:
CSEG segment
org 100h
Begin:

;подготовка порта:
mov	al,0			;сбрасываем сигналы DTR и RTS
mov	dx,03FCh		;dx = регистру управления модемом
out	dx,al
jmp	$+2			;задержка

;сбрасываем регистр состояния линии
mov	dx,03FDh		;- адрес регистра состояния линии
in	al,dx
jmp	$+2			;задержка

;сбрасываем регистр состояния модема
mov	dx,03FEh		;- адрес регистра состояния модема
in	al,dx
jmp	$+2			;задержка

;сбрасываем регистр данных
mov	dx,03F8h		;- адрес регистра данных
in	al,dx
jmp	$+2			;задержка


;инициализация порта:
mov	 dx,03FBh		;dx = адресу регистра управления (линией)
mov	 al,10000000b	;al = 10000000 - устанавливаем БИТ 7 (DLAB) в "1" для перевода порта в
				;режим получения делителя
out	 dx,al
jmp	$+2			;задержка

mov	 dx,03F9h		;dx = адресу старшего байта делителя скорости
mov	 al,00000000b
out	 dx,al
jmp	$+2			;задержка

mov	 dx,03F8h		;dx = адресу младшего байта делителя скорости
mov	 al,1			;1 = 115200
out	 dx,al
jmp	$+2			;задержка

mov	 dx,03FBh		;dx = адресу регистра управления (линией)
mov	 al,00000011b	;нет проверки чётности, 1 стоп-бит, 8 бит/слово
out	 dx,al
jmp	$+2			;задержка

mov	 dx,03F9h		;dx = адресу регистра разрешения прерываний
mov	 al,00000000b	;запретить прерывания от порта
out	 dx,al
jmp	$+2			;задержка

;инициализация модема:
mov	 dx,03FCh		;dx = регистру управления модемом
mov	 al,00000001b	;оповещение о готовности терминала данных (DTR)
out	 dx,al
jmp	$+2			;задержка

mov	 dx,03FEh		;dx = регистру состояния модема
DSR_test:
in	 al,dx
jmp	$+2			;задержка
test	 al,00100000b	;проверяем готовность модема (DSR)
jz	 DSR_test

mov	 dx,03FCh		;dx = регистру управления модемом
mov	 al,00000011b	;...добавляем готовность нашего терминала данных к передече данных (DTR + RTS)
out	 dx,al
jmp	$+2			;задержка


mov	 dx,03FEh		;к регистру состояния модема
CTS_test:
in	 al,dx
jmp	$+2			;задержка
test	 al,00010000b	;проверяем состояние готовности получить данные (CTS)
jz	 CTS_test	

CSEG ends
end Begin
Т.е. это полная подготовка порта и модема к работе. Что писать дальше для отправки и получения AT команд?
Кстати, а задержка вида "jmp $+2" - действительно сработает как задержка?

Последний раз редактировалось Steve_s; 06.09.2008 в 22:45.
Steve_s вне форума Ответить с цитированием
Старый 06.09.2008, 22:09   #5
Prot
 
Регистрация: 29.07.2008
Сообщений: 4
По умолчанию

Можешь указать источник откуда взят код подготовки порта, где происходит сбрасывание регистров путем чтения из них. Что-то такое припоминаю, но не помню откуда. Впрочем я уже отказался от своей первоначальной идеи.

А дальше видится так, подготовишь строку с АT-командой, и выводишь её в цикле в порт (регистр данных) побайтно, каждый раз проверяя возможность записи байта в порт. Затем пауза. И чтение из порта аналогично, но есть вероятность пропуска части данных, и с прерываниями все же попроще будет.

А jmp $+2, здесь как ты знаешь, делает переход на следующую команду сразу за собой, при этом процессор затрачивает на ее выполнение сколько-то тактов, за которые в порту успевают завершится переходные процессы связанные с выводом/вводом в него. Правда я не знаю насколько они нужны в твоем случае, поскольку с помощью этой инструкции разделяют следующие подряд друг за другом инструкция ввода/вывода (in/out).

Последний раз редактировалось Prot; 06.09.2008 в 22:13.
Prot вне форума Ответить с цитированием
Старый 06.09.2008, 22:36   #6
Steve_s
 
Регистрация: 06.09.2008
Сообщений: 4
По умолчанию

Цитата:
Можешь указать источник откуда взят код подготовки порта, где происходит сбрасывание регистров путем чтения из них.
Это я взял из "Библиотеки системного программиста" том4 "Программирование модемов"

Цитата:
и выводишь её в цикле в порт (регистр данных) побайтно, каждый раз проверяя возможность записи байта в порт. Затем пауза. И чтение из порта аналогично
Я так пытался делать, только после отправки AT команды и завершающего ASCII кода "возврата каретки" от модема я ничего не получал И бит, говорящий что данные есть в регистре приёмо-передатчике стоял всё время в "0", говоря что ничего не принято ...Собственно даже считав "насильно" байт из этого регистра - оказывалось что в нём лежит последний переданный байт

Цитата:
при этом процессор затрачивает на ее выполнение сколько-то тактов
Просто я слышал что современные процессоры "предугадывают" прыжок и таким образом ликвидируют задержку выполнения...

Цитата:
но есть вероятность пропуска части данных
Это ещё почему? 0_0

Последний раз редактировалось Steve_s; 07.09.2008 в 00:40.
Steve_s вне форума Ответить с цитированием
Старый 10.09.2008, 22:37   #7
Prot
 
Регистрация: 29.07.2008
Сообщений: 4
По умолчанию

Попробуй не только "код возврата каретки", но и добавить код "перевода строки" ( т.е. 0Ah, ODh или 0Dh, 0Ah - последовательность сейчас не помню ).

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

Насчет "предугадывают прыжок" ничего умного не скажу.

Вероятность пропуска части данных есть вот потому. Читал что, без FIFO, буфер современного последовательного порта состоит из 3 регистров, собственно того откуда ты читаешь байт, сдвигового регистра и еще какогото одного. И если пришел еще один байт, а все эти регистры уже заняты, то есть после их приема, не было чтения из порта, то выставляется ошибка и новый байт и все последующие не принимаются (теряются). Вроде ничего не напутал
Prot вне форума Ответить с цитированием
Старый 11.09.2008, 17:54   #8
Steve_s
 
Регистрация: 06.09.2008
Сообщений: 4
По умолчанию

Цитата:
если пришел еще один байт, а все эти регистры уже заняты, то есть после их приема, не было чтения из порта, то выставляется ошибка и новый байт и все последующие не принимаются (теряются)
Так буферы FIFO этого порта тоже не резиновые и так же могут быть переполнены ) Единственное отличие что вероятность этого меньше... Ну короче главное - что я твою мысль уловил

Цитата:
Попробуй не только "код возврата каретки", но и добавить код "перевода строки"
Да, я тоже подумывал так попробовать, но вообще во всяких документациях сказано только о коде "возврата каретки".

Цитата:
А считанный байт равен последнему отправленному потому что, при посылке каждого байта модему, модем возвращает его обратно (эхо)
По умолчанию мой (и, кажется многие другие) модем не возвращает это-ответ после каждого переданного символа, если ему не разрешить это, предварительно введя соответствующую AT команду (ATZ что ли...). Так что лежащий в регистре байт, учитывая состояние бита, оповещающего о полученных новых данных, похоже тот самый, который я отправлял...

В общем мне всё ещё нужна помощь А пока буду пытаться реализовать различные варианты...

Последний раз редактировалось Steve_s; 11.09.2008 в 17:58.
Steve_s вне форума Ответить с цитированием
Старый 14.09.2008, 15:01   #9
Steve_s
 
Регистрация: 06.09.2008
Сообщений: 4
По умолчанию

Ух ты... кажется заработало... Только я не понял почему 0_о =)
Такой вопрос: как можно устроить задержку не по количеству тактов процессора (на разных процессорах частоты разные и в таком варианте время задержек будет разное на разных процах, если я правильно понимаю), а по времени?

P.S. ...или я не правильно понимаю? =)
Steve_s вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Старый серер перенести на новый, а старый заглушить, при этом не потерять настроек. Spartak Помощь студентам 1 28.01.2008 12:07
компилятор у меня старый и программа в нем не хочет компилироваться Vofka Общие вопросы C/C++ 3 12.12.2007 00:26
Старый добрый тетрис Format C: Gamedev - cоздание игр: Unity, OpenGL, DirectX 15 05.07.2007 16:02