实战DeviceIoControl之六:访问物理端口
2010-01-10 09:37:25 来源:WEB开发网核心提示:有了ReadPortByte和WritePortByte这两个函数,我们就能很容易地操纵CMOS和speaker了(关于CMOS值的含义以及定时器寄存器定义,实战DeviceIoControl之六:访问物理端口(4),请参考相应的硬件资料):// 0x70是CMOS索引端口(只写)// 0x71是CMOS数据端口BYT
有了ReadPortByte和WritePortByte这两个函数,我们就能很容易地操纵CMOS和speaker了(关于CMOS值的含义以及定时器寄存器定义,请参考相应的硬件资料):
// 0x70是CMOS索引端口(只写) // 0x71是CMOS数据端口 BYTE ReadCmos(BYTE index) { BYTE data; ::WritePortByte(0x70, index); data = ::ReadPortByte(0x71); return data; } // 0x61是speaker控制端口 // 0x43是8253/8254定时器控制端口 // 0x42是8253/8254定时器通道2的端口 void Sound(DWORD freq) { BYTE data; if ((freq >= 20) && (freq <= 20000)) { freq = 1193181 / freq; data = ::ReadPortByte(0x61); if ((data & 3) == 0) { ::WritePortByte(0x61, data | 3); ::WritePortByte(0x43, 0xb6); } ::WritePortByte(0x42, (BYTE)(freq % 256)); ::WritePortByte(0x42, (BYTE)(freq / 256)); } } void NoSound(void) { BYTE data; data = ::ReadPortByte(0x61); ::WritePortByte(0x61, data & 0xfc); }
// 以下读出CMOS 128个字节 for (int i = 0; i < 128; i++) { BYTE data = ::ReadCmos(i); ... ... } // 以下用C调演奏“多-来-米” // 1 = 262 Hz ::Sound(262); ::Sleep(200); ::NoSound(); // 2 = 288 Hz ::Sound(288); ::Sleep(200); ::NoSound(); // 3 = 320 Hz ::Sound(320); ::Sleep(200); ::NoSound();
Q 就是个简单的端口I/O,这么麻烦才能实现,搞得俺头脑稀昏,有没有简洁明了的办法啊?
A 上面的例子,之所以从编写驱动程序,到安装驱动,到启动服务,到打开设备,到访问设备,一直到读写端口,这样一路下来,是为了揭示在NT/2000/XP中硬件访问技术的本质。假如将所有过程封装起来,只提供OpenMyPort, CloseMyPort, ReadPortByte, WritePortByte甚至更高层的ReadCmos、WriteCmos、Sound、NoSound给你调用,是不是会感觉清爽许多?
实际上,我们平常做的基于一定硬件的二次开发,一般会先安装驱动程序(DRV)和用户接口的运行库(DLL),然后在此基础上开发出我们的应用程序(APP)。DRV、DLL、APP三者分别运行在核心态、核心态/用户态联络带、用户态。比如买了一块图象采集卡,要先安装核心驱动,它的“Development Tool Kit”,提供类似于PCV_Initialize, PCV_Capture等的API,就是扮演核心态和用户态联络员的角色。我们根本不需要CreateFile、CloseHandle、 DeviceIOControl、ReadFile、WriteFile等较低层次的直接调用。
Yariv Kaplan写过一个WinIO的例子,能实现对物理端口和内存的访问,提供了DRV、DLL、APP三方面的源码,有兴趣的话可以深入研究一下。
Tags:实战 DeviceIoControl 访问
编辑录入:爽爽 [复制链接] [打 印][]
- ››实战案例分析:高质量软文对网站百度排名的影响
- ››实战经验浅谈网站搬家后的优化工作
- ››实战Active Directory站点部署与管理,Active Dir...
- ››实战操作主机角色转移,Active Directory系列之十...
- ››实战经验:巧用微博推广淘宝网店
- ››实战iPhone GPS定位系统
- ››实战Linux环境配置DBD:Oracle模块
- ››实战DeviceIoControl系列之一:通过API访问设备驱...
- ››实战DeviceIoControl系列之二:获取软盘/硬盘/光盘...
- ››实战DeviceIoControl系列之三:制作磁盘镜像文件
- ››实战DeviceIoControl系列之四:获取硬盘的详细信息...
- ››实战DeviceIoControl之五:列举已安装的存储设备
更多精彩
赞助商链接