![]() |
|
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]()
|
|
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Здравствуйте! Расскажу о своей проблеме. Несколько лет назад моими коллегами была разработана самодельная интерфейсная плата. Задача - считывание технологических данных с установок. Все - самодельное - и сами установки, и блоки-контроллеры и др. В то время под эту задачу могли выделить лишь IBM PC 386. Я разрабатывала программу для связи компьютера с установками - на Turbo-Pascal-7 под DOS. Часть, которая непосредственно обращается к портам ввода-вывода (не Com и не LPT!), написана на встроенном ассемблере. Теперь появилась возможность купить Пентиум и заменить старый компьютер. Пока все работает под DOS, но мне поставили задачу - перевести программу под Windows-98. Я перевожу старую программу на Delphi. Есть три порта: по первому я вывожу байт с номером установки в линию связи; считываю второй порт - в него приходят такты - я проверяю младший бит, если есть единица, то перехожу к считыванию данных из линии связи - считывание по третьему порту. Если единица не пришла, то опрос производится определенный отрезок времени (задается программно), после этого периода времени опрос Программа простейшая. Пытаясь перевести эту часть на Delphi, я оформила ее как DLL. В библиотеке всего одна процедура, и основная программа обращается к ней. И вот здесь я столкнулась с проблемой - похоже, что команды ассемблера in и out не могут под Windows обратиться к портам, или обращаются как-то неправильно. Номер установки в линию связи не выводится, данные и такты не считываются, хотя сама процедура работает, что-то где-то опрашивает, выжидает нужный период времени, затем выходит и ничего не считывает. Хотя точно известно, что данные в линии есть. Подскажите, пожалуйста, что это можем быть и как мне напрямую обратиться к портам? Никаких стандартных устройств ввода-вывода никто покупать не будет, использовать нужно только эту самодельную плату. Я уже не знаю, что делать. Помогите, пожалуйста!
=Извините, если мое письмо слишком длинное. Izvinite, esli problemy s kodirovkoj. = Bagira -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| December |
|
|||
![]() Antitheorist ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4423 Регистрация: 14.8.2002 Где: Харьков Репутация: нет Всего: 57 |
bagira, как раз 98-я позволяет напрямую обращаться к портам. Возможно, у тебя проблемы со стабильностью сигналов. IRQ и прочие досовские радости работают крайне нестабильно под win. Убедись, что ты привязалась к виндозному таймеру.
|
|||
|
||||
| remax |
|
|||
|
Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: нет Всего: 5 |
1.
Если да - то проблема с новой программой Если нет - то необходимо проверить работоспособность старой проги в этом режиме 2. Возможные проблемы с новой программой 2.1 Правильно ли организована DLL (как откомпилирована DLL (в стиле PASCAL или С передача параметров, например))? Почему бы не сделать все в рамках DELPHI (использовать встроенный ассемблер, например). 2.2 Как организованы временные задержки (надо привязываться к тактам системы а не делать безусловвное ожидание) 2.3 Адреса I/O портов самодельной платы ни с чем не конфликтуют? 2.4 Как быстро изменяются в новой программе данные в портах - хватает ли времени на переключение для устаревшей электроники? -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
December! Спасибо, что откликнулся. Я в своей подпрограмме не обращаюсь к виндозному таймеру, а для проверки времени использую прерывание INT 1AH, обращение к таймеру 18 раз в секунду. И вроде бы это работает под Windows. Можно проверять как-то иначе? Я еще плохо знаю Delphi, только изучаю по ходу дела.
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Dmitry V.Abramov |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 30.9.2003 Где: Saint-Petersburg Репутация: нет Всего: 4 |
bagira Был даден хороший совет от remax - запустить старую DOS-программу в дос-окне windows. Если она при этом НЕ будет нормально функционировать, то "лобовой" перенос ее под Delphi ничего не даст. Работать также не будет.
Если же старая программа в дос-окне работает нормально, а после переписи в Delphi НЕТ, то дело в переписи. 1. Автор ДОС и Виндовс версий один и тот же? Если нет, то новичок может не осознавать многих "тонкостей" это программы и ошибки придется искать в самых неожиданных местах. 2. Каким способом (пример текста) под Delphi используется INT 1Ah ? 3. Уж не о Delphi 1.0 идет речь? --------------------
/DVA |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Remax, спасибо за ответ!
1. Когда я проверяла программу в режиме DOS, то DOS загружала по-всякому: и из-под Windows, и перезагружала компьютер в настоящем режиме DOS и она работала. 2. Скорее всего, все дело в новой программе, хотя я попыталась воссоздать в ней все то, что было в старой. 2.1. DLL я создавала, используя встроенный в Delphi ассемблер. Причем и делала ее и полностью на ассемблере, и на паскале со вставками asm... end. В основной программе эта процедура объявлена External и указано имя библиотеки. 2.2. Временные задержки организованы у меня с помощью прерывания INT 1AH, при этом обращение к системному таймеру происходит 18 раз в секунду. Задавая различные временные задержки: 1 с, 5 с, 10 с и т.д., я убедилась, что именно на это время и замедляется работа программы (приблизительно, конечно). 2.3. Когда я запускаю старую программу в DOS из-под Windows, то она работает, значит адреса не конфликтуют, я так думаю. А как еще проверить? 2.4. Времени должно хватать, т.к. данные считываются не в режиме реального времени по ходу технологического процесса. Каждая установка накапливает данные в течение нескольких часов - они пишутся в энергонезависимое ОЗУ. Несколько раз в день осуществляется считывание- момент определяет пользователь. Выводится в первый порт номер (адрес) установки, (установок - 36 шт.). Контроллеры всех установок, получив по линии связи этот номер, сверяют его с индивидуальным номером установки (задан перемычками на плате - у каждой установки - свой). Если номер совпал, и если в ОЗУ есть данные, контроллер посылает тактовый сигнал, принимаемый во втором порту. Этот порт может опрашиваться в течение любого промежутка времени (какой задам) - времени должно хватить с большим запасом. Если единица в младшем бите не придет, считается, что данных нет, если придет, то считывается байт данных в третьем порту. При считывании данных из ОЗУ контроллера, оно автоматически очищается (записываются все нули). -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Dmitry V.Abramov! Я проверяла старую программу в DOS-окне Windows. Она работает. Точно также работает, когда компьютер перезагружаю полностью в режиме DOS. Разницы нет.
1. Автор один и тот же - это я. 2. Пример использования прерывания INT 1AH: ... INT 1AH {или $1A - при этом в DX попадает текущее время } ADC DX,90 {например, 5 секунд - задержка добавляется к текущему времени} MOV WORD PTR VRK,DX {сохранили время конечное} ... ... INT 1AH {снова вызов таймера} СМР DX,VRK {сравниваем время текущее и конечное} JNE ... {не равно - вернуться к опросу тактов} ... {если равно - время ожидания закончилось, данных нет} 3. Пытаюсь переделать программу в Delphi 5. -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: нет Всего: 12 |
да, кстати... процессоры Pentium загадочно быстрая штука
-------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Baa, как рассчитать эту самую задержку?
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: нет Всего: 12 |
Я делал так:
mov cx, 0FFFFh @@begin: loop @@begin У меня прога с ком-портом работала, вот кусок, как задержка юзалась:
-------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
|||
|
||||
| Dmitry V.Abramov |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 30.9.2003 Где: Saint-Petersburg Репутация: нет Всего: 4 |
bagira
1. Это гораздо лучше, чем обратное. 2&3. Вот это и настораживало. В win32 работа с прерываниями должна осуществляться как-то особенно. Как именно - уже не припомню... Не проще ли для "подождать" использовать, например, sleep(5000) для 5 секунд? Либо взять недавно обсуждаемый вариант процедуры Wait()... --------------------
/DVA |
|||
|
||||
| <Spawn> |
|
||||
![]() Око кары:) ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2776 Регистрация: 29.1.2003 Где: Екатеринбург Репутация: 1 Всего: 64 |
А в ДЛЛ стоит способ передачи параметров stdcall? Если нет, то укажите вашей функции это. На пример:
Это сообщение отредактировал(а) <Spawn> - 26.10.2003, 10:48 -------------------- "Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков. |
||||
|
|||||
| December |
|
|||
![]() Antitheorist ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4423 Регистрация: 14.8.2002 Где: Харьков Репутация: нет Всего: 57 |
bagira Я думаю, Вам стоит определиться, с чем проблемы - с железом или вызовом DLLей. А то мы запутываем и себя, и Вас.
|
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Здравствуйте! Спасибо всем, кто принимает участие в обсуждении моей проблемы! Но разговор постепенно перешел к обсуждению временных задержек и таймеров. Конечно, может причина и в таймере... Но мне бы еще хотелось узнать Ваше мнение по поводу обращения к портам. Что-то здесь есть непонятное - всего две простых команды IN и OUT - других не придумать, но вот именно они, похоже, и не работают. Номера трех портов, с которыми работает самодельная интерфейсная плата, заданы аппаратно, ни с чем не конфликтуют. DLL оформлена, по-моему, правильно, Stdcall присутствует, никаких ошибок при выполнении программы не выдается, данные в линии связи есть. Но моя новая программа их просто "не видит", не берет, к нужным номерам портов не обращается, а, отработав, выдает нули. После этого перехожу в DOS (из-под Windows), запускаю свою древнюю программу, и она все данные безошибочно считывает. Ну пожалуйста, подскажите, где еще поискать ошибку? Заранее благодарна.
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: нет Всего: 12 |
Повторюсь, советую сделать задержку после команд IN и OUT... Если не поможет, то плохо, и надо думать
-------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Baa, спасибо за совет! Когда я сделала задержки после IN и OUT, программа начала обращаться к портам. До этого, данные, отправленные с контроллера, "зависали" и могли быть считаны при последующем запуске старой программы под DOS. Теперь старая программа их не находит, значит обращение к портам происходит правильно. Но дальше они (данные) куда-то исчезают, и не появляются в основной программе после вызова процедуры из DLL. Может быть, я неправильно передаю полученный из порта в AL байт в переменную? Например, MOV byte ptr D1,AL.
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| remax |
|
|||
|
Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: нет Всего: 5 |
Может это и банально, но в пошаговом режиме через отладчик Вы проверяли работу дельфийской программы? Это должно однозначно снять вопрос с правильностью вывода в порт -
1.Остановились перед командой OUT, проверили выходы порта 2.Выполнили команду OUT, проверили выходы порта Влияние времени исключается. -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Я пыталась воспользоваться отладчиком Дельфи еще в самом начале этих проблем, но не нашла, где там смотреть номера портов? Подскажите, пожалуйста. Вопрос с выводом в порт решился, как ни странно, еще банальнее - с помощью набора из 8-ми светодиодов, который сегодня по моей просьбе сделали наши электронщики. Плату со светодиодами подцепили к выходному порту, и теперь все, что я вывожу, наглядно видно в 8-ми разрядах: 1 - светодиод горит, 0 - не горит. Так что с выводом стало более-менее ясно. Но не работает команда ввода данных во входные порты (IN), или данные теряются где-то дальше - при передаче между DLL и основной программой, т.е. в основную программу приходят одни нули. Как проверить, куда исчезают данные?
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| remax |
|
||||
|
Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: нет Всего: 5 |
При отладке ассемблерной части проги Вы идете по командам, а номер порта сидит в регистре DX (см окно регистров).
Используй отладчик! А если не получается - поставь в тектсте программы вывод промежуточных сообщений. Например, на дисплей или в файл. Т.е. в контрольных точках поставить вызов вспомогательной процедуры выводящей информацию о состоянии регистра. Но лучше всего - разберись с отладчиком - там можно использовать точки останова, просмотр содержимого переменных и регистров.... P.S. А еще проще - убедись, что правильно передаешь значение мз DLL - взяв за основу свой принцип построй упрощенную DLL передающую наперед известное значение. Получилось - проблема не связана с передачей. Не получилось - исправляй. -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
||||
|
|||||
| Baa |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: нет Всего: 12 |
Че за бред? С какой стати он там сидит?
Ну и где он здесь сидит в DX? -------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
||||
|
|||||
| December |
|
|||
![]() Antitheorist ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 4423 Регистрация: 14.8.2002 Где: Харьков Репутация: нет Всего: 57 |
Baa Для другой формы команды IN порт должен сидеть в DX.
|
|||
|
||||
| man2002ua |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 943 Регистрация: 12.11.2002 Где: Киев Репутация: нет Всего: 2 |
может я недопонимаю, но если необходимо выжидать больше секунды, то функция Sleep должна подходить для этих целей... почему не попробовать?
-------------------- "Нет ничего более постоянного, чем временное" |
|||
|
||||
| Dmitry V.Abramov |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 30.9.2003 Где: Saint-Petersburg Репутация: нет Всего: 4 |
man2002ua Там ведь еще и DLL зачем-то прикручена. Причем, возможно, сидящая в отдельном потоке и непонятно чем занимающаяся. При такой схеме sleep может приостанавливать вовсе не то, что требуется.
--------------------
/DVA |
|||
|
||||
| man2002ua |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 943 Регистрация: 12.11.2002 Где: Киев Репутация: нет Всего: 2 |
ну я не думаю, что используется оконная dll... речь наверняка идет об экспорте обычных функций (Bagira говорила - stdcall). В любом случае, увидеть весь код не помешает.
-------------------- "Нет ничего более постоянного, чем временное" |
|||
|
||||
| Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: нет Всего: 12 |
можно поподробней? Енто про тот случай, когда порт должен быть больше 255? -------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
|||
|
||||
| Dmitry V.Abramov |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 30.9.2003 Где: Saint-Petersburg Репутация: нет Всего: 4 |
Baa Зачем же так...
В любом случае. Особенно, когда не хочется жестко привязываться к номеру порта. Ведь никто, надеюсь, не отрицает наличие инструкции mov al, [bx] ?
Для out/outs - аналогично. --------------------
/DVA |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Привет всем!
1. В DLL - в процедуре обращения к портам - почему-то выдается сообщение об ошибке при: mov dpn,al, где dpn - переменная объявлена как byte, а в аккумулятор считан байт из порта: in al,dx (потом - временная задержка) Когда изменила конструкцию: mov byte ptr dpn,al то ошибка выдаваться перестала, но в основную программу нужное число все равно не передается. Убрала вообще строку с командой in, напрямую задаю: mov byte ptr dpn,7 Но результат тот же - вместо семерки в основную программу попадает ноль. 2. Проверить в пошаговом режиме с отладчиком опрос портов сегодня не удалось - у меня временно отобрали кабель для подключения прибора к ЭВМ. Дождусь понедельника. 3. man2002ua, не знаю, стоит ли приводить весь код - он довольно громоздкий, но позднее я приведу фрагмент непосредственного чтения портов. А сейчас - до свидания - заканчивается карточка Internet. -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| man2002ua |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 943 Регистрация: 12.11.2002 Где: Киев Репутация: нет Всего: 2 |
да, код чтения/записи порта не помешал бы. И еще размеры задержек, к-е должны быть установлены для нормальной работы
-------------------- "Нет ничего более постоянного, чем временное" |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 14 Всего: 112 |
bagira, а ты как связываешь переменные в DLL и переменные в основной программе ? Из приведенного кода я предполагаю, что ты просто объявила в DLL и в основной программе переменную dpn и думаешь, что при её изменении в DLL, она автоматом будет меняться и в основной программе ? Это не так. Самый простой способ - это создать разделяемую память (CreateFileMapping, MapViewOfFile) и туда поместить все переменные, которые должны быть доступны как для DLL, так и для основной программы. -------------------- С уважением, г-н Посол. |
|||
|
||||
| man2002ua |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 943 Регистрация: 12.11.2002 Где: Киев Репутация: нет Всего: 2 |
проще объйявить импортируемую преременную... извините, если плолхо пишу... снова ДР. -------------------- "Нет ничего более постоянного, чем временное" |
|||
|
||||
| Crait |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 244 Регистрация: 20.2.2003 Репутация: нет Всего: 1 |
Bagira, попроси своих электронщиков сделать приспособу
для тестирования ввода из порта - с кнопочками, они поймут. И зачем все-таки работа с портами вынесена в .dll ? По поводу величины задержек между командами ввода-вывода, о которых говорил Baa. В свое время, чтобы все заработало корректно на "самодельной плате", потребовалось проставить 4-микросекундные задержки. Да, вот еще что. Если устройство достаточно медленное и позволяет работать в таком режиме, а в твоем случае это, кажется, так, так вот, советую считывать данные из порта ввода более одного раза - до совпадения считанных два последовательных раза значений. Это нужно для подавления помех на линии. А то некоторые компы, бывает, наводят... Это сообщение отредактировал(а) Crait - 1.11.2003, 20:41 |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Привет всем!
man2002ua: что такое импортируемая переменная и как ее объявить? Posol: где можно узнать подробнее про разделяемую память? Crait: О том, что ассемблерные процедуры следует выносить в отдельную DLL, я прочитала в статье: http://www.delphikingdom.com/mastering/ports1.htm -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Crait |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 244 Регистрация: 20.2.2003 Репутация: нет Всего: 1 |
По крайней мере на Win9x не надо, все прекрасно работает и так.
Под NT же одного только переноса в .dll команд обращения к портам увы, окажется недостаточно ;) |
|||
|
||||
| man2002ua |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 943 Регистрация: 12.11.2002 Где: Киев Репутация: нет Всего: 2 |
bagira, все же приведи кусок кода в к-м идет непоср. обращение к портам.
-------------------- "Нет ничего более постоянного, чем временное" |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Привет всем!
Сегодня у меня две новости: хорошая и плохая. Начну, пожалуй, с хорошей. Итак, загадка, связанная с обращениями к портам и с последующей передачей данных в основную программу, успешно разрешилась! Ура, товарищи! Когда Posol и man2002ua обратили мое внимание на связь переменных в DLL и в основной программе, я чуть-чуть переработала процедуру - и вот пожалуйста! Все передается! Вариант первоначальный - в основную программу нужное значение не передавалось. {library} ... procedure DataRead(var dpn:byte); stdcall; begin asm mov dx,$1fb in al,dx ... mov byte ptr dpn,al ... end; end; Вариант исправленный, введена дополнительная переменная dp, глобальная для данной процедуры. {library} ... var dp:byte; ... procedure DataRead(var dpn:byte); stdcall; begin asm mov dx,$1fb in al,dx ... mov byte ptr dp,al ... end; dpn:=dp; end; Когда процедура приняла такой вид, при обращении к процедуре в основной программе: DataRead(dn); {dn была объявлена как byte} - в переменную dn попадает значение, считанное из порта. Плохая новость связана с аппаратной частью всей этой затеи. После разговора с электронщиками мне стало ясно, как я заблуждалась: думала, что всегда сначала вырабатывается тактовый байт, моя программа считывает его в порту $1FA, проводит анализ - если присутствует единица в младшем разряде, то можно начинать считывание байта данных в порту $1FB (т.е. я считала, что байт данных при этом где-то ждет и лишь после моей команды in al,dx проходит в порт). А оказалось все гораздо хуже, о чем раньше мне не говорили. Электронщики разработали контроллер и интерфейсную плату таким образом, что как только выставлен номер установки в линию связи, та установка, чей номер совпал с выставленным, сразу отправляет всю партию данных в линию связи одновременно с тактами, одно от другого не зависит. Если моя программа не успеет в силу каких-либо причин считать очередной тактовый байт, то при этом соответствующий ему байт данных просто пропадет в никуда. Особенно, если эта штуковина работает под Windows. Вот это сейчас и происходит - часть данных приходит, часть теряется, и никаким подбором временных задержек не удается точно подстроиться под частоту следования этой последовательности байтов. Тем более, что частоту эту я не знаю - электронщики не могут мне ответить, через какие точно промежутки времени следуют байты. Как это ни печально, но похоже, что ничего сделать не удастся. Как эти данные зацепить-то? Когда работала под DOS, не было таких проблем ... До свидания! -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
Оставить работать под ДОС или использовать какую-либо ось реального времени QNX например...
-------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
Слушай, а если прогу запустить с наивысшим приорететом? Неужели не помогает? И не из-под Дельфи IDE?
-------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| remax |
|
||||||||
|
Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: нет Всего: 5 |
1) Насчет частоты
Самостоятельно считаешь тактовые импульсы и фиксируешь суммарное время от первого импульса до последнего. Затем, делишь число тактов-1 на время (с) =Частота (Гц). Но это тебе совершенно ненужно 2) Насчет задержек.
Использовать задержки в этом процессе - гиблое дело. Даже если процесс приема данных осуществляется по прерываниям (COM port, например), а в процедуре приема данных втулячены задержки (sleep, например) практически наверняка будут потери. (Проверено много раз) 3) Насчет "очереди" байтов
4) Насчет повышения надежности
Есть как минимум два варианта, оба связаны с повышением приоритета считывающей процедуры: ВАРИАНТ 1. Стандартный. Повысить приоритет всего приложения. ВАРИАНТ 2. Экзотический. Процедуру обмена с железом сделать под DOS и запустить в сеансе MS DOS. Предусмотреть в ней соответствующий буфер. А Win программа будет общаться через Dos программу. Смысл всей этой сложности в том, что Dos программы при запуске из под Win9x имеют приоритет на уровне драйверов ядра. Получить такой приоритет для пользовательской Winпрограммы практически невозможно. -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
||||||||
|
|||||||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
А если написать свой VxD или сервис? -------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| remax |
|
||||
|
Доцент ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 686 Регистрация: 7.4.2002 Где: Украина, Харьков Репутация: нет Всего: 5 |
Теоретически, это так. Но практически Bagire как новичку в программировании под Win это значительно более сложный путь. Хотя в промышленных компьютерах (которые управляют различной автоматикой) идут по этому пути + обрезают сам Windows по самое нехочу - чтобы лишние (ненужные) процессы не путались под ногами. Но на самом деле, меня не оставляют смутные сомнения, что проблема даже не в приоритете. Не знаю на сколько именно замедляет работу связка Prog->DLL->Prog, особенно если много раз подряд, но в одном модуле это точно будет быстрее. Кроме того, возможно необходимо вообще оптимизировать процедуру приема. Но есть и другие соображения. Прикидки следующие: Если контролер старый, то он во первых на шине ISA во вторых, скорее всего, на советских микросхемах 155, 555 или 1533 серии. А это значит, что максимальная такстовая частота работы устройства в прыжке 10МГц. С учетом разных факторов и личного опыта думаю, что Реальная пропускная способность не больше 1 Мб. А скорее всего еще меньше. Компьютер на котором установлен Win9x должен иметь частоту не менее 100 МГц (иначе, это не работа, а порнография). Имеем не менее 100 кратного превышения! Устройство должно успевать опрашиваться на все 100%. Выводы: 1) Либо программа не оптимальная (делает много лишних телодвижений) 2) Либо в Win установлено много чего лишнего (Ребятки, управляющий компьютер не должен одновременно быть и офисным и серверным и ...). 3) Ресурсы компьютера недостаточны для Win - плохое быстродействие или мало ОЗУ (регулярный своп на диск). Это сообщение отредактировал(а) remax - 5.11.2003, 23:26 -------------------- Как бы ты не старался быть хорошим и правильным человеком с принципами и уважительным отношением к другим, всегда найдется кто-то, кто бросит в тебя какашку |
||||
|
|||||
| man2002ua |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 943 Регистрация: 12.11.2002 Где: Киев Репутация: нет Всего: 2 |
bagira а можешь показать код чтения портов под дос? Может и выплывет что-то еще
если много, то сюда> [email protected] -------------------- "Нет ничего более постоянного, чем временное" |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Здравствуйте! Это снова я...
1. Vit, оставить программу под DOS никак нельзя - хитрый пользователь (а работает вся эта ерунда на заводе в другом городе), позвонил и сказал, что под DOS работать неудобно, и возжелал программу под Windows. Начальник ответил, что это - запросто - он же не понимает... После этого мне уже нельзя было отступать... И еще, я к сожалению, не понимаю, как сделать наивысший приоритет. Что это, вообще, такое? И как пишут VxD? В знании Delphi у меня огромные пробелы - только в октябре начала изучать... 2. Remax, можно узнать подробнее про вариант №2 - экзотический? Это, наверное, очень удачный вариант, но можно ли сделать так, чтобы пользователь не заметил момент обращения к MS DOS? 3. Man2002ua, код отправлю позднее. -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
Приоретет - это сколько процессорного времени выделяется конкретному потоку. Посмотри например функцию CreateProcess... -------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Vit, почему-то в Help я не нашла CreateProcess...
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
Известные грабли. Кликни по иконке help правой кнопкой мыши, далее в меню выбрали Customize, засладка Commands, раздел Help, находишь иконку "Windows API" и вытаскиваешь её на панель инструментов. Вот там и описаны почти все функции WinAPI
-------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
На всякий случай привожу тебе эту страницу help, но лучше оригинальным help пользоваться, так как много перекрёстных ссылок:
The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file. BOOL CreateProcess( LPCTSTR lpApplicationName, // pointer to name of executable module LPTSTR lpCommandLine, // pointer to command line string LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes BOOL bInheritHandles, // handle inheritance flag DWORD dwCreationFlags, // creation flags LPVOID lpEnvironment, // pointer to new environment block LPCTSTR lpCurrentDirectory, // pointer to current directory name LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION ); Parameters lpApplicationName Pointer to a null-terminated string that specifies the module to execute. The string can specify the full path and filename of the module to execute. The string can specify a partial name. In that case, the function uses the current drive and current directory to complete the specification. The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space-delimited token in the lpCommandLine string. The specified module can be a Win32-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer. Windows NT: If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine should specify the executable module. A 16-bit application is one that executes as a VDM or WOW process. lpCommandLine Pointer to a null-terminated string that specifies the command line to execute. The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line. If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute, and * lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. C runtime processes can use the argc and argv arguments. If lpApplicationName is NULL, the first white space-delimited token of the command line specifies the module name. If the filename does not contain an extension, .EXE is assumed. If the filename ends in a period (.) with no extension, or the filename contains a path, .EXE is not appended. If the filename does not contain a directory path, Windows searches for the executable file in the following sequence: 1. The directory from which the application loaded. 2. The current directory for the parent process. 3. Windows 95: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory. Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32. 4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM. 5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. 6. The directories that are listed in the PATH environment variable. If the process to be created is an MS-DOS - based or Windows-based application, lpCommandLine should be a full command line in which the first element is the application name. Because this also works well for Win32-based applications, it is the most robust way to set lpCommandLine. lpProcessAttributes Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpProcessAttributes is NULL, the handle cannot be inherited. Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new process. If lpProcessAttributes is NULL, the process gets a default security descriptor. Windows 95: The lpSecurityDescriptor member of the structure is ignored. lpThreadAttributes Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited. Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the main thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor. Windows 95: The lpSecurityDescriptor member of the structure is ignored. bInheritHandles Indicates whether the new process inherits handles from the calling process. If TRUE, each inheritable open handle in the calling process is inherited by the new process. Inherited handles have the same value and access privileges as the original handles. dwCreationFlags Specifies additional flags that control the priority class and the creation of the process. The following creation flags can be specified in any combination, except as noted: Value Meaning CREATE_DEFAULT_ERROR_MODE The new process does not inherit the error mode of the calling process. Instead, CreateProcess gives the new process the current default error mode. An application sets the current default error mode by calling SetErrorMode.This flag is particularly useful for multi-threaded shell applications that run with hard errors disabled. The default behavior for CreateProcess is for the new process to inherit the error mode of the caller. Setting this flag changes that default behavior. CREATE_NEW_CONSOLE The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS flag. CREATE_NEW_PROCESS_GROUP The new process is the root process of a new process group. The process group includes all processes that are descendants of this root process. The process identifier of the new process group is the same as the process identifier, which is returned in the lpProcessInformation parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or CTRL+BREAK signal to a group of console processes. CREATE_SEPARATE_WOW_VDM Windows NT only: This flag is valid only when starting a 16-bit Windows-based application. If set, the new process is run in a private Virtual DOS Machine (VDM). By default, all 16-bit Windows-based applications are run as threads in a single, shared VDM. The advantage of running separately is that a crash only kills the single VDM; any other programs running in distinct VDMs continue to function normally. Also, 16-bit Windows-based applications that are run in separate VDMs have separate input queues. That means that if one application hangs momentarily, applications in separate VDMs continue to receive input. CREATE_SHARED_WOW_VDM Windows NT only: The flag is valid only when starting a 16-bit Windows-based application. If the DefaultSeparateVDM switch in the Windows section of WIN.INI is TRUE, this flag causes the CreateProcess function to override the switch and run the new process in the shared Virtual DOS Machine. CREATE_SUSPENDED The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called. CREATE_UNICODE_ENVIRONMENT If set, the environment block pointed to by lpEnvironment uses Unicode characters. If clear, the environment block uses ANSI characters. DEBUG_PROCESS If this flag is set, the calling process is treated as a debugger, and the new process is a process being debugged. The system notifies the debugger of all debug events that occur in the process being debugged.If you create a process with this flag set, only the calling thread (the thread that called CreateProcess) can call the WaitForDebugEvent function. DEBUG_ONLY_THIS_PROCESS If not set and the calling process is being debugged, the new process becomes another process being debugged by the calling process's debugger. If the calling process is not a process being debugged, no debugging-related actions occur. DETACHED_PROCESS For console processes, the new process does not have access to the console of the parent process. The new process can call the AllocConsole function at a later time to create a new console. This flag cannot be used with the CREATE_NEW_CONSOLE flag. The dwCreationFlags parameter also controls the new process's priority class, which is used in determining the scheduling priorities of the process's threads. If none of the following priority class flags is specified, the priority class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS. In this case the default priority class of the child process is IDLE_PRIORITY_CLASS. One of the following flags can be specified: Priority Meaning HIGH_PRIORITY_CLASS Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal-priority or idle-priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles. IDLE_PRIORITY_CLASS Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes. NORMAL_PRIORITY_CLASS Indicates a normal process with no special scheduling needs. REALTIME_PRIORITY_CLASS Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive. lpEnvironment Points to an environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process. An environment block consists of a null-terminated block of null-terminated strings. Each string is in the form: name=value Because the equal sign is used as a separator, it must not be used in the name of an environment variable. If an application provides an environment block, rather than passing NULL for this parameter, the current directory information of the system drives is not automatically propagated to the new process. For a discussion of this situation and how to handle it, see the following Remarks section. An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains Unicode characters, the dwCreationFlags field's CREATE_UNICODE_ENVIRONMENT flag will be set. If the block contains ANSI characters, that flag will be clear. Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block. lpCurrentDirectory Points to a null-terminated string that specifies the current drive and directory for the child process. The string must be a full path and filename that includes a drive letter. If this parameter is NULL, the new process is created with the same current drive and directory as the calling process. This option is provided primarily for shells that need to start an application and specify its initial drive and working directory. lpStartupInfo Points to a STARTUPINFO structure that specifies how the main window for the new process should appear. lpProcessInformation Points to a PROCESS_INFORMATION structure that receives identification information about the new process. Return Values If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. Remarks The CreateProcess function is used to run a new program. The WinExec and LoadModule functions are still available, but they are implemented as calls to CreateProcess. In addition to creating a process, CreateProcess also creates a thread object. The thread is created with an initial stack whose size is described in the image header of the specified program's executable file. The thread begins execution at the image's entry point. The new process and the new thread handles are created with full access rights. For either handle, if a security descriptor is not provided, the handle can be used in any function that requires an object handle of that type. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process is not able to use the handle to gain access to the thread. The process is assigned a 32-bit process identifier. The identifier is valid until the process terminates. It can be used to identify the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also assigned a 32-bit thread identifier. The identifier is valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are returned in the PROCESS_INFORMATION structure. When specifying an application name in the lpApplicationName or lpCommandLine strings, it doesn't matter whether the application name includes the filename extension, with one exception: an MS-DOS - based or Windows-based application whose filename extension is .COM must include the .COM extension. The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process. The preferred way to shut down a process is by using the ExitProcess function, because this function notifies all dynamic-link libraries (DLLs) attached to the process of the approaching termination. Other means of shutting down a process do not notify the attached DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to execute any additional code (including the thread termination code of attached DLLs). ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold: · During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process. · Only one thread in a process can be in a DLL initialization or detach routine at a time. · The ExitProcess function does not return until no threads are in their DLL initialization or detach routines. The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created. When the last thread in a process terminates, the following events occur: · All objects opened by the process are implicitly closed. · The process's termination status (which is returned by GetExitCodeProcess) changes from its initial value of STILL_ACTIVE to the termination status of the last thread to terminate. · The thread object of the main thread is set to the signaled state, satisfying any threads that were waiting on the object. · The process object is set to the signaled state, satisfying any threads that were waiting on the object. If the current directory on drive C is \MSVC\MFC, there is an environment variable called =C: whose value is C:\MSVC\MFC. As noted in the previous description of lpEnvironment, such current directory information for a system's drives does not automatically propagate to a new process when the CreateProcess function's lpEnvironment parameter is non-NULL. An application must manually pass the current directory information to the new process. To do so, the application must explicitly create the =X environment variable strings, get them into alphabetical order (because Windows NT and Windows 95 use a sorted environment), and then put them into the environment block specified by lpEnvironment. Typically, they will go at the front of the environment block, due to the previously mentioned environment block sorting. One way to obtain the current directory variable for a drive X is to call GetFullPathName("X:",. .). That avoids an application having to scan the environment block. If the full path returned is X:\, there is no need to pass that value on as environment data, since the root directory is the default current directory for drive X of a new process. The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object. The current directory specified by the lpcurrentDirectory parameter is the current directory for the child process. The current directory specified in item 2 under the lpCommandLine parameter is the current directory for the parent process. Windows NT: When a process is created with CREATE_NEW_PROCESS_GROUP specified, an implicit call to SetConsoleCtrlHandler(NULL,TRUE) is made on behalf of the new process; this means that the new process has CTRL+C disabled. This lets good shells handle CTRL+C themselves, and selectively pass that signal on to sub-processes. CTRL+BREAK is not disabled, and may be used to interrupt the process/process group. See Also AllocConsole, CloseHandle, CreateRemoteThread, CreateThread, ExitProcess, ExitThread, GenerateConsoleCtrlEvent, GetCommandLine, GetEnvironmentStrings, GetExitCodeProcess, GetFullPathName, GetStartupInfo, GetSystemDirectory, GetWindowsDirectory, LoadModule, OpenProcess, PROCESS_INFORMATION, ResumeThread, SECURITY_ATTRIBUTES, SetConsoleCtrlHandler, SetErrorMode, STARTUPINFO, TerminateProcess , WaitForInputIdle, WaitForDebugEvent, WinExec -------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Спасибо, Vit! А это из какой версии Delphi?
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
Из любой. Понимаешь ли, в Дельфи грубо говоря есть несколько разных уровней:
1) Модуль system - там прописаны основные конструкции языка, не все в явном виде. Это собственно ядро языка ObjectPascal 2) Модули SysUtils и некоторые другие - там прописаны многие платформонезависимые функции и процедуры для работы с самыми разными данными 3) VCL/CLX - это объектные библиотеки компонентов - кнопки, формы, и т.п. 4) Модули Windows, ShellAPI - там описаны экспортные функции, типы и константы функций самого Windows - так называемых Windows API - физически эти функции находятся в User32.dll, Kernel32.dll и других файлах, составляющих ядро Windows. Дельфи имеет только заголовки для этих dll - посмотри файл Windows.pas - они все там, например CreateProcess там описывается как
Другими словами к дельфи эти функции не имеют никакого отношения, Дельфи толкьо умеет их вызывать, но ничего не знает о их реализации. Реализация их же зависит не от Дельфи, а от версии винды. Поэтому и help на них не всегда срабатывает, он просто поставляется отдельно - поищи у себя на диске файл win32.hlp - вот там и описаны все WinAPI -------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Привет всем! Извините, что долго не появлялась - у меня сломался монитор, а ремонтировать его будут целый месяц. Расскажу о том, как продвигается моя многострадальная задача. В-общем, данные из портов внешнего устройства стали считываться, но иногда есть потери. По-видимому, не хватает мощности компьютера. Но, если отключить все лишние задачи и запускать программу не из IDE, то потерь практически нет. Интересно, поможет ли замена процессора на молее мощный и добавление памяти?
Большое спасибо всем, кто помогал мне, без вас я бы еще долго мучилась! -------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| Vit |
|
|||
![]() Vitaly Nevzorov ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 10964 Регистрация: 25.3.2002 Где: Chicago Репутация: 1 Всего: 207 |
Добавление мощности явно ускорит. Запускай свою программу с высоким приорететом.
-------------------- With the best wishes, Vit I have done so much with so little for so long that I am now qualified to do anything with nothing Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru |
|||
|
||||
| bagira |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2858 Регистрация: 25.10.2003 Где: в тайге Уральских гор Репутация: нет Всего: 123 |
Я подумала, что не стоит все приложение запускать с высоким приоритетом, а запустить лишь ту часть, где осуществляется обращение к портам. И вместо CreateProcess применила CreateThread. Все работает превосходно, потерь данных больше нет. Большое спасибо всем, кто участвовал в обсуждении и помогал мне в этой задаче!
-------------------- Сегодня ты не бродил, не искал, не любил - можно сказать - и не жил... Ф.Х. Дагларджа (Турция) http://zveriolginovour.ru/ https://vmeste.yandex.ru/zveriolginovour |
|||
|
||||
| SergeCpp |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 955 Регистрация: 8.8.2005 Где: At Home Репутация: 1 Всего: 124 |
Жаль, что меня не было в то время на VinGrad'e...
Интересная задачка... Не так, чтобы и очень сложная, но интересная! |
|||
|
||||
![]()
|
| Правила форума "Delphi: WinAPI и системное программирование" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |