MikePol
Постоялец
Offline
|
|
« : 12-12-2007 06:52 » |
|
Есть плата PCI. Использует 1024 байта ресурсов памяти. Для нее написал драйвер Windows, который эту память читает/записывает с помощью фукций READ_REGISTER_ULONG и WRITE_REGISTER_ULONG. Но разработчик изменил протокол передачи данных на "пакетную передачу данных". ( Memory Read Multiple, Memory Read Line, packet burst) Расскажите по каким ключевым словам искать, как мне драйвер изменить ? О чем надо почитать ? Заранее спасибо.
|
|
« Последнее редактирование: 12-12-2007 07:08 от MikePol »
|
Записан
|
|
|
|
sss
Специалист
Offline
|
|
« Ответ #1 : 12-12-2007 08:50 » |
|
А поточнее - разработчик изменил какие драйвера ? Протоколов ?
|
|
|
Записан
|
while (8==8)
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #2 : 12-12-2007 09:45 » |
|
Разработчик изменил протокол чтения данных в плате, как я понял. Раньше я считывал 1024 байта из памяти с помощью READ_REGISTER_ULONG. Теперь он говорит, что я, каким то образом должен устанавливать флаг трансзакции, считывать буфер данных, потом сбрасывать флаг. Разработчик не знает, как это реализовывается со стороны ОС. Вот хотелось бы узнать что это может быть ? Возможно тут DMA надо использовать ? Разработчик дал "набор ключевых слов" из спецификации PCI : Memory Read Multiple, Memory Read Line, burst
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #3 : 12-12-2007 11:23 » |
|
насколько я понимаю, речь идет об отображаемой памяти? то есть 1К находится в железке а вы его читаете по требованию? если да, то: никаких средств операционки тут нет. операционка просто отображает память находящуюся в железе в адресное пространство ПК. READ_REGISTER_ULONG и WRITE_REGISTER_ULONG - макросы, которые под intel процессорами просто читают память. то что ваш разработчик подключил "бурст" если и повлияет на что-то, то только на контроллер доступа к памяти. короче шина сама разберется. максимум что вы можете сделать, используйте _asm movsd или просто memcpy(s, d, LenDW*4); настоятельно! рекомендую использовать именно такой тип указания длинны блока(либо жестко 1024) - будет более оптимальный код. а флаги транзакции выставит контроллер памяти. но! пусть ваш разработчик на них особо не закладывается, так как транзакции по шине не обязательно будут длинной 1024 байта. длинна транзакции определяется занятостью шины и может быть прервана в любой момент. придумывайте собственную синхронизацию например через порты I/O.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #4 : 12-12-2007 11:36 » |
|
Ochkarik, спасибо за ответ, но видно что то другое он сделал Потому как в тестовой версии прошивки обмен с платой должен происходить следующим образом. Устанавливается флаг транзакции, начинается чтение данных по одному и тому же смещению (0 в моем случае). , считывается, к примеру 10 двойных слов (все время по одному и тому же смещению 0) В итоге я должен получить данные [0,1,2 ..10]. Потом я каким то образом должен сбросить флаг транзакции. Сейчас если использовать READ_REGISTER_ULONG - все время получаю 0.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #5 : 12-12-2007 11:57 » |
|
извращение))) лентяй он у тебя))) да? и причем тут вобще бурстовые транзакции ты у него не спросил?))) если не ошибаюсь при пакетных транзакциях в железку приходит начальный адрес откуда читать и длинна. геморой с тем, что когда пакет будет прерван знает только шина) поэтому он решил не гемороится, а по любому запросу просто выдавать данные из фифо... скорее всего еще и без проверки адреса) впрочем эт ладно.. эт я так... сами такие)
короче забудь про READ_REGISTER_ULONG, и вместо него поставь чтение memcpy(,,1024). транзакцию начинает контроллер шины, и думаю, что при одиночном чтении - он может пакетную и не запрашивать. а заодно уточни, что за флаг транзакции он смотрит? я точно помню что транзакция может досрочно быть оборвана шиной. и скорее всего так и происходит.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ochkarik
|
|
« Ответ #6 : 12-12-2007 12:01 » |
|
стоп? как это по одному смещению? ересь. при пакетной транзакции запрос на чтение выглядит так: 1 ты выполняешь чтение адреса памяти. 2. проц переводит значение адреса из виртуального в физический. 3. запрос доходит до контроллера шины 4, контролер шины говорит типа ага! это запрос к такой то железке и формирует запрос. 5 такой запрос на шине выглядит так: адрес и длинна. железка это получает и начинает плеваться данными. нет там флага. 6. когда контроллеру шины надоест, или кто то еще ресурс запросит, может прервать данную транзакцию и обратиться к другому устройству. ... 7 потом вернуться к прерванной транзакции и запросить заново, (передать новое смещение с которого прервала и новую длинну) .. я тут наверняка сильно напутал, но общий принцип примерно такой.
PS вы несколько неправильно пакетную транзакцию поняли. при обычных запросах чтения, по шине выдается запрос адреса (например +0) с которого читать и железо возвращает 32 бита лово. потом опять адрес(+4)-данные. оптом опять запрос адрес(+8) обратно данные.
при пакетной транзакции выполняется линейное чтение паямяти. в этом случае необязательно каждый раз выдавать новый адрес с новым смещением. поэтому контроллер выдает начальный адрес(например +0), и длинну (например 16) а все что выплюнет железка контроллер шины САМ разложит по необходимым линейным адресам. причем чтение 1кб с точки зрения транзакций по шине, скорее всего выполнится в несколько запросов(транзакций) с разными начальными адресами и может быть разной длинной: запрашиваем чтение 1кб данных, запросы по шине такие: первый - чтение с +0 длинной 16, второй - чтение с +16 длинной 32. третий - чтение с +48 длинной 32. и т.д. в сумме получится как бы линейное чтение с адреса +0 до адреса +1020 словами по 32 бита. это тебе контроллер и отдаст в итоге. с точки зрения быстродействия шины - тратится меньше времени на передачу нового адреса, вот и все.
|
|
« Последнее редактирование: 12-12-2007 12:19 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
sss
Специалист
Offline
|
|
« Ответ #7 : 13-12-2007 01:28 » |
|
Если честно я так и не понял:
1. Устройство - сетевая плата или какое? 2. Кто пишет драйвер - MikePol или разработчик ? 3. Изменилось само устройство ? 4. Есть datasheet контроллеров ?
|
|
|
Записан
|
while (8==8)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 13-12-2007 04:11 » |
|
Offtopic: влезу тут с маленьким замечанием насчёт memcpy: Remarks Copies count bytes of src to dest. If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions. лучше привыкать пользоваться memmove Поставлю в угол.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #9 : 13-12-2007 12:20 » |
|
Алексей1153++, русский секс бесмысленен и беспощаден))))
пример компиляции майкрософтом memove и memcpy: memmove(TextBuff, TextBuff2, Counter_All_Sample*4 ); mov eax, DWORD PTR _Counter_All_Sample lea ecx, DWORD PTR [eax*4] push ecx lea edx, DWORD PTR _TextBuff2$[esp+596] push edx lea eax, DWORD PTR _TextBuff$[esp+600] push eax call _memmove add esp, 12 ; 0000000cH
; 605 : memcpy(TextBuff, TextBuff2, Counter_All_Sample*4 );
mov ecx, DWORD PTR _Counter_All_Sample lea esi, DWORD PTR _TextBuff2$[esp+608] lea edi, DWORD PTR _TextBuff$[esp+608] rep movsd
есть разница?))) так что memmove только там где это ДЕЙСТВИТЕЛЬНО надо...
PS а интеловский компилятор в релизе жестоко раскидывает... не буду приводить) да и не совсем адекватно будет.
PPS кстати почему я намекал что при копировании выровненных на 32 бита буферов использовать умножение на 4 при вызове: ; 605 : memcpy(TextBuff, TextBuff2, Counter_All_Sample );
mov ecx, DWORD PTR _Counter_All_Sample mov edx, ecx shr ecx, 2 lea esi, DWORD PTR _TextBuff2$[esp+608] lea edi, DWORD PTR _TextBuff$[esp+608] rep movsd mov ecx, edx and ecx, 3 rep movsb думаю коментарии излишни)
|
|
« Последнее редактирование: 13-12-2007 12:25 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 13-12-2007 12:23 » |
|
по барабану пример компиляции ) В мсдн английским по белому сказано - если перекрываются участки памяти, юзать надо memmove. И хочь ты тресни ) А там - личное дело каждого , закладывать глюки в прогу или нет. Лучше всегда memmove пользовать от греха подальше
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #11 : 13-12-2007 12:33 » |
|
Алексей1153++, если! а если нет - то зачем? а уж если копируешь пересекающиеся участки - тут сам бог велел подумать) в любом случае здесь не тот случай... и потом я привык ресурсы не растрачивать зазря...
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 13-12-2007 12:35 » |
|
Ochkarik, для того, чтобы не думать о том, что они пересекаются ))) Ой, да конечно, ресурсов жрёт это много. Прямо задыхается компутер лана, моё дело маленькое - предупредить Я наступал на эти грабельки
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #13 : 13-12-2007 12:41 » |
|
Алексей1153++, вы просто не сталкивались) еще как задыхается... да я что... я - ничего) пригодится)
MikePol, кстати... о том флаге... если ничего другого не придумаете, пусть ваш железячник у себя счетчик поставит, отосланых слов... по достижении размера буфера - вот вам и флаг что все вычитано. но тогда уж тебе придется гарантировать что ты лишний раз читать не будешь) хотя мне не нравится такой метод... мало ли кто еще залезет, и опачки. лучше через запись в IO порты, если не лениво.
|
|
« Последнее редактирование: 13-12-2007 12:52 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 13-12-2007 12:53 » |
|
Ochkarik, задыхается - пора менять железо
|
|
|
Записан
|
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #15 : 17-12-2007 08:12 » |
|
Ochkarik, большое спасибо за объяснения принципа работы . Попробовал memcpy - не помогло. Сейчас плата сделана следующим образом: +0: должен быть пакетный режим, при запросе которого буфер должен заполняться числами (0,1,2,3 ... (N-1)), где N - колчиство запрашиваемых слов. +1: возвращает константу А +2: возвращает константу В +3: 0 пытаюсь запросить буфер данных : ULONG *packet[4] = {0}; memcpy(&packet, pdx->mem_start, 16); В итоге получаю : packet = {0,A,B,0 } , должен получить {0,1,2,3} Железячник говорит, что система делает 4 запроса (транзакции). Вопрос в общем то риторический ....
|
|
« Последнее редактирование: 17-12-2007 09:05 от MikePol »
|
Записан
|
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #16 : 17-12-2007 09:05 » |
|
Что я не так делаю ?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 17-12-2007 09:16 » |
|
ULONG *packet[4] = {0}; - а почему массив указателей , а не просто переменных ? ULONG packet[4]; memcpy(packet, pdx->mem_start, sizeof(packet));
|
|
« Последнее редактирование: 17-12-2007 09:18 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #18 : 17-12-2007 09:18 » |
|
ой, блин, сорри, допустил ошибку - см переправленный пост с кодом. Не надо адрес у packet брать
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #19 : 17-12-2007 09:55 » |
|
MikePol, стоп... чего то я не понял... вот это: +0: должен быть пакетный режим, при запросе которого буфер должен заполняться числами (0,1,2,3 ... (N-1)), где N - колчиство запрашиваемых слов. +1: возвращает константу А +2: возвращает константу В +3: 0
это что? +0 +1 +2 +3 - смещение адреса певрого слова чтения? адреса по шине лучше на 4 байта выравнивать. и вообще по шине только словами по 32 бита работают. может с этим что то не так... второе... сам уже забыл.. давно мы с этим ковырялись... странно что 4 транзакции.... подразумевалось что четыре раза адрес был запрошен? в пакетном режиме транзакция должна быть одна.. с запросом четырех слов. в противном случае что то не так... может из за выравнивания? у тебя в драйвере массив для копирования на сколько выровнен? попробуй выделить его принудительно с выравниванием в 4Кб. вряд ли... но вдруг) еще... что то там с PREFETCH было такое... но уже не помню... упреждающее чтение... то ли ставить то ли нет... не помню уже. и был еще в PCI параметр... "latency" что ли, или "maxGNT"... я его в софтайсе смотрел командой "pсi"... помоему от него макимальная длинна транзакции как-то косвенно зависела. если айс есть- сравните конфигурационное пространство вашей платы с сетевухой например.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #20 : 17-12-2007 10:26 » |
|
Ochkarik, 0,1, 2, 3 - это смещение относительно базового адреса платы. я имел ввиду в двойных словах. то есть в байтах - 0,4,8,12.
Должна быть одна транзакция - по факту получается 4. По факту получается, то, что я выше описал. Наверное 4 раза считывается, раз такой результат. С выравниванием все ОК.
Про PREFETCH , latency, maxGNT - попробую.
|
|
|
Записан
|
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #21 : 17-12-2007 10:31 » |
|
ой, блин, сорри, допустил ошибку - см переправленный пост с кодом. Не надо адрес у packet брать
Да, я понял, спасибо.
|
|
|
Записан
|
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #22 : 19-12-2007 07:36 » |
|
так ничего у меня и не получилось. Не хочет пакетная передача работать. А про PREFETCH , latency, maxGNT - где смотреть ? У меня RapidDriver стоит, там можно PCI Command/STATUS, HEADER изменять. Но что то PREFETCH я так и не нашел. Сейчас у меня при выполнении memcpy(packet, pdx->mem_start, 16) - выполняется 4 раза чтение 32битных слов с 0,4,8,12 смещения соответственно. Я правильно понимаю, что контроллер шины не дожидается всех данных, получает одно значение с 0го смещения, потом запрашивает с 4-го .. .и так далее. Почему это происходит и где искать ошибку ? В плате или можно что то программно изменить ?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #23 : 20-12-2007 16:39 » |
|
программно не получится - это какой то аппаратный флаг в конфигурационном пространстве вашей железки, если она вообще умеет в таком режиме работать)... по нему контроллер ПК определяет можно ли блочное чтение выполнять или нет. точнее это помоему называется линейным чтением... или как-то так...
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ochkarik
|
|
« Ответ #24 : 20-12-2007 18:03 » |
|
http://www.sm1820.com.ru/KSNews_170.htmпочитайте, может найдется что нибудь полезное. оно даже по русски переведено...может поможет) потом еще поищу) самому стало интересно)))
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
MikePol
Постоялец
Offline
|
|
« Ответ #25 : 21-12-2007 10:50 » |
|
Тут вопрос возник , а возможно ли организовать пакетную передачу на х86 под Windows воообще ? Гук пишет что организовать сложно, и реально только через регистры ММХ и ХММ. Ochkarik, А получалась пакетная передача у вас ?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #26 : 21-12-2007 12:36 » |
|
а чем вам Windows и x86 не угодила?))) второе. хто такой Гук? и при чем тут вообще MMX регистры? PCI разрабатывалась когда и понятия такого вообще не было))) и не шибко сильно с тех пор менялась... а что у нас получилось - увы я уже не помню. помню что мы с тем же вопросом точно ковырялись. а вот что вышло... у железячника нашего спросил - тоже не помнит. в любом случае мы в конечном счете на Master перешли. скорости нужны были большие, а памяти в железке мало поставили. но 100% что это у нас реализовано в мастереPCI. суть та же, только уже наша железка пишет в память ПК. PS проверьте кто у вас транзакцию обрывает, и по какой причине. а вообще... нужна ли вам такая скорость?)
|
|
« Последнее редактирование: 21-12-2007 12:39 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|