C/C++使用WinIO读取CMOS数据

基本原理

CMOS RAM 芯片介绍

PC机的主板上集成有CMOS实时时钟,为操作系统提供时间信息:年、月、日与时、分、秒。它附有128或256个字节的RAM,用于存放时间与硬盘、内存、显示卡等最基本的硬件配置信息。操作系统启动时,从CMOS实时时钟中读取时间信息作为系统的基准时间。系统断电后由后备的锂电池供电,以保障信息不丢失。这个芯片内部有两个端口,端口地址为 70h 和 71h,CPU 通过这两个端口来读写 CMOS RAM。70h 为地址端口,存放要访问的 CMOS RAM 单元的地址,71h 位数据端口,存放从选 定的 CMOS RAM 单元中读取的数据,或者要写入到其中的数据。

WinIO简介

Yariv Kaplan在2010年发布开源软件WinIo 3.0,它采用了非文档化的Windows API(native API)和其它一些底层编程技巧绕过Windows安全保护机制,使得Windows下的应用程序可直接对I/O端口进行操作。WinIo 3.0提供了10个库函数,用于对I/O端口和内存物理存储单元的直接读写。WinIo软件包由WinIo.sys、winio_nt.h、Winio.h、WinIo.dll、WinIo.lib(未提供,需要用户在VC2010下生成)等5个核心文件组成。

CMOS RAM信息表

地址内容
00HTime - Seconds
01HAlarm - Seconds
02HTime - Minutes
03HAlarm - Minutes
04HTime - Hours
05HAlarm - Hours
06HDate - Day of the week
07HDate - Day
08HDate - Month
09HDate - Year
0AHStatus Register A
0BHStatus Register B
0CHStatus Register C
0DHStatus Register D
0EHDiagnostic Status
0FHShutdown Status
2EHCMOS Checksum (high byte)
2FHCMOS Checksum (low byte)
32HDate - Century

WinIo与I/O端口操作相关的4个函数

WinIo库函数初始化

      WINIO_API bool _stdcall InitializeWinIo();

卸载WinIo库函数

      WINIO_API void _stdcall ShutdownWinIo();

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位端口。

I/O端口写操作函数

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

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

实现代码

读取CMOS RAM中的数据

代码比较简单,但是可以运行

#include "stdio.h"
#include "windows.h"
#include "winio.h"
#pragma comment( lib, "winio.lib" )
int main( )
{
	DWORD dw;
	bool re;
	byte i;
	re = InitializeWinIo();


	if (re)
	{
		for (i = 0; i < 64; i++) {
			SetPortVal(0x70, i, 1);
			GetPortVal(0x71, &dw, 1);
			switch (i)
			{
			case 0:
				printf("%2d:%4x***秒\n",i,dw);
				break;
			case 2:
				printf("%2d:%4x***分\n", i, dw);
				break;
			case 4:
				printf("%2d:%4x***时\n", i, dw);
				break;
			case 6:
				printf("%2d:%4x*星期\n", i, dw);
				break;
			case 7:
				printf("%2d:%4x***日\n", i, dw);
				break;
			case 8:
				printf("%2d:%4x***月\n", i, dw);
				break;
			case 9:
				printf("%2d:%4x***年\n", i, dw);
				break;
			default:
				printf("%2d:%4x\n", i, dw);
			}
		}

		ShutdownWinIo();
	}
	else
	{
		printf("WinIo函数初始化错误\n");
		exit(1);
	}
	system("pause");
	return 0;
}

将CMOS RAM 中的前64为置零

#include "stdio.h"
#include "windows.h"
#include "winio.h"
#pragma comment( lib, "winio.lib" )
int main( )
{
	DWORD dw;
	bool bResult;
	int i;
	bResult = InitializeWinIo();
	if (bResult)
	{
		for (i = 0; i < 64; i++) {
			SetPortVal(0x70, i, 1);
			SetPortVal(0x71, 0, 1);
		}
		ShutdownWinIo();
	}
	else
	{
		printf("WinIo函数初始化错误\n");
		exit(1);
	}
	system("pause");
	return 0;
}

注意事项

生成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文件;Visual Studio 2015及以上无法生成;

WinIo应用环境配置 :

创建一个Win32控制台应用项目

创建一个“Win32控制台应用程序”的WinIoDemo项目,打开“生成”菜单,单击“生成WinIoDemo”。

复制WinIo核心文件到制定的文件夹

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

修改Winio.h文件

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

测试模式/证书安装

64位的系统管理员身份进入“命令提示符”,输入“bcdedit /set testsigning on”打开测试模式,重启;
右击winio65.dll->属性->数字签名->详细信息->查看证书->安装证书->下一步->将所有的证书都放入下列存储->受信任的根证书颁发机构

以管理员身份打开VC2017!!!

资源下载

WinIO 资源包(含winio.lib、winio.h、winio.sys、winio.dll文件)64/32 位下载
C/C++使用WinIO读取CMOS数据代码下载

部分内容来源:“VC 2010下WinIo 3.0直接访问IO端口”

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值