Приветствую всех! Такая проблема, как программным путем можно организовать задержку 10мкс? Можно конечно использовать системный таймер, но для этого требуется вызвать прерывание BIOS int 15h с ф-цией 86h, что возможно только из доса. А надо чтоб это все работало под виндой (желательно WIN 9X) Заранее спасибо
В 9x системный таймер работает с периодом ~600 мкс, а int 15h, как ты сам заметил, отрабатывает неверно (сразу возвращается). GetTickCount тупо возвращает глобальный счетчик по этим самым 600 мкс. Так что "стандартно", пожалуй, никак. Возможно провести калибровочные измерения выполнения десятка mov eax,eax или типа in al,_ненужный порт_ (in/out работает дольше), выполнять их в драйвере (динамический VxD), обрамленные cli/sti (хотя cli в win32 вроде в 9x тоже работает как-то). Тебе в VxD это нужно или в win32?
Chingachguk Мне это нужно в win98, но без драйверов. ( хотелось бы, но если без драйвера VxD никак, то с ним ) asmfan Все эти ф-ции вроде как не могут делать задержку меньше 1 мс, а нужно 10 мкс.
AB_Celitel Из QueryPerformanceFrequency получаем частоту счетчика. На моей рабочей железяке это 3014530000, т. е. похоже, что это частота проца и используется rdtsc. Из QueryPerformanceCounter получаем текущее значение счетчика. По идее можно получить задержки значительно меньше 10 мкс, но врядли очень точно.
Ustus Т.е. если к примеру запомнить текущее значение счетчика с помощью QueryPerformanceCounter, а затем в цикле снова получать текущее значение и сравнивать с сохраненным до тех пор пока разница между ними не составит 10. Так что ли?
Ты знаешь частоту счетчика (резолюшн; мелкость разбиения; разрешение) за 1 секунду, ты знаешь сам счетчик... Так почему бы тебе не организовать всё это воедино...? Чти МСДН, учи мат.часть©подполковник Шведов...
1. Сними значение rdtsc 2. Вызови Sleep(1) 3. Сними значение rdtsc Разность между значениями "после" и "до" вызова rdtsc считай равной количеству тактов за 1 миллисекунду (лучше повторить несколько раз и аппроксимировать на случай возможных DPC, APC и прочего). Потом делай cli, в ecx клади количество тактов на нужное число микросекунд и выполняй команду в цикле (между регистрами например погоняй что-нибудь). А потом sti есессено не забудь вызвать. Должно по идее получиться (чем больше количество тестовых шагов 1,2,3 повторишь, тем точнее будет)
Ustus QueryPerformanceFrequency выберает самый быстрый мультимедиа таймер. Всего разновидностей 3 штуки. Наиболее распростроненная частота 3579545.
Кто в лес, кто по дрова ) ECk Ес-но никаких Sleep с "бесконечными" повторами не нужно - для это существует QueryPerformanceFrequency Pavia QueryPerformanceFrequency выдает число тактов процессора за 1 сек. Т.е. по сути тоже самое, о чем говорит ECk, только за секунду и вычисляется это значение один раз при старте винды. Разумеется это число зависит от частоты CPU, поэтому не понятно о каких "разновидностях" и "наиболее распространенных" значениях может идти речь А QueryPerformanceCounter это по сути та же rdtsc плюс фиксированное смещение. В отличие от обычного rdtsc, Query.. выполняется в ядре, поэтому с одной стороны на нее не действуют запреты TSD = 1, а с другой стороны уходит больше времени на вызовы\возвраты
Мдя, прошу прощения, к Win 9x вышеприведенные измышления не относятся Видимо в 9х (а может и в ранних NT, теперь уж и не знаю и в самом деле QueryXXX по таймеру работает
leo И какая у меня частота процессора если QueryPerformanceFrequency вернул 3579545, у друга такаяже, а комп совершенно другой. Найду статью покажу откуда вычитал, не нашел. Да в некоторых системах используется RDTSC.
Ну может что бы более понятно было для чего это все требуется : Я пишу прогу для управления своим программатором контроллеров, а для прошивки 87C51 и аналогичных требуется на определенную лапу посылать 25 импульсов длиной 100мкс с интервалом 10мкс. Вот в этом и вся проблема. Может теперь найдутся еще какие-либо решения данной задачи. Заранее спасибо. P.S. ECk Ты имеешь ввиду, что когда мы узнаем кол-во тактов за 1мс, то мы их разделим на 1000 что бы узнать кол-во тактов за 1мкс, а в ecx положим кол-во тактов за 1мкс * на кол-во микросекунд при условии что цикл будет выполнятся примерно за 1 такт. И после этого всего получим нужную задержку. Я так понял?
AB_Celitel Микроинструкция такая. Это же через COM порт посылается, так? Тогда зачем самому задавать задержки, если это может сделать контроллер порта (UART)? Достаточно настроить baudrate под эти задержки и отправить цепочку байт.
Quantum Дело в том, что программатор подключен через LPT порт. А сам программатор состоит из 3-х параллельных 8-разрядных регистра (для младшего байта адреса, старшего байта адреса и байта данных) и управляющего счетчика который эти регистры поочередно переключает на запись. Импульсы на управляющий счетчик, а также на ключ который подает напряжение записи и ключ который подает эти короткие импульсы(100мкс) подаются напрямую с LPT порта, т.о. комп полностью управляет программатором.
AB_Celitel Организовать задержку 10мкс в винде невозможно. Нужно либо менять ось, либо менять интерфейс ПК <-> программатор (добавить самопальный генератор этих самых импульсов по сигналу с компа). Я бы выбрал второе.
Quantum Достаточно настроить baudrate под эти задержки и отправить цепочку байт А требуемую скважность как обеспечить? Chingachguk В 9x системный таймер работает с периодом ~600 мкс, Я дико извиняюсь, но AFAIK, это не так. Я много раз на разных машинах в разных системах разными способами измерял эту величину. Во-первых, она непостоянна и, вроде бы, управляется timeBeginPeriod-ом. Во-вторых, по умолчанию, сразу после старта Маздая она тоже не 600 мкс. Откуда взялась эта цифра? Доказательства предоставить можно? AB_Celitel 1. QueryPerformanceConter / QueryPerformanceFrequency. 2. RDTSC 3. Сканирование счетчика 2-го ("музыкального") канала таймера. 4. Калиброванный цикл (т.е. взять, например, цикл из 1000000 итераций, точно измерить его длительность при помощи (1), (2) или (3), а потом в нужное количество раз уменьшить). По собственному опыту - у (1) и (3) большеватые накладные расходы, по крайней мере несколько мкс. Т.е. использовать можно, но константы придется подбирать, глядя в осциллограф, впрочем, это любых методов касается. И еще, самое главное: совсем побороть многозадачность Маздая не получится, т.е. рано или поздно произойдет переключение на другие потоки и получится большая задержка. Поэтому можно попробовать дать рабочему потоку TIME_CRITICAL_PRIORITY, это не спасет от переключения на другие потоки, но отсрочит на 4-5 секунд, вполне должно хватить на передачу требуемой серии импульсов.
drmad А в чём проблема? По условию нужно выдать 25 таких импульсов: Код (Text): 100us 10us __|''''''''|__|''''''''|__|''''''''| Получается такая последовательность: 011111111110111111111101111111111 и т.д. Настраиваем скорость так чтобы каждый бит имел длительность 10мкс. Размер байта задаём 8 бит, + 1 бит чётности + 1 stop bit. Итого, получаем 10 единиц и 1 нолик (start bit) в каждом периоде.
drmad Да чего там дико извиняться Я тоже мог быть не прав: я измерял это так. Года 4 назад я улучшал быстродействие брутфорса md5+rc4 (excel), на компе P120 МГц, win98. Измерения делал с помощью SoftIce , у него собственное мертвое время было ~60 мкс. Я обнаружил, что функа GetTickCount читает некую глобальную ячейку, которую обновляет некая подпрограмма в ядре, которую вызывает (вроде бы!) обработчик таймера, и вызовы были как раз 1 раз в ~600мкс... Возможно, оно и регулируется виндой в зависимости от скорости CPU (интересно, из каких соображений ?...), и на более мощном компе винда его сделат поменьше... ++ По проблеме. Имхо, такие задержки _ТОЧНО_ нельзя делать даже на самом быстром на сей момент компе в _win_. Да, можно добиться что в некотором небольшом периоде (секунда? три? more?) все будет "гладко", но _никто_ не будет четко передавать управление коду который посылает данные с требуемой частотой... Решение, ИМХО, лежит в написании динамического VxD, который нафик блокирует все, прерывания все остальные, переделывает таймер на нормальную частоту / использует калибровки под частоту CPU и делает требуемые действия, затем все гладко возвращается на обычную винду... Разве что часики некорретные будут...