Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
Ответить

Программирование DMA для LPT - как?

Пт окт 15, 2010 11:02:29

Приветствую всех на форуме.
Возникла у меня такая задача - нужно читать с LPT-порта с "дискретом" 10 микросекунд. А таймеры в операционках (Windows, Linux) работают от часов и у них дискрет 1 миллисекунда. Посему, замечательная библиотека input32.dll и ей подобные мне не подходят (по крайней мере, я не вижу способа их использовать в данных условиях).
Но LPT-осциллографы же как-то читают и с меньшим дискретом.
Прошу помочь информацией, как запрограммировать на высокоуровневых языках работу LPT с DMA. Либо каким образом, помимо этого, можно реализовать требуемое.

Re: Программирование DMA для LPT - как?

Пт окт 15, 2010 11:13:59

можно попытаться сделать так: настроить порт в режим ECP или EPP (я что-то подзабыл, какой из них умеет работать в DMA-режиме) и использовать для обращения к LPT системную функцию для блочного чтения файла. в вашем девайсе надо будет предусмотреть подачу строба "данные готовы" (в соответствии с протоколом ECP/EPP) с периодом 10 мкс, тогда все остальное драйвер Windows сделает сам автоматичеси.

другие способы, имхо, не помогут...

Re: Программирование DMA для LPT - как?

Пт окт 15, 2010 11:29:39

Я правильно понял, что в биосе настроить на ECP (вроде ДМА он поддерживает), на строб "данные готовы" повесить "генератор" с периодом 10 мкс и читать LPT как блочный файл 1 раз в миллисекунду блоками по 100 байт? Ну или раз в 2 миллисекунды блоком в 200 байт и т.п.

Re: Программирование DMA для LPT - как?

Пт окт 15, 2010 11:53:44

я думаю, читать вам надо тем блоком, сколько байт надо, только время ожидания чтения не забудьте задать правильное. например, если надо считать 2048 байт - таким блоком и читайте сразу, винде по барабану.

P.S. еще, возможно, придется поиграться с настойками прерывания от LPT в свойствах драйвера порта (диспетчер устройств) - я, к сожалению, давно не интересовался, как родной лптшный драйвер у винды устроен - нужны ему прерывания или нет... в старых версиях винды (95, 98) ему было начхать на прерывания...

Re: Программирование DMA для LPT - как?

Пт окт 15, 2010 22:24:24

Ещё у кого-нибудь варианты есть? :roll:

Re: Программирование DMA для LPT - как?

Пт окт 15, 2010 22:40:43

Эм, винда какбэ многозадачная система, так что вариантов не много!

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 01:18:21

Мурик писал(а):Эм, винда какбэ многозадачная система, так что вариантов не много!

Ну, какбэ, интересуют варианты заставить LPT с DMA работать. Многозадачность винды при этом не играет роли. Звуковухе ведь это не мешает оцифровывать. Что там сигнал о готовности буфера, что тут должен быть. Только как запрограммировать-то?

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 08:33:05

Inquirer писал(а):Возникла у меня такая задача - нужно читать с LPT-порта с "дискретом" 10 микросекунд. А таймеры в операционках (Windows, Linux) работают от часов и у них дискрет 1 миллисекунда.


Дискрет у компонентов-таймеров для Delphi или Builder C++ вообще-то еще хуже - 22 мс...
Сделайте вот что. В программе заюзайте API-функции QueryPerformanceFrequency, QueryPerformanceCounter. Первая читает частоту суперпупермегасчетчика :0) в ПК (даже в 486 частота была в районе 1 МГц), вторая - текущее значение. Дальше делаете так:

time=0,00001;
QueryPerformanceFrequency(freq);
QueryPerformanceCounter(stcount);
ticks:=round(freq*time)+stcount;
repeat
QueryPerformanceCounter(endcount);
until (endcount>ticks);

Все! Вот нужная Вам задержка. Если этой программе повышать приоритет в Винде до "реального времени", весь ПК зависнет наглухо :0), но прога будет работать.
Режим LPT надо использовать EPP, он проще всего реализуется, при этом из проги можно читать сразу 4 байта подряд (берете и читаете 32-разрядный Integer) для ускорения, можно скидывать все это в файл, но проще - в собственный программный массив огромных размеров (если надо динамический - делайте), а потом - в файл. DMA тут вовсе не при чем. Все вкусно и просто. А еще Вам надо бы прочитать М.Гука "Аппаратные интерфейсы ПК" в части, касающейся LPT, тогда будете совсем "гуру" по этому вопросу.
Пока в качестве "гуру" могу побыть я.

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 09:09:02

использовать счетчик тиков нет смысла, т.к. с его помощью невозможно обеспечить гарантированную периодичность на уровне 10 микросекунд! это я вам заявляю со всей ответственностью: часть интервалов будет близкой к 10 vrc? но периодически будут промежутки до 20, 50 и даже 100 микросекунд - это 100%!!! возможно на каком-нибудь многоядерном пне будет иначе, но на обычном только так. это проверено не один раз.

упомянутый счетчик делается программно - как вы думаете, на его инкремент надо как-то прервать остальные задачи? а то, что при наивысшем приоритете для потока курсор мышки продолжает шевелиться, USB-порты продолжают опрашиваться, системная шина обсуживаться, интернет не отключается и ядро системы продолжает крутиться с тем же приоритетом - вас не смущает? 10 микросекунд - слишком мало для ПРОГРАММНОЙ реализации задержки...

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 12:36:11

Тут наверное надо свой драйвер порта писать.
А строб данных наверное надо не отправлять от ЛПТ порта компа,
а принимать компом от подключаемого девайса. Кажется так быстрее будет в ECP режиме.
ECP режим имеет буфер FIFO для приёма\передачи данных и допускает работу в DMA режиме + аппаратное ускорение.
Вот Теория работы порта в разных режимах От туда уже можно плясать по поводу программирования порта и организации обмена данными.

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 13:14:47

свой драйвер писать смысла нет - это из пушки по воробьям. а что строб посылать должно устройство - я писал в своем первом посте. драйвер винды и так должен блоком считать - а DMA там или что-то иное будет - все равно

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 14:54:09

Ну в принципе тоже верно, просто виндосовский драйвер больше подточен под принтерные протоколы и возможно, что мозгоёпПки будет немало. Тут скорее надо бы изучить функции WinAPI по этим портам (поискать документацию). А там уже включить логику и соответственно написать программу. Тут просто такая хрень, что простым прямым доступом к порту не подступишься к аппаратным возможностям порта, тем более к режиму ECP и тем более в NT системах. Тут API в помощь. Проще будет.

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 21:46:50

«не так, всё не так»™
Не так задан вопрос. Надо озвучивать не трудности на вбранном пути, а цель. Тогдамогут другой путь подсказать. Правильно задать так:
Вводить в ПК байты с периодом 10мкс - как?

Не тот выбран метод. Надо взять FT245 или FT232 с буквами BM или R, включить асинхроный бит-банг, настроив его на нужную частоту (период до 1мкс возможен, но стабильнее будет, если больше 2-3мкс) и только успевать выгребать.
У 245-ых ещё можно в режиме FIFO, как-то так

Да, FT232BM или FT232R несколько дороже, чем ничего, но зато будет работать.

Не верите ARV. поверьте мне — под вытесняющей операционкой при работе с LPT более-менее просто решаются только вещи «не быстрее чем, а медленнее - не страшно».
Да, можно взять режим EPP/ECP, ввести снаружи задержку между стробом и квитированием такую, чтобы вышло 10мкс периода при пакетном вводе, попытаться достучаться сквозь win до DMA или через DLportIO сделать read block (inpout32 имеет только одиночные обращения, а без REP INSB равномерности не будет, да и с ними не факт, что будет всегда).
А с FTDI-кой по крайней мере всё через готовые драйвера будет.
Последний раз редактировалось avreal Сб окт 16, 2010 21:54:23, всего редактировалось 1 раз.

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 21:52:25

avreal писал(а):«не так, всё не так»™
Не так задан вопрос. Надо озвучивать не трудности на вбранном пути, а цель. Тогдамогут другой путь подсказать. Правильно задать так:
Вводить в ПК байты с периодом 10мкс - как?
следующим шагом на этом пути будет "вводить байты в ПК - зачем?" :))) и вывод: нафиг это не нужно, ибо можно купить что-то готовое, что и введет само, и на дисплее покажет. решать задачу в исходной постановке - интересно, в "переделанной" - бессмысленно. :)))

Re: Программирование DMA для LPT - как?

Сб окт 16, 2010 22:02:09

Если цель — что-то отлаживать или мерять таким «анализатором», то LPT-шный и FTDI-ный пути по сравнению с «купить всё готовое» приблизительно одинаковы по «нитересности», «себестоимости», но FTDI-ный даст результат лучше и быстрее. Причм «железка» может и для другого пригодиться и «кап. вложения» в освоение как-то более «окупаемы», чем в LPT.

Ну а если «ввести со стабильным темпом 10мкс/байт через LPT» — самоцель, то тогда да, флаг в руки, ветер в спину, решать интересную задачу.

Re: Программирование DMA для LPT - как?

Вс окт 17, 2010 20:51:39

avreal писал(а):«не так, всё не так»™
Не так задан вопрос. Надо озвучивать не трудности на вбранном пути, а цель. Тогдамогут другой путь подсказать. Правильно задать так:
Вводить в ПК байты с периодом 10мкс - как?

Не тот выбран метод. Надо взять FT245 или FT232 с буквами BM или R, включить асинхроный бит-банг, настроив его на нужную частоту (период до 1мкс возможен, но стабильнее будет, если больше 2-3мкс) и только успевать выгребать.
У 245-ых ещё можно в режиме FIFO, как-то так

Да, FT232BM или FT232R несколько дороже, чем ничего, но зато будет работать.
Кхм. Оно не просто несколько дороже, чем ничего. Оно в 2 раза дороже, чем вся задача, от которой ввод в ПК с частотой 10 мкс есть всего лишь восьмая часть. Повесить на тот же LPT внешний микроконтроллер было моей первой мыслью, но было отброшено, так как излишне сложно в рамках задачи. К тому же, это ВОЗМОЖНО реализовать с помощью LPT. Это реализовывается уже с помощью LPT и мне только нужно узнать, как сделать это высокоуровневым методом.

Re: Программирование DMA для LPT - как?

Пн окт 18, 2010 22:28:38

Под LINUX на asme для обычных PC с наивысшим приоритетом по LPT 2-4 мкс плавает - это когда систему поставить на колени - ьи то время плавает . Вообще нормальные приложения быстрее чем 50 KHZ с LPT не работают.

В промышленных материнках другая архитектура - порты ввода вывода - прямое отображение в физическую

память - на асме можно обращаться как к порту так и ячейке памяти - тут уже и с мегагерцами можно работать

Но с синхронизацией времени приходится туговато.

Re: Программирование DMA для LPT - как?

Вт окт 19, 2010 14:11:06

Если не требуется красивый интерфейс, межплатформенная переносимость и многопоточность, то успешно работать с портами можно и из DOS программ, написанных на чём угодно.
У меня, к примеру, очень много АЦП, измерительных приборов и оборудования, которые прекрасно согласуются с LPT и не требуют сложных алгоритмов управления. В этих случаях мне показалось эффективным писать программы на Turbo или на TMT Паскале под DOS. Более того, эти программы прекрасно работают и в Windows 2000/XP в её виртуальной машине NTVDM. Для прямого доступа к портам, которые не эмулируются NTVDM, использую AllowIo.exe с драйвером porttalk.sys.
Вот пример работы моей небольшой паскалевской программы-скоростемера операций ввода-вывода. Запускается она через пакетный файл в котором прописана, как аргумент для AllowIo.exe с указанием адреса тестируемого порта. Для отсчёта временных интервалов используется даже не TSC, а второй канал таймера i8254, который обычно отвечает за спикер. NTVDM прозрачно обрабатывает программирование этого канала, пуск, а также защёлкивание счётчика и регистра статуса. Дискретность отсчёта 0,8 мкс, диапазон 0,11 сек.

Изображение

Из скриншота можно сделать вывод, что среднее время однобайтного чтения - порядка 1 мкс, а дисперсия блочного обмена невелика. Но даже в однозадачной DOS гарантировать синхронность чтения порта можно лишь с определённой погрешностью, связанной с обработчиками прерываний таймера, клавиатуры, SMI и др.

Re: Программирование DMA для LPT - как?

Ср окт 20, 2010 02:12:09

Mickle писал(а):Если не требуется красивый интерфейс, межплатформенная переносимость... и многопоточность...
Именно, что требуется. Только не межплатформенная, а межОСевая.
Ну, у меня, конечно, хватит железа, чтобы на одной машине запустить ДОС с замером, обсчётом и логгированием 8 каналов, а на другой отображение и логгирование остальных датчиков, но как-то это не оптимально выглядит.

Re: Программирование DMA для LPT - как?

Ср окт 20, 2010 07:34:42

Mickle писал(а):Из скриншота можно сделать вывод, что среднее время однобайтного чтения - порядка 1 мкс, а дисперсия блочного обмена невелика. Но даже в однозадачной DOS гарантировать синхронность чтения порта можно лишь с определённой погрешностью, связанной с обработчиками прерываний таймера, клавиатуры, SMI и др.
вы сделайте лог работы вашей утилитки в течение пары секунд хотя бы, т.е. чтобы прошло время, в течение которого винда обязательно прервет работу виртуальной машины для своих нужд... вот тогда и посмотрим, насколько точно из-под виртуальной DOS временные интервалы отрабатываются...
Ответить