WINCE下I/O操作基础
生活随笔
收集整理的這篇文章主要介紹了
WINCE下I/O操作基础
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
| ? |
| 對外設進行?I/O?操作實際上也就是讀寫外設的寄存器,而我們通常使用的X86或者ARM處理器在硬件上決定了wince系統啟動后,無法直接訪問物理地址,因此需要做一些工作來實現I/O操作.?? 首先要理解?windows?CE?下的地址映射機制。?wince有兩種地址:物理地址和虛擬地址.不同架構的?CPU?硬件上的區別導致地址映射也不同。MIPS和SH?x?處理器,不采用MMU,直接在CPU和內核里定義?1G?的物理地址;而X86和ARM帶有?MMU?單元,在?OEMAddressTable?中定義物理地址到虛擬地址間的映射關系或者是OS啟動后調用?CreateStaticMapping?和?NKCreateStaticMapping?來實現從虛擬地址到物理地址的靜態映射.經過靜態映射的地址,可以由操作系統內核用于?ISR?訪問設備。如果我們要在應用程序中訪問外設,必須在物理地址和虛擬地址間建立動態映射關系,我們可以使用?VirtualAlloc?和?VirtualCopy?(或者直接調用?MmmapIoSpace?函數)來實現。?? 其次,如果是操作通過總線掛接的?I/O?或者存儲器,必須先把總線地址轉化成?CPU?上的系統地址,再做物理地址到虛擬地址的映射。這里需要查?CPU?的?Datasheet?,找出所要操作的I/O地址.先調用?HALTranslateBusAddress(?)把總線地址轉化成CPU上的系統地址,?再調用?MmmapIoSpace?函數實現虛實映射;也可以使用?TransBusAddrToVirtual?()直接把總線上的地址轉化成系統的虛擬地址。?? 第三,在一般的應用程序中訪問?I/O?是訪問它的緩存段虛擬地址,而驅動中必須訪問無緩存段虛擬地址。簡單來說無緩存段虛擬地址?=?緩存段虛擬地址?+0x20000000?。?? ????總結起來,如果是?wince?內核(如HAL)訪問外部?I/O?,只需要在?OEMAddressTable?中定義物理地址到虛擬地址間的映射關系就可以了;如果是應用程序或者驅動要訪問?I/O?,要做的工作包括:?1?。在?CPU?物理地址和虛擬地址間做一個動態映射,?2?。對虛擬地址進行操作。? 在X86和ARM架構的CPU中,wince訪問系統內存的方法隨程序所屬模式層次的不同而有所區別.? ??1.在系統內核模式下(kernel?mode),在OAL層訪問,只需要在OEMAddressTable?中做靜態的虛實地址映射就可以了.例如X86架構的映射表格式如下:? ???;?OEMAddressTable?defines?the?mapping?between?Physical?and?Virtual?Address??//?定義4GB的虛擬地址和512MB存儲的映射關系? ???;???o?MUST?be?in?a?READONLY?Section? ???;???o?First?Entry?MUST?be?RAM,?mapping?from?0x80000000?->?0x00000000? ???;???o?each?entry?is?of?the?format?(?VA,?PA,?cbSize?)? ???;???o?cbSize?must?be?multiple?of?4M? ???;???o?last?entry?must?be?(0,?0,?0)? ???;???o?must?have?at?least?one?non-zero?entry? ???;?RAM?0x80000000?->?0x00000000,?size?64M???????//把物理地址為0x00000000映射到虛擬地址為?0x80000000?處? ???dd??80000000h,????0,???04000000h? ???;?FLASH?and?other?memory,?if?any? ???;?dd??FlashVA,??????FlashPA,????FlashSize? ???;?Last?entry,?all?zeros? ???dd??0???0???0? 2.在驅動或應用程序(user?mode)中訪問RAM,既可以通過OEMAddressTable+VirtualCopy方式,也可以直接用MmMapIoSpace函數建立物理地址到當前進程虛擬地址的映射關系.? 經過OEMAddressTable,實現的只是CPU物理地址到OS內核層虛擬地址的一次映射,如果需要在普通的應用程序中訪問內存,還要再用VirtuaAlloc+VirtualCopy做一個內核到當前進程的二次映射(有一種情況例外,就是你的OS被配置成Full?Kernel?Mode,這時任何應用程序都可以訪問OS內核地址).? ?????簡單說明幾個關鍵函數:? ?????VirtualAlloc用于在當前進程的虛擬地址空間中保留或者提交空間,在保留時以64KB為單位,提交時以4KB為單位。其函數原型為?? ?LPVOID?VirtualAlloc(?? ??LPVOID?lpAddress,??//?分配虛擬地址的起始指針?? ??DWORD?dwSize,?????//?大小,以字節為單位?? ??DWORD?flAllocationType,?//?類型,設為MEM_RESERVE?? ??DWORD?flProtect????//??存取保護,設為PAGE_NOACCESS?? );?? ??c:?? ??BOOL?VirtualCopy(?? ??LPVOID?lpvDest,?????????//?虛擬目的地址指針,接受VirtualAlloc的返回值?? ??LPVOID?lpvSrc,?????????//?源物理地址指針?? ??DWORD?cbSize,??????????//?大小必須與虛擬地址相同?? ??DWORD?fdwProtect??//?存取保護類型?? );?? 這里需要注意的是?fdwProtect?參數。如果是驅動程序訪問,需要設置為?PAGE_NOCACHE?,以訪問無緩存段虛擬地址。如果映射的物理地址范圍在?0x1FFFFFFF?之上,必須使用?PAGE_PHYSICAL?,此時必須把?lpvSrc?右移八位,實現地址對齊。(這是由內核中?VirtualCopy?的實現決定的,在那個函數中會判斷如果是?PAGE_PHYSICAL?就將?PHYSADDR?左移?8?位移回來,源代碼位于?private/winceos/coreos/nk/kernel?目錄下的?virtmem.c中的DoVirtualCopy?)?? ??????MmMapIoSpace?用來把物理地址直接映射到與進程無關的虛擬地址上。函數原型為?? ?PVOID?MmMapIoSpace(?? ??PHYSICAL_ADDRESS?PhysicalAddress,?? ??ULONG?NumberOfBytes,?? ??BOOLEAN?CacheEnable?? );? ??一個使用?VirtualAlloc+Copy?的例子:把物理地址為?0x10000000?的單元映射到虛擬地址空間中。?? #include?<windows.h>?? ??? #define?PHYSADDR??((PVOID)0x10000000)?? //?PHYSADDR?is?the?physical?address?of?the?peripheral?? //?registers?? ??? #define?SIZE??(4800*4)?? ??? LPVOID?lpv;?? BOOL?bRet;?? ??? lpv?=?VirtualAlloc(0,?SIZE,?MEM_RESERVE,?PAGE_NOACCESS);?? //?For?a?user?mode?driver,?always?leave?the?first?? //?parameter?0?and?use?only?the?flags?MEM_RESERVE?? //?and?PAGE_NOACCESS?Check?the?return?value:?lpv?==?0?? //?is?an?error?? ??? printf(TEXT("VirtualAlloc?reservation?@%8.8lx/r/n"),?lpv);?? bRet?=?VirtualCopy(lpv,?PHYSADDR>>8,?SIZE,?PAGE_READWRITE?|?PAGE_NOCACHE?|?PAGE_PHYSICAL);? //?The?lpv?parameter?is?the?virtual?address?returned?? //?by?VirtualAlloc().?? //?Always?use?PAGE_NOCACHE?*/?? ??? //?Check?the?return?value:?bRet?==0?is?an?error?*/?? printf(TEXT("VirtualCopy?returned:?%d/r/n"),?bRet);?? ??? //?At?this?point?lpv?is?a?virtual?address?which?maps?? //?the?I/O?registers?? //?at?PHYSADDR?for?SIZE?bytes?*/? |
總結
以上是生活随笔為你收集整理的WINCE下I/O操作基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 招行附属卡怎么绑定微信
- 下一篇: 信用卡密码函可以丢吗