Serge, а мне не нравится создание потока для каждого элементарного действия.
Запускать таймер должен драйвер по одному ему известным условиям. Добавлять драйверное API для таймеров специально для USBшных драйверов только чтобы их обрабатывал поток USB, а не главный, на том основании, что это же USBшный драйвер, - бред.
Тестируем поддержку USB
-
Сделаем мир лучше!
CleverMouse
А причем здесь драйверное API ? И разве нынешнее решение не сделано специально для USB ?
У тебя ведь драйвер уже работает в своём потоке ? Что мешает ему обработать в этом потоке событие таймера ? Почему это должен делать поток OS/IDLE ? Потому что так проще ? На эти грабли уже наступали.
А причем здесь драйверное API ? И разве нынешнее решение не сделано специально для USB ?
У тебя ведь драйвер уже работает в своём потоке ? Что мешает ему обработать в этом потоке событие таймера ? Почему это должен делать поток OS/IDLE ? Потому что так проще ? На эти грабли уже наступали.
Функции TimerHS/CancelTimerHS? Нет, в них нет вообще ничего специфичного для USB. Одним из планов использования, между прочим, является замена check_fdd_motor_status и check_ATAPI_device_event при выносе соответствующего кода в драйвера. Соответственно, я не понимаю, почему ты предлагаешь заняться этим потоку USB, и где ты видишь грабли.
Сделаем мир лучше!
CleverMouse
Ага, значит мы друг друга не понимаем. Совсем ничего не имею против TimerHS/CancelTimerHS. Наоборот таймеры нужны, вопрос в реализации. Моя идея:
Ага, значит мы друг друга не понимаем. Совсем ничего не имею против TimerHS/CancelTimerHS. Наоборот таймеры нужны, вопрос в реализации. Моя идея:
Code: Select all
usb_thread()
{
while(1)
{
kevent_t event;
get_event_ex(&event);
switch(event.code)
{
case EV_IRQ:
;постобработка irq.
break;
case EV_TIMER:
;обрабатываем таймеры
break;
};
};
};
В реализации чего именно?
На что, по-твоему, нужно заменить вот эти два фрагмента из usbhid.asm, который на данный момент является единственным пользователем TimerHS/CancelTimerHS?
На что, по-твоему, нужно заменить вот эти два фрагмента из usbhid.asm, который на данный момент является единственным пользователем TimerHS/CancelTimerHS?
Code: Select all
; 5h. Start the auto-repeat timer.
pop ecx ; restore keycode
mov [ebx+keyboard_data.repeatkey], cl
stdcall TimerHS, 25, 5, autorepeat_timer, ebx
mov [ebx+keyboard_data.timer], eax
Code: Select all
; Timer function for auto-repeat.
autorepeat_timer:
mov eax, [esp+4]
movzx ecx, [eax+keyboard_data.repeatkey]
test cl, cl
jns @f
push ecx
mov ecx, 0xE0
call SetKeyboardData
pop ecx
and cl, not 0x80
@@:
call SetKeyboardData
ret 4
Сделаем мир лучше!
Не надо ничего менять. autorepeat_timer надо вызывать из потока usb (в обработчике EV_TIMER), а не из osloop.
Может я и не прав. Просто мне нравится идея Minix, где каждый сервис работает в своём потоке.
Может я и не прав. Просто мне нравится идея Minix, где каждый сервис работает в своём потоке.
Хорошо. Теперь предположим, что завтра появляется драйвер PS/2-клавиатуры, автор которого посчитал механизм автоповтора в PS/2 недостаточно гибким и тоже использует программную эмуляцию. Естественно, в этом драйвере тоже будут два вышеприведённых фрагмента кода, причём дословно те же самые. Если мы против копипаста, предположим заодно, что загрузчик PE-драйверов умеет обрабатывать импорт не только из ядра, тогда можно считать, что два драйвера просто вызывают одну функцию общей библиотеки. Должен ли поток USB захватывать autorepeat_timer и для этого драйвера? Если да, то что будет, если подсистема USB не загружена, поскольку USB-устройств нет? Если нет, то почему два логически абсолютно идентичных фрагмента кода должны исполняться в двух логически совершенно разных местах?
Я определённо предпочитаю Windows, а не Minix. Там KeSetTimerEx/KeCancelTimer позволяют поставить процедуру на выполнение и не думать, какой именно поток её будет выполнять.
Я определённо предпочитаю Windows, а не Minix. Там KeSetTimerEx/KeCancelTimer позволяют поставить процедуру на выполнение и не думать, какой именно поток её будет выполнять.
Сделаем мир лучше!
Отлично. А теперь предположим, что у нас есть общий сервис (процесс), который принимает от драйверов устройств события (нажатие клавиш, перемещение мыши и джойстика) обрабатывает, сам генерирует автоповтор для клавиатуры, и пересылает приложениям. И этот сервис является частью оконной системы, как и должно быть. Очень похоже на osloop. Должен ли этот процесс обрабатывать таймеры для совершенно посторонних устройств, как флоппи ?
Ответ на твой вопрос зависит от того, создаст ли автор драйвера для PS/2 отдельный процесс. Если нет, он не сможет обработать событие таймера и TimerHS() ему не поможет. Если да, то он будет выполнять autorepeat_timer независимо от usb. Это вопрос принципов устройства драйверной модели.
Я кстати именно эту схему предлагаю, только название у KeWaitForMultipleObjects другое.
Ответ на твой вопрос зависит от того, создаст ли автор драйвера для PS/2 отдельный процесс. Если нет, он не сможет обработать событие таймера и TimerHS() ему не поможет. Если да, то он будет выполнять autorepeat_timer независимо от usb. Это вопрос принципов устройства драйверной модели.
И действительно, зачем нам всякие KeWaitForSingleObject и KeWaitForMultipleObjects если есть замечательные DPC которые блокируют остальные потокиЯ определённо предпочитаю Windows, а не Minix. Там KeSetTimerEx/KeCancelTimer позволяют поставить процедуру на выполнение и не думать, какой именно поток её будет выполнять.
Spoiler:
Есть ещё Threaded DPC но это же VistaNote The CustomTimerDpc routine, like all DPC routines, is called at IRQL = DISPATCH_LEVEL. While a DPC routine runs, all threads are prevented from running on the same processor. Driver developers should carefully design their CustomTimerDpc routines to run for as brief a time as possible.
![Sad :(](./images/smilies/icon_sad.gif)
Ага. Значит, в ситуации "как и должно быть" всё-таки автоповтор обрабатывается не потоком, который, как сложилось, породил драйвер клавиатуры, а потоком-частью оконной системы, который имеет непосредственное отношение к содержимому autorepeat_timer. С этим я соглашусь. Разумеется, в этой ситуации поток-часть оконной системы не должен обрабатывать посторонние таймеры. Я даже соглашусь, что идеологически osloop не должен обрабатывать посторонние таймеры. Тем не менее, сейчас он их по факту обрабатывает, и я считаю, что сейчас это правильно.
Для реализации второго способа работы с KeSetTimerEx - через объекты ядра, на которых могут ждать потоки, - как в винде, нужен планировщик, как в винде. Сейчас каждый новый поток - это заметная нагрузка на систему: планировщик просматривает этот поток, даже если он просто спит, на каждом тике - в предположении ненагруженности системы, когда за тик успевает прокрутиться вся карусель потоков; в CPU этот поток даёт ещё один невнятный вход; если он создан не при загрузке системы и попал в середину карусели с пользовательскими потоками, то получаем плюс одну перезагрузку CR3; каждый новый поток приближает предел в 255 потоков. Мне кажется, что ты это понимаешь и поэтому настаиваешь на включении таймеров в поток usb вместо создания отдельных потоков, хотя идеологически там они столь же неуместны, сколь и в osloop.
Если планировщик не будет вообще обращаться к спящим потокам, будет отдавать предпочтение потокам текущего процесса и система будет чётко осознавать разницу между процессами и потоками - хотя бы для CPU, чтобы он давал внятные показания, - я только за выделение различных сущностей в различные потоки. Но поскольку этого нет, я настаиваю на включении всех мелких задач в osloop, который по факту уже и есть обработчик кучи мелких задач; это экономит время планировщика, ограниченное число потоков, перезагрузки CR3, а в качестве минусов задерживает на миллисекунды отрисовку курсора - с моей точки зрения в текущей ситуации плюсы явно существеннее.
Для реализации второго способа работы с KeSetTimerEx - через объекты ядра, на которых могут ждать потоки, - как в винде, нужен планировщик, как в винде. Сейчас каждый новый поток - это заметная нагрузка на систему: планировщик просматривает этот поток, даже если он просто спит, на каждом тике - в предположении ненагруженности системы, когда за тик успевает прокрутиться вся карусель потоков; в CPU этот поток даёт ещё один невнятный вход; если он создан не при загрузке системы и попал в середину карусели с пользовательскими потоками, то получаем плюс одну перезагрузку CR3; каждый новый поток приближает предел в 255 потоков. Мне кажется, что ты это понимаешь и поэтому настаиваешь на включении таймеров в поток usb вместо создания отдельных потоков, хотя идеологически там они столь же неуместны, сколь и в osloop.
Если планировщик не будет вообще обращаться к спящим потокам, будет отдавать предпочтение потокам текущего процесса и система будет чётко осознавать разницу между процессами и потоками - хотя бы для CPU, чтобы он давал внятные показания, - я только за выделение различных сущностей в различные потоки. Но поскольку этого нет, я настаиваю на включении всех мелких задач в osloop, который по факту уже и есть обработчик кучи мелких задач; это экономит время планировщика, ограниченное число потоков, перезагрузки CR3, а в качестве минусов задерживает на миллисекунды отрисовку курсора - с моей точки зрения в текущей ситуации плюсы явно существеннее.
Сделаем мир лучше!
Планировщик не переключается на блокированные потоки. Поиск по всем TASKDATA и проверка событий для ожидающих потоков занимает незначительное время. Хотя разбирать события в планировщике не лучшее решение.
Приношу извинения за поднятие такой старой темы, но я только сейчас добрался до ковыряния кода usbhid.asm. Я так понимаю, что этот драйвер вызывается только тогда, когда ядро уже определило, что устройство - это HID? Потому что я добавляю в драйвер отладочную строчку, и не вижу ее:
Впрочем, я вообще никаких строчек не вижу, получаю сообщение ядра о том, что что-то не так с SET_ADDRESS, и USB-устройство будет отключено. Использовал ядро и исходник драйвера с ftp. Как сделать так, чтобы ядро и с другими Class/Subclass/Protocol работало? Нашел наконец исходники драйвера, через который работает мой 3G-модем, хочу попробовать для начала хотя бы совершать звонки.
Code: Select all
AddDevice:
mov edx, [esp+12]
push ebx ; save used register to be stdcall
mov cx, word [edx+interface_descr.bInterfaceSubClass]
DEBUGF 1,'K : unknown device: %x\n',cx
SoUrcerer,
мне тоже интересно попробовать свои силы в драйверописании. Исходники ядра с usb были бы как нельзя кстати, пусть и не на svn.
CleverMouse,CleverMouse в usbapi.txt wrote:For every interface the kernel looks for class code of this interface and loads the corresponding COFF driver. Currently the correspondence is hardcoded into the kernel code and looks as follows: 3 = usbhid.obj.
мне тоже интересно попробовать свои силы в драйверописании. Исходники ядра с usb были бы как нельзя кстати, пусть и не на svn.
Last edited by dunkaist on Fri Mar 02, 2012 12:16 pm, edited 1 time in total.
Да, я именно об этом и подумал. Спасибо за уточнение. Все равно, поэкспериментировать желание имеется.
Ядро http://ftp.kolibrios.org/users/CleverMo ... kernel.mnt синхронизировано с транком. Драйвера usbhid.obj и usbstor.obj не пострадали. В процессе синхронизации произошло выпиливание старых мьютексов и замена их новыми, так что могли появиться глюки.
Я напоминаю, что ядро умеет работать с существующими и вновь подключаемыми usb1-устройствами, определяя их class/subclass/protocol и выводя информацию на доску отладки, а также - при существовании usbhid.obj и usbstor.obj в папке drivers - поддерживать мышки и клавиатуры и распечатывать первые несколько байт первого сектора флешки для проверки работы с аппаратной частью. USB2-устройства в зависимости от настроек BIOSа и конкретного порта, к которому они подключены, могут либо работать на скорости usb1, либо захватываться BIOSом, в последнем случае ядро либо не увидит их совсем, либо произойдёт ошибка на первой стадии конфигурации aka SET_ADDRESS. При динамическом переподключении USB2-устройства могут в зависимости от тех же условий либо быть, либо не быть захваченными BIOSом.
Я напоминаю, что ядро умеет работать с существующими и вновь подключаемыми usb1-устройствами, определяя их class/subclass/protocol и выводя информацию на доску отладки, а также - при существовании usbhid.obj и usbstor.obj в папке drivers - поддерживать мышки и клавиатуры и распечатывать первые несколько байт первого сектора флешки для проверки работы с аппаратной частью. USB2-устройства в зависимости от настроек BIOSа и конкретного порта, к которому они подключены, могут либо работать на скорости usb1, либо захватываться BIOSом, в последнем случае ядро либо не увидит их совсем, либо произойдёт ошибка на первой стадии конфигурации aka SET_ADDRESS. При динамическом переподключении USB2-устройства могут в зависимости от тех же условий либо быть, либо не быть захваченными BIOSом.
Сделаем мир лучше!
Мышка, я разницы при байтовом сравнение trunk'ов не увидел. Сможешь покакать где проблемная часть возникла?
Или могла возникнуть, случаем![Smile :)](./images/smilies/icon_smile.gif)
Или могла возникнуть, случаем
![Smile :)](./images/smilies/icon_smile.gif)
Программист не тот, кто постоянно пишет КОД, а тот кто сможет понять чужой КОД!!!
Who is online
Users browsing this forum: No registered users and 0 guests