(1)在WINCE下能够直接访问的都是虚拟地址,不能直接访问GPIO端口,因此我们首先需要将GPIO口的物理地址映射到虚拟地址上来。在普通的应用程序或者驱动中访问内存,还要再用VirtuaAlloc+VirtualCopy做一个内核到当前进程的二次映射(有一种情况例外,就是你的OS被配置成Full Kernel Mode,这时任何应用程序都可以访问OS内核地址).
VirtualAlloc用于在当前进程的虚拟地址空间中保留或者提交空间,在保留时以64KB为单位,提交时以4KB为单位。其函数原型为
LPVOID VirtualAlloc(
LPVOID lpAddress, // 分配虚拟地址的起始指针
DWORD dwSize, // 大小,以字节为单位
DWORD flAllocationType, // 类型,设为MEM_RESERVE
DWORD flProtect // 存取保护,设为PAGE_NOACCESS
);
BOOL VirtualCopy(
LPVOID lpvDest, // 虚拟目的地址指针,接受VirtualAlloc的返回值
LPVOID lpvSrc, // 源物理地址指针
DWORD cbSize, // 大小必须与虚拟地址相同
DWORD fdwProtect // 存取保护类型
);
(2)keybd_event(VK_DOWN,0x27, KEYEVENTF_KEYUP, 0); VK_DOWN为虚拟键值详见MSDN中的keybd_event解释,KEYEVENTF_KEYUP指定则按键释放,不指定则按键按下状态
(3)pdisk是物理上的盘,而hdisk是平时使用的逻辑盘
(4)LoadLibrary加载动态连接库为使用库里面强大的集成功能,如hmCore = (HMODULE) LoadLibrary(_T("coredll.dll"));
(5)MapPtrToProcess函数允许将一个指针从一个地址克难攻坚映射到另一个地址 空间,用于获得对应用程序地址空间数据的访问,GetCallerProcess函数用于获取调用进程的句柄
(6)WaitForMultipleObjects参数依次:句柄数组个数, 句柄数组指针,等待类型,等待时间,如ret = WaitForMultipleObjects(9, gReadKeyEvent, FALSE, INFINITE);
(7)程序包含stdio.h,stdlib.h头文件,则程序会去连接coredll.dll;在wince系统中该库非常重要,我们调用system API时都不是直接调用的,而是先转到coredll.dll,由它帮我们去调用system API的。coredll.dll提供内核的一些功能,其中的函数或变量供我们在驱动中使用。
(8)WINCE 5之前都是静态中断,从CE 5开始中断申请分为动态申请和静态分配2种;楼主用的KernelIoControl+IOCTL_HAL_REQUEST_SYSINTR就是动态申请的方法;静态分配其实很简单,在OEMInterruptHandler里直接switch
case即可;具体实现很多,各家BSP不一样,但是道理都是如此;其实,动态申请就是由系统维护一个table,使得OEM允许其他厂商的驱动以安装的形式动态加到这个table里。作为OEM自己,其实维护一个静态的中断分配就可以了,驱动完全不用动态申请。只不过很多参考BSP用了这个形式,导致大家都在动态申请。(中断设计的头文件:在oalintr.h中添加中断的宏定义,然后在cfw.c中添加初始化,在armint.c中添加ISR程序,处理中断发生后返回定义的中断号)
未完,待续……