WEB开发网
开发学院软件开发汇编语言 实战DeviceIoControl之六:访问物理端口 阅读

实战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三方面的源码,有兴趣的话可以深入研究一下。

上一页  1 2 3 4 

Tags:实战 DeviceIoControl 访问

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接