реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> WinCE 6.0 и драйвер для ARM926, Как правильно доступаться к памяти?
Russky
сообщение Feb 18 2015, 16:16
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Всем привет!

Есть следующая проблема. Работаю с OMAP-L138. C ARM под WinCE. Написал простенький драйвер (драйвер загружается, IOControl вызывается, все замечательно).
Моему драйверу надо работать с областью памяти для взаимодействия с DSP, например 0xc4000000. Т.е. в эту область надо записать, и считать.
Когда я смотрю как работает DSPLink драйвер, то для того чтобы записать в эту область, но преобразует адрес и записывает в d3a10000. Зачем он это делает, в смысле преобразует, и как он преобразует реальный адрес в этот?
И еще.
Когда мой драйвер пытается доступиться к адресу больше 0x80000000, у меня программа вылетает с OS exception. Очивидно, что там как-то включается режим доступа к адресам, но вопрос как?

В общем вороса два:
Как мне преобразовывать реальный адрес в "виртуальный"?
И как разрешить драйверу доступ ко всему адресному пространству?

Спасибо! sm.gif
Go to the top of the page
 
+Quote Post
SimpleSoft
сообщение Feb 18 2015, 17:49
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 273
Регистрация: 3-11-05
Пользователь №: 10 442



https://msdn.microsoft.com/en-us/library/bb331824.aspx
https://msdn.microsoft.com/en-us/library/aa450977.aspx
Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 19 2015, 13:31
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Цитата(SimpleSoft @ Feb 18 2015, 21:49) *


Спасибо за информацию. Но пока что-то непонятно как это работает. Сколько не пытался скопировать (VirtualCopy) буффер по адресу 0xc4000000, все время возвращает мне false.
Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 19 2015, 17:41
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Еще вопрос возник.
Сейчас у меня драйвер компилируется и подгружается с основным имиджем WinCE. Это очень должго и нужно.
Возможно ли как-то перекомпилировать и перегружать драйвер без перекомпиляции имиджа целиком? Хоти-бы для отладки?

Спасибо! :-)
Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 20 2015, 14:18
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Всем привет, еще раз!
Вот разобрался, как работает адресация. Но возникла теперь вот какая проблема.
Есть метод MmMapIoSpace. Я его пытаюсь вызвать из C# приложения. Вот враппер:

[DllImport("k.coredll.dll")]
или
[DllImport("coredll.dll")]
public static extern IntPtr MmMapIoSpace(ulong PhysicalAddress, uint NumberOfBytes, bool CacheEnable);

При вызове этого метода, вылетает эксепшен, что метода такого нет: Can't find PInvoke DLL 'k.coredll.dll'. (или Can't find PInvoke DLL 'coredll.dll'.)

Или этот метод можно вызывать только из драйвера?

Кто знает где ошибка?
Спасибо! sm.gif
Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 22 2015, 00:22
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Всем привет!
Можете меня поздравить! Я сделал двайвер под WinCE! sm.gif
Все оказалось не сложно, но нюансов достаточно много было. Может как-нибудь напишу инструкцию о том, как писать двайвера под CE. sm.gif
Go to the top of the page
 
+Quote Post
Иваныч
сообщение Feb 22 2015, 22:07
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 188
Регистрация: 5-10-05
Из: Советский Союз
Пользователь №: 9 244



Цитата(Russky @ Feb 19 2015, 19:41) *
Возможно ли как-то перекомпилировать и перегружать драйвер без перекомпиляции имиджа целиком? Хоти-бы для отладки?
Можно делать Build->Advanced Build commands->Build (или Rebuild) current BSP and subprojects.

Шпаргалка что и когда компилировать https://guruce.com/blogpost/what-to-build-when

Цитата(Russky)
Можете меня поздравить! Я сделал двайвер под WinCE! sm.gif
Все оказалось не сложно, но нюансов достаточно много было. Может как-нибудь напишу инструкцию о том, как писать двайвера под CE.
Поздравляю ! Такая инструкция была бы очень полезна.

Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 23 2015, 15:19
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Цитата(Иваныч @ Feb 23 2015, 02:07) *
Можно делать Build->Advanced Build commands->Build (или Rebuild) current BSP and subprojects.


Можно. Но это особенность TI делать уё...ные сборки, которые компиляться долго и только с бубном. sm.gif
За шпаргалку - спасибо! :-)

Цитата(Иваныч @ Feb 23 2015, 02:07) *
Поздравляю ! Такая инструкция была бы очень полезна.


Сделаю.
Начнем с того, что сначала все скачивают вот эту тулзу:
https://cedriverwiz.codeplex.com/
Go to the top of the page
 
+Quote Post
SimpleSoft
сообщение Feb 24 2015, 05:34
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 273
Регистрация: 3-11-05
Пользователь №: 10 442



Цитата(Russky @ Feb 20 2015, 17:18) *
Вот разобрался, как работает адресация. Но возникла теперь вот какая проблема.
Есть метод MmMapIoSpace. Я его пытаюсь вызвать из C# приложения.
Кто знает где ошибка?

Ошибка в том, что VirtualCopy и MmMapIoSpace работают только в Kernel mode. Т.е. трансляция должна быть организована в драйвере, работающем в режиме ядра.
Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 24 2015, 08:54
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



Цитата(SimpleSoft @ Feb 24 2015, 09:34) *
Ошибка в том, что VirtualCopy и MmMapIoSpace работают только в Kernel mode. Т.е. трансляция должна быть организована в драйвере, работающем в режиме ядра.


Да! Только хотел об этом написать! sm.gif
Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 24 2015, 10:12
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



И так! Продолжаем описание. sm.gif

WinCE, как и любая винда, работает с виртуальными адресами. Т.е. приложение не напрямую обращается к памяти, а через виртуализатор(у процессора есть специальный HW блок который это делает автоматом, но нам это знать вообще не нужно). Нужно просто знать, что процессор может автоматом конвертить виртуальный адрес A в физический B. Сделано это для защиты. Т.е. если мы попробуем доступиться к адресу 0xс4000000, или любому другому физическому адресу, приложение выдаст нам ошибку и закроется.
Верно и обратное. Если мы считываем данные из памяти с адресом 0x1223, то это не физический адрес DDR, а виртуальный. Где реально находится эта память - ХЗ.

Для того чтобы обратиться к физическому адресу, нам надо получить его виртуальный адрес. Но сделать это можно только в режиме kernel (режим ядра, но правельней наверное режим драйвера).

Приложение работает только в обычном режиме, поэтому получить виртуальный адрес физической памяти для него невозможно.


Важно отметить: режимы user и kernel - это не физические режимы, т.е. нельзя переключить режим вызовом специальной ф-и! Это очень тонкий момент, и я на нем остановлюсь поподробнее.

Как винда переключает режимы (для меня это было не очивидно из описаний).
На этапе когда запускается ф-я, винда разрещает user или kernel режим для этой ф-и в зависимости от того в каком участке памяти эта ф-я расположена. Т.е. у винды есть таблица, где храниться соответствие адреса и режима. По умолчанию все ф-и всех приложений расположены в памяти помеченной как user.
Если мы загружаем в приложении DLL, то ф-и этой DLL будут располагаться в памяти user.
Для того чтобы ф-я и все что в ней запускалась в режиме kernel, DLL должна быть загружина специальной ф-ей, которая помечает ее память как kernel.
В общем случае, сделать это можно, если загружать DLL как dll драйвера на этапе загрузки виндов. Т.е. если мы скажем винде загрузить нашу DLL как драйвер в режиме kernel, то сможем внутри ф-й этой DLL работать в режиме ядра.
Как загрузить в режиме ядра, чуть позже... sm.gif
Go to the top of the page
 
+Quote Post
Russky
сообщение Feb 24 2015, 14:27
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 17-11-11
Пользователь №: 68 371



В общем разобрались с режимами win и пришли к выводу, что драйвер необходим. Теперь вернемся к драйверу.

Итак, драйвер должен просто писать и читать данные по физическому адресам: 0xdeadf000...0xdeadface. Сначала сгенерим двайвер с помощью https://cedriverwiz.codeplex.com/.
Создаем стрим двайвер в kernel режиме, realtime сообщения и IOControl. Префикс - DDA. Путь выбирите сами.

Для этого нам надо в драйвере сказать винде, что мы хотим это сделать. Для этого в методе Init драйвера (DDA_Init(), где DDA это префикс драйвера) вызываем ф-ю MmMapIoSpace()
примерно так:
void* access_addr = MmMapIoSpace(0xdeadf000,.0xdeadface - 0xdeadf000, FALSE);
FALSE означает что нам не нужно кешировать эту память.

ВСЕ!
Теперь нам надо сохранить переменную access_addr как глобальную.
Дальше, в методе DDA_IOControl, реализуем две команды: Read и write.

Read будет: memcpy(pBufOut, access_addr, dwLenOut);
Цкшеу будет: memcpy(access_addr, pBufIn, dwLenIn);
Вот как-то так.
Теперь давайте разберемся, как нам подкомпилировать драйвер, чтобы он был установлен в видах (WinCE в нашем случае)... sm.gif
Go to the top of the page
 
+Quote Post
SimpleSoft
сообщение Feb 25 2015, 20:14
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 273
Регистрация: 3-11-05
Пользователь №: 10 442



Рекомендую литературу
http://caxapa.ru/177773.html

Также посмотрите про маршаллинг https://msdn.microsoft.com/en-us/library/jj...ror=-2147217396
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01387 секунд с 7
ELECTRONIX ©2004-2016