阅读:1067回复:6
向各位大虾请教这几个端口读写函数的具体含义
WRITE_PORT_UCHAR(PUCHAR port, UCHAR data)
WRITE_PORT_USHORT(PUSHORT port, USHORT data) WRITE_PORT_ULONG(PULONG port, ULONG data) UCHAR READ_PORT_UCHAR(PUCHAR port) USHORT READ_PORT_USHORT(PUSHORT port) ULONG READ_PORT_ULONG(PULONG port) 比如现在我想从 0x378 读一个字节或写一个字节应该选哪一对读写函数?为什么? |
|
沙发#
发布于:2003-10-12 11:06
还有一个问题:
应该怎样把打开设备和设备操作封装到动态连接库中,我现在用 CretateFile 老是失败 |
|
板凳#
发布于:2003-10-12 13:13
WRITE_PORT_UCHAR(PUCHAR port, UCHAR data) 这几个函数的区别在于读/写的数据不同, UCHAR是8bit,USHORT是16bit,ULONG是32bit。 你的要求是读/写1byte也就是8bit, 用WRITE_PORT_UCHAR / READ_PORT_UCHAR。 |
|
|
地板#
发布于:2003-10-12 14:25
实际上本人的疑惑是在函数的本身,而不在数据类型。
一个 unsigned char 自然是一个 8 位数据,但一个 0x378 是什么?我想它起码应该是 unsigned short 16 位。问题是,为什么需要用一个 unsigned char * 作为端口地址传送呢? 这个映射地址如何来实现? 难道只能分配 255 个吗? 还希望高手能再解释一下 |
|
地下室#
发布于:2003-10-12 14:31
如果没有地址的话,怎么知道数据要送到哪里去?
|
|
|
5楼#
发布于:2003-10-12 14:37
我找到资料了,非常感谢你们的回答
端口与寄存器 -------------------------------------------------------------------------------- 图7-4显示了Windows 2000驱动程序访问硬件设备的几种模式。通常,CPU的内存地址空间和I/O地址空间是分离的。为了访问“内存映射”设备,CPU用load或store操作直接对一个虚拟地址进行内存引用,然后CPU利用一组页表把虚拟地址转换成物理地址。为了访问“I/O映射”设备,CPU必须使用特殊的机制,如使用x86处理器上的IN和OUT指令。 图7-4. 访问端口与寄存器 设备使用总线专有的方式解码内存和I/O地址。在PCI总线中,主PCI桥把CPU物理地址和I/O地址映射到总线地址空间,而设备可以直接访问总线地址空间。对于两种地址空间都支持的CPU,设备配置空间中的标志位决定了主PCI桥是把设备寄存器映射成内存地址还是映射成I/O地址。 正如我刚提到的,某些CPU有分离的内存地址空间和I/O地址空间。例如,Intel架构的CPU同时支持这两种地址空间。其它CPU,例如Alpha,仅有一个内存地址空间。如果你的设备是I/O映射的,PnP管理器将赋予你端口资源。如果你的设备是内存映射的,它将赋予你内存资源。 为了避免为兼容各种平台而使用大量条件编译代码,Windows NT的设计者发明了硬件抽象层(HAL),这个概念我曾在本书的多个地方提到过。HAL提供了用于访问端口和内存资源的函数,见表7-3。正如这个表所指出的,你可以从或向一个PORT/REGISTER资源READ/WRITE一个或一组UCHAR/USHORT/ULONG值。有24个函数用于设备访问,但WDM驱动程序不直接依靠HAL做任何事,你可以把这24个函数看成是HAL的全部公共接口。 表7-3. 用于访问端口和内存寄存器的HAL函数 存取宽度 端口访问函数 内存访问函数 8位 READ_PORT_UCHAR WRITE_PORT_UCHAR READ_REGISTER_UCHAR WRITE_REGISTER_UCHAR 16位 READ_PORT_USHORT WRITE_PORT_USHORT READ_REGISTER_USHORT WRITE_REGISTER_USHORT 32位 READ_PORT_ULONG WRITE_PORT_ULONG READ_REGISTER_ULONG WRITE_REGISTER_ULONG 8位字节串 READ_PORT_BUFFER_UCHAR WRITE_PORT_BUFFER_UCHAR READ_REGISTER_BUFFER_UCHAR WRITE_REGISTER_BUFFER_UCHAR 16位字串 READ_PORT_BUFFER_USHORT WRITE_PORT_BUFFER_USHORT READ_REGISTER_BUFFER_USHORT WRITE_REGISTER_BUFFER_USHORT 32位双字串 READ_PORT_BUFFER_ULONG WRITE_PORT_BUFFER_ULONG READ_REGISTER_BUFFER_ULONG WRITE_REGISTER_BUFFER_ULONG 很明显,这些访问函数的内部实现与平台高度相关。例如,Intel x86版本的READ_PORT_CHAR函数用IN指令从指定的I/O端口读一个字节。而在Windows 98中,有些地方甚至把驱动程序对这个函数的CALL指令直接替换成IN指令。该函数的Alpha版本则执行一个内存提取。READ_REGISTER_UCHAR函数的Intel x86版本将执行一个内存提取;而该函数的Alpha版本则是一个直接内存引用的宏。该函数的缓冲区版本,READ_REGISTER_BUFFER_UCHAR,在x86环境中需要做一些额外工作,以确保在操作完成时所有CPU的高速缓存都被正确刷新。 使用HAL的关键原因是你可以不必担心平台的不同,也不用担心Windows 2000的多任务和多处理器环境对设备访问的特殊要求。因此,你的工作将十分简单:使用PORT调用访问端口资源,使用REGISTER调用访问内存资源。 |
|
6楼#
发布于:2003-10-12 14:50
谁能帮我解答第二个问题!在加载动态库时我想用 LoadLibrary
来实现。目前有一个现象:动态库内部用 CreateFile 不能打开设 备,从调用层试用参数输入就可,但必须在工程引入投文件和 lib 库文件进行联编,如果使用 loadLibrary ,只要一加载完动态库程序就自动退出。要注明的是:在程序主线成启动后的线程中加载。 |
|