VC 2010下WinIo 3.0直接访问I/O端口

2015-06-29 02:06付笑宇张线媚
科技资讯 2015年13期
关键词:驱动程序

付笑宇 张线媚

摘 要:WinIo 3.0软件包只提供了在C#使用WinIo的用例,且没有提供WinIo.lib文件,使得VC 2010下无法直接使用WinIo。在VC 2010下对WinIo 3.0的源码重新进行编译生成WinIo.lib,修改WinIo.h文件后VC 2010下即可直接使用WinIo。给出了一个应用样例,实验结果表明该方法安全、简洁、高效。

关键词:内核态 WDF 驱动程序 I/O端口

中图分类号:TP311 文献标志码:A 文章编号:1672-3791(2015)05(a)-0020-02

在电网实时测控系统研发过程中,需要使用in和out指令对测控单元的端口直接进行读写,但X86CPU的硬件保护机制将I/O指令指定为特权指令,禁止用户态的应用程序访问I/O端口。用户态的应用程序只能通过运行于核心态的设备驱动程序提供的API间接地访问I/O端口,实时性较差。

Windows操作系统为用户提供了WDM (Windows Driver Model)[1]架构,用于编写设备驱动程序。WDM架构异常复杂,要求开发人员对Windows系统内部的管理机制非常熟悉,有丰富的系统级应用开发的经验,驱动程序的调试相对困难,其安全性与效率无法保障。

Yariv Kaplan在2010年发布开源软件WinIo 3.0[2],它采用了非文档化的Windows API(native API)和其它一些底层编程技巧绕过Windows安全保护机制,Windows下的应用程序程序可直接对I/O端口进行操作、

1 WinIo 3.0简介

WinIo 3.0支持32位和64位版的Windows 7/8,它提供了10个库函数,用于对I/O端口和内存物理存储单元的直接读写。WinIo软件包由WinIo.sys、winio_nt.h、Winio.h、WinIo.dll、WinIo.lib(未提供,需要用户在VC2010下生成)等5个核心文件组成。与I/O端口操作相关的4个函数如下:

(1)WinIo库函数初始化。

WINIO_API bool -stdcall InitializeWinIo();

(2)卸载WinIo库函数。

WINIO_API void -stdcall ShutdownWinIo();

(3)I/O端口读操作函数。

WINIO_API bool _stdcall GetPortVal(WORD wPortAddr,PDWORD pdwPortVal,BYTE bSize);

参数wPortAddr为端口地址,16位整型变量或常量;参数pdwPortVal为指向一存放读取端口内容的32位整型变量指针;参数bSize为实际读取的字节数,8位整型变量或常量,取值范围为1、2或4,表示读操作的对象为8位、16位或32位端口。

(4)I/O端口写操作函数。

WINIO_API bool _stdcall SetPortVal(WORD wPortAddr,DWORD dwPortVal, BYTE bSize);

参数wPortAddr为端口地址,16位位整型变量或常量;参数dwPortVal为要写入端口的32位整型变量或常量;参数bSize为实际写出的字节数,取值范围为1、2或4,表示写操作的对象为8位、16位或32位端口。

2 VC 2010下WinIo 3.0的应用

2.1 VC 2010下WinIo.lib的生成

WinIo 3.0软件包的Source文件夹下包含了WinIo的源文件及其所需的资源,其下的DLL文件夹为VC 2010的WinIo项目文件夹。生成WinIo.lib文件的步骤如下。

(1)双击“WinIo.sln”启动WinIo项目。

(2)在VC 2010 IDE下打开“生成”菜单,单击“生成WinIo”。

生成的WinIo.lib文件它存放于“.\Suorce\DLL\Debug”文件夹。注意:VC 2010学习版不能生成WinIo.lib文件。

2.2 VC 2010下WinIo应用环境配置

(1)创建一个Win32控制台应用项目。

启动VC 2010,创建一个“Win32控制台应用程序”的WinIoDemo项目,在VC2010 IDE下打开“生成”菜单,单击“生成WinIoDemo”。

(2)复制WinIo核心文件到制定的文件夹。

将WinIo 3.0软件包的Source文件夹下的winio_nt.h、Winio.h与WinIo.lib复制到WinIoDemo项目文件夹下,WinIo.sys与WinIo.dll复制到WinIoDemo项目文件夹下的Debug文件夹。

(3)修改Winio.h文件。

将Winio.h中的“#include"..\drv\winio_nt.h"”,修改为“#include "winio_nt.h"”;

(4)配置链接器附加依赖项。

在VC 2010 IDE下打开“项目”菜单,单击“属性”,打开项目属性页对话框,打开“配置属性”目录树,选择“链接器”下的“输入”子项,在“附加依赖项”中添加“WinIo.lib”,如图1所示。WinIo应用环境配置完成,用户可以编写自己的源代码进行调试。

2.3 CMOS RAM读写实例

PC机的主板上集成有CMOS实时时钟,为操作系统提供时间信息:年、月、日与时、分、秒。它附有128或256个字节的RAM,用于存放时间与硬盘、内存、显示卡等最基本的硬件配置信息。操作系统启动时,从CMOS实时时钟中读取时间信息作为系统的基准时间。系统断电后由后备的锂电池供电,以保障信息不丢失。

PC机为CMOS实时时钟分配了70H和71H两个8端口,用于访问CMOS RAM,在进行读写操作时,需要先向70H端口写入CMOS RAM单元的地址,然后通过71H端口进行读写操作。

CMOS RAM的0、2、4单元分别存放秒、分、小时信息,7、8、9单元依次存放日、月、年信息,这些数据均采用压缩的BCD码表示。下面的代码是一个完整的利用WinIo实现对I/O端口直接进行读写操作的样例,它先读取CMOS RAM的9号单元的年份信息并显示,然后再向9号单元写入新的年份信息。重新启动PC后,Windows系统则采用新的年份。该样例源代码在32位版的Windows 7/8操作系统平台上,使用VC 2010调试通过。

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

#include

#include "winio.h"

int _tmain(int argc, _TCHAR* argv[])

{

DWORD dwPortVal;

bool bResult;

bResult = InitializeWinIo();

if (bResult)

{

// write CMOS ram addr=9

SetPortVal(0x70, 9, 1);

// read CMOS ram addr=9,year,BCD code

GetPortVal(0x71, &dwPortVal, 1);

printf("Current Year:%4x\n",dwPortVal);

printf("Enter new year:");

scanf("%x",&dwPortVal);

SetPortVal(0x70, 9, 1);

SetPortVal(0x71,dwPortVal , 1); //write new year

SetPortVal(0x70, 9, 1);

GetPortVal(0x71, &dwPortVal, 1); //read new year

printf(" new Year:%4x\n",dwPortVal);

// When you're done using WinIo, call ShutdownWinIo

ShutdownWinIo();

}

else

{

printf("Error during initialization of WinIo.\n");

exit(1);

}

printf("\nPress anyke to continue …");

_getch();

return 0;

}

3 结语

该文给出了一种在VC 2010下使用WinIo 3.0的简洁方法,已有的采用使用WinIo 2.0开发的应用系统,无需修改源代码,在VC 2010下重新编译后即可迁移到安全性更好的WinIo 3.0平台。在实时测控系统的开发中,使用WinIo 3.0,省去了设备驱动程序的开发环节,可以极大的缩短系统的开发周期,降低开发成本,系统的安全性和可靠性也得到了保障。

参考文献

[1] 邰铭 ,武安河,于洪涛.Windows 2000/XP WDM设备驱动程序开发[M].北京:电子工业出版社,2003.

[2] Yariv Kaplan.WinIo[DB/OL].http://www.internals.com,2014-11-02.

[3] 孙颖.随机波浪数据采集与处理技术的研究[D].天津:天津理工大学,2014.

[4] 万振凯,郭建民.大型自动化三维编织复合材料编织机的开发[J].纺织导报,2013(9):64-66,68.

[5] 袁军,谭永东,任俊.利用WinIo实现并口数据通信[J].计算机与现代化,2009(8):49-53.

[6] 冯晓伟,李正生,吴宁.XP系统下CB对ISA总线的读写方法及应用研究[J].自动化与仪器仪表,2011(5):17-19.

[7] 王元强,朱为.一种通过PCI总线配置FPGA的设计方法[J].现代电子技术,2010(2):90-92,95.

猜你喜欢
驱动程序
更新、备份、还原、卸载驱动程序管理一条龙
避免Windows系统更新反复安装显示驱动
方便直观改善Windows驱动程序管理
设备升级问题回退驱动解决
阻止Windows Update更新驱动程序
计算机硬件设备驱动程序分析
基于MPC8280的CPU单元与内部总线驱动程序设计
基于WDM的 USB键盘驱动程序开发*
驱动光盘丢了不用愁 打印一体机驱动程序下载安装实战体验
妙用鼠标驱动