Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinCE 6.0 и драйвер для ARM926
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы
Russky
Всем привет!

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

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

Спасибо! sm.gif
Russky
Цитата(SimpleSoft @ Feb 18 2015, 21:49) *


Спасибо за информацию. Но пока что-то непонятно как это работает. Сколько не пытался скопировать (VirtualCopy) буффер по адресу 0xc4000000, все время возвращает мне false.
Russky
Еще вопрос возник.
Сейчас у меня драйвер компилируется и подгружается с основным имиджем WinCE. Это очень должго и нужно.
Возможно ли как-то перекомпилировать и перегружать драйвер без перекомпиляции имиджа целиком? Хоти-бы для отладки?

Спасибо! :-)
Russky
Всем привет, еще раз!
Вот разобрался, как работает адресация. Но возникла теперь вот какая проблема.
Есть метод 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
Russky
Всем привет!
Можете меня поздравить! Я сделал двайвер под WinCE! sm.gif
Все оказалось не сложно, но нюансов достаточно много было. Может как-нибудь напишу инструкцию о том, как писать двайвера под CE. sm.gif
Иваныч
Цитата(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.
Поздравляю ! Такая инструкция была бы очень полезна.

Russky
Цитата(Иваныч @ 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/
SimpleSoft
Цитата(Russky @ Feb 20 2015, 17:18) *
Вот разобрался, как работает адресация. Но возникла теперь вот какая проблема.
Есть метод MmMapIoSpace. Я его пытаюсь вызвать из C# приложения.
Кто знает где ошибка?

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


Да! Только хотел об этом написать! sm.gif
Russky
И так! Продолжаем описание. 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
Russky
В общем разобрались с режимами 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
SimpleSoft
Рекомендую литературу
http://caxapa.ru/177773.html

Также посмотрите про маршаллинг https://msdn.microsoft.com/en-us/library/jj...ror=-2147217396
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.