
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.52] |
![]() |
|
Страницы: (51) « Первая ... 23 24 [25] 26 27 ... 50 51 ( Перейти к последнему сообщению ) |
Сообщ.
#361
,
|
|
|
Каждый хост проецирует свои регистры в пространство ввода-вывода. Надо работать с портами. По какому именно адресу находится базовый порт, нужно смотреть в регистрах PCI - это уже уровень пониже.
Работал с низким уровнем очень давно, поэтому уже всё практически позабывал, но могу посоветовать литературу, которая в совокупности со спецификациями мне в своё время помогла всё сделать как надо: 1. Сергей Петров: Шины PCI, PCI Express. Архитектура, дизайн, принципы функционирования (это по работе с регистрами PCI - инициализация, чтение регистров, поиск устройств на шине и т.п.) 2. Михаил Гук: Шины PCI, USB и FireWire (уже непосредственно по работе с USB хост-контроллерами) Ну и естественно, долго и муторно листал эту тему. Это помогло мне местами решить некоторые проблемы |
Сообщ.
#362
,
|
|
|
Boogerman, UHCI не проецирует регистры на адресное пространство, а работает через порты ввода-вывода. Базовый (начальный)адрес пространства портов записывается в конфигурационном пространстве PCI как BAR1. Только там младший бит надо обнулить. Адреса всех нужных портов вычисляются относительно этого базового адреса.
А вот что касается собственно ввода-вывода, то тут действительно надо глубоко изучать литературу. Потому что через эти порты никакой ввод-вывод не делается. Они служат только для управления контроллером. Сам же ввод-вывод идет по прямому доступу в память (DMA) и управляется специальными блоками - Transfer Descriptor (TD). В самых общих чертах все делается примерно так: ты строишь очередь этих самых TD, а потом через порт даешь контроллеру команду на ее выполнение. Но есть много тонкостей. Короче, надо читать. Добавлено А из литературы рекомендую: В.Кулаков. Программирование на аппаратном уровне. Там UHCI рассмотрен очень подробно, с примеами на Ассемблере. |
Сообщ.
#363
,
|
|
|
Цитата Хрен @ Boogerman, UHCI не проецирует регистры на адресное пространство, а работает через порты ввода-вывода. Да, загнался. Перепутал с OHCI =) |
Сообщ.
#364
,
|
|
|
Цитата zakharo @ Там UHCI рассмотрен очень подробно, с примеами на Ассемблере. И ошибок там в этих примерах хватает... Добавлено Суть вопроса для меня до конца не ясна. Прежде чем работать с регистрами хост-контроллера нужно получить базовый адрес блока этих регистров (BAR). Получить его можно с шины PCI, но предварительно контроллер на ней надо еще найти + иногда на этом этапе требуется конфигурирование контроллера. После того как базовый адрес блока регистров получен, то можно с ними работать согласно спецификации (как правило сперва требуется инициализация). По данному коду ничего конкретного я сказать не могу. В частности не ясно как инициализируются хост-контроллеры и само USB устройство. ЕМНИП почти также как и bulk. Цитата Boogerman @ Но вроде в спецификации к UHCI написано, что только хост может выдавать запросы на получение и отправление данных. Да, это так. Есть некоторая разница в обработке, давно уже низкоуровневым программированием USB не занимался, многое забыл, но точно помню, что поле считывания Interrupt пакета при определенных настройках хост-контроллера может генериться аппаратное прерывание от контролера. Какие параметры конкретно надо определить? |
Сообщ.
#365
,
|
|
|
Цитата shm @ И ошибок там в этих примерах хватает... На самом деле именно ошибок там можна сказать нету (по крайней мере грубых), там просто очень ограниченная реализация. Например он использует размер пакета для нулевой конечной точки равным 8 (константа), что правда далеко не для всех устройств. Соответственно и работают его примеры далеко не со всеми устройствами. Но для начала, чтобы разобраться, вполне нормально. Добавлено Цитата Boogerman @ Но вроде в спецификации к UHCI написано, что только хост может выдавать запросы на получение и отправление данных. Если это так, тогда не пойму разницы между InterrupIn и BulkIn... Да, запрос на данные может выдавать только хост, устройство инициировать передачу не может. Разницы между BulkIn и InterruptIn с точки зрения структуры и функционирования нету, у меня с ними работает одна и та же функция. Вся разниза заключается в том что они в разные очереди помещаются, и у InterruptIn приоритет выше. Т.е. вначале обрабатываются все InterruptIn, а потом, если осталось время в текущем кадре, BulkIn. Кроме приоритета разницы нету. Более того, если устройство имеет Interrupt конечную точку, запросы к ней вполне можно помещать в очередь TD для Bulk транзакций, всё будет работать, просто приоритет на получение данных будет низкий. Зачем два типа разных ввели - ну допустим у тебя есть мышь и флэшка, мышь использует Interrupt конечную точку, флэшка - Bulk. Так вот чтобы не получилось, что ты с флэшки что-нибудь копируешь, занял всю пропускную способность шины, пользователь мышью дёргает, а эффекта ноль. А потом, только когда закончится копирование, система получит все сообщения от мыши (или не все если у мыши буфер маленький). Чтобы этого не было, у Interrupt устройств приоритет выше сделан. Т.е. Interrupt конечные точки рассчитаны на переодическую передачу небольших пакетов, а Bulk - на передачу больших объёмов, необязательно срочно. Это если на пальцах. |
Сообщ.
#366
,
|
|
|
Хорошо, спасибо. С интерраптами Я разобрался.
С портами так все и делается: Я получал базовый адрес, а дальше через встроенную функцию в BorlandС - outpw(Base+shift, word), inpw(Base+shift),- обращаюсь через смещение к тому или иному регистру, записываю или считываю то или иное значение. По поводу формирования ТД и вопроса о том, по какой команде контроллер понимает, что данные подготовлены и их нужно передавать, Я сделаю уточнение с приложенным кодом во вторник или понедельник вечером (Все на работе осталось, дома исходников нету). Да а так же о последовательности передачи числа. Насколько Я смог вычитать, моментом для передачи или приема данных считается формирование пустого TD с битом Terminate = 1. Кстати Дескрипторы на прием для хоста Я должен готовить сам? То есть от МК Я получаю данные только о готовящемся для передачи объеме данных? Цитата Цитата (Boogerman @ 10.11.11, 17:52)Но что-то не въеду, как по ним определять те или иные параметры. Какие параметры конкретно надо определить? Хорошо, задам вопрос по отладке по-другому. Расскажите, как Вы производите отладку хост-контроллера. Ведь при написании обычного приложения при появлении ошибки компиллятор выдаст те или иные указания на ошибку. С МК и хост-контроллерами такой фигни нет, и если код не работает, то начинаешь усиленно чесать репу и задавать себе вопросы типа: "Ну какого *gensored* опять *gensored* хрена?? Уже неделю с тобой *gensored* вожусь, а Ты все *gensored* никак не поддаешься". |
Сообщ.
#367
,
|
|
|
Цитата Boogerman @ По поводу формирования ТД и вопроса о том, по какой команде контроллер понимает, что данные подготовлены и их нужно передавать, У каждого объекта есть определенные биты определяющие валидность (его самого и ли связанных с ним). У дескриптора передачи это ЕМНИП 23 бит поля управления и сотояния. У заголовка к примеру есть бит 0ой бит Т в в поле указателя на список дескрипторов. Для того, чтобы UHC начал дорабатывать связанный с ним список TD, этот бит надо обнулить. Сразу после того, как контроллер обработает цепочку TD (у них 23 бит должен быть установлен в 1, иначе контроллер проигнорирует), то он сам установит этот бит в единичку и это будет сигналом "подсунуть" ему другую очередь. Добавлено Цитата Boogerman @ Насколько Я смог вычитать, моментом для передачи или приема данных считается формирование пустого TD с битом Terminate = 1. Нет, насколько я помню этот бит служи только в качестве флага последнего элемента в списке. А вот в списке кадров бит T определяет валидность указателя. Добавлено Цитата Boogerman @ Кстати Дескрипторы на прием для хоста Я должен готовить сам? Естественно, а как иначе-то? Вы в этом дескрипторе должен указать физический адрес (обращаю на это внимание) буфер куда считаются сами данные. Кстати по поводу адресов, во всех структурах данных указываются физические адреса. И все области данных должны быть расположены за 1вым мегабайтом адресного пространства. Добавлено Цитата Boogerman @ То есть от МК Я получаю данные только о готовящемся для передачи объеме данных? Не понял до конца вопрос. Цитата Boogerman @ Расскажите, как Вы производите отладку хост-контроллера Ну отладку самого контроллера я никогда не производил, ибо и так хорошо работает ![]() Цитата Boogerman @ при появлении ошибки компиллятор выдаст те или иные указания на ошибку Компилятор может выдать только указания на синтаксический ошибки. Ошибки в работе может помочь найти отладчик, но для программ работающих с железом зачастую от него толку не много. Рекомендую для этих целей использовать виртуальную машину с возможностью мониторинга обмена данными с вирт. железкой. |
Сообщ.
#368
,
|
|
|
Цитата shm @ И все области данных должны быть расположены за 1вым мегабайтом адресного пространства. Совсем не факт. У меня все прекрасно работает в области реальных адресов (в пределах 640 Кб). Кстати, для этой области физические адрса вычисляются элементарно просто. Добавлено Цитата Boogerman @ С портами так все и делается: Я получал базовый адрес, а дальше через встроенную функцию в BorlandС - outpw(Base+shift, word), inpw(Base+shift),- обращаюсь через смещение к тому или иному регистру, записываю или считываю то или иное значение. Я тоже работал в BorandC 3.1. Мне еще пришлось дописать на ассемблере функции inpd и outpd, т.к. все или почти все порты UHCI - 32-битные. |
Сообщ.
#369
,
|
|
|
Цитата shm @ И все области данных должны быть расположены за 1вым мегабайтом адресного пространства. Располагать можно где угодно, требования есть только к выравниванию. Цитата zakharo @ У меня все прекрасно работает в области реальных адресов (в пределах 640 Кб). Кстати, для этой области физические адрса вычисляются элементарно просто. Они одинаково вычисляются для любых логических адресов. |
Сообщ.
#370
,
|
|
|
Цитата cppasm @ Они одинаково вычисляются для любых логических адресов. Не-а... Если мы будем работать с адресами выше 640 К, то наткнемся на отображаемую область памяти. Это будет либо страничка EMS, либо просто блоки "верхней" памяти, если мы в config.sys напишем для EMM386 ключ NOEMS или RAM. А для таких страничек простая арифметика типа (сегмент*16)+смещение не работает. Нужно пользоваться функцией 8103h прерывания 4Bh (LOCK DMA REGION). |
Сообщ.
#371
,
|
|
|
Это если экстендер использует виртуальную память.
Общая схема получения физического адреса в защищённом режиме такая: А разница в случае с экстендером возникает из-за того, что они для страниц ниже 1Мб устанавливают прозрачное преобразование, т.е. виртуальный адрес страницы равен физическому. В общем это просто частный случай. А вообще для доступа ко всей памяти проще использовать так называемый Unreal Mode или Flat Real Mode. Это реальный режим со всеми вытекающими, доступны функции BIOS, DOS и т.д. - просто предел для всех сегментов установлен в 4Гб, т.е. можно в сегментный регистр записать 0 и при помощи 32-битного смещения адресовать до 4Гб памяти. |
Сообщ.
#372
,
|
|
|
M Удалено по просьбе автора сообщения |
Сообщ.
#373
,
|
|
|
Цитата Boogerman @ Я с успехом все это подзабыл, и уложилось лишь то, что это конструктивные особенности процессора и его внутренней памяти. Чтобы получить реальный адрес нужно получить адрес смещения сегмента и нечто вроде статического адреса и сложить их со смещением в 4 бита. Кто-нибудь знает откуда вообще можно это прочитать? Это в реальном режиме. В защищённом или нереальном все адреса уже указываются явно, без сегмента. Так что зависит от того, в каком режиме ты работаешь. |
Сообщ.
#374
,
|
|
|
Цитата Boogerman @ Наткнулся вот на такую книжонку "Intel Architecture Software Developer’s Manual Volume 2: Instruction Set Reference", но полистав понял, что это преимущественно команды ассемблера. Базовые вещи описаны в первом томе (архитектура), более детально - в третьем (системное программирование). Лучше все скачать и полистать хотя бы. http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html |
Сообщ.
#375
,
|
|
|
Цитата zakharo @ Совсем не факт. У меня все прекрасно работает в области реальных адресов Цитата cppasm @ Располагать можно где угодно, требования есть только к выравниванию. Не везде оно будет прекрасно работать. Был у меня ноут на базе PIIX4, на нем DMA (ни IDE, ни USB) не работало с памятью ниже первого мегабайта. Там этой памятью работает только стандартный DMA контроллер (FDD и прочие). Добавлено Цитата Boogerman @ Кто-нибудь знает откуда вообще можно это прочитать? Много где, всех проще в учебниках по ассемблеру написано, например Юров Ассемблер. Добавлено Цитата Boogerman @ Вроде ни адресов ни ссылок на них не даем, кроме адресов на элементы массива данных. Ссылки быть должны, к примеру из заголовка очереди. Сами дескрипторы могут образовывать список. |