菜鸟的求助啊!关于winio 得到cpu温度
#include <iostream>#include <Windows.h>
#include "WinIo.h"
using namespace std;
#pragma comment(lib, "winio.lib")
int PMU_SC = 0x6C;//命令端口
int PMU_DATA = 0x68;//数据端口
int RD_EC_SMI = 0x80;//读寄存器命令
int POLLING_DATA = 0xE7;//CPU温度寄存器号
DWORD dwTemp = 0;
void PMU_Wait4IBE(DWORD *_value);
void PMU_Wait4OBF(DWORD *_value);
int main(int argc, char* argv[])
{
if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
//1、mov dx,PMU_SC //
//2、mov al,RD_EC_SMI //
//3、call pmuWait4IBE //Musthave 输入缓冲为空吗,为空可以放命令了
//4、out dx,al //将读寄存器命令放到命令端口中。
PMU_Wait4IBE(&dwTemp);
SetPortVal(PMU_SC, RD_EC_SMI, 1);
PMU_Wait4IBE(&dwTemp);
SetPortVal(PMU_DATA, POLLING_DATA, 1);
PMU_Wait4IBE(&dwTemp);
cout << dwTemp << endl;
ShutdownWinIo();
system("pause");
return 0;
}
void PMU_Wait4IBE(DWORD *_value)
{
//#########################################################
/*
pmuWait4IBE proc
PUSH AX
PW4IBE:
IN AL,06CH //ReadPMUstatus
TEST AL,2 //IsInputBufferEmpty?
JNZ PW4IBE //Jmpifno
POP AX
ret
pmuWait4IBE endp //ENDOFPMUWAIT4IBE
*///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
//#########################################################
/*do
{
GetPortVal(PMU_SC, _value, 4);
}
while ( *(_value) & 0x00000001 );*/
DWORD dwRegVal=0;
do
{
GetPortVal(PMU_SC,&dwRegVal,1);
}
while(dwRegVal!=0x2);
}
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
所以变成了死循环了。
我对硬件编程不懂。又不知道从何下手。
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
感觉现在无从下手。我在网上google不到pmu的信息。比如说我想搞清楚0x6c到底是pmu的什么东西。我想这该有张表什么的吧?硬是没得。郎个办嘛?有哪位大侠给我指条明路吧!::'( 这东西,底层实现是千差万别的。你如果没有主板的电路图的话,怎么知道温度这些东西是那种方式设计的? 一般的程序都是通过Windows的API读的 你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
所以.....呵呵 按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
那么有些什么可行的办法呢?
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗? http://www.ufoit.com/bbs/viewthread.php?tid=420
http://www.ufoit.com/bbs/viewthread.php?tid=452
http://www.ufoit.com/bbs/viewthread.php?tid=241
看来得先从这些地方看看了。谢谢楼上两位的回答。 那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
2、Driver最复杂,也需要BIOS配合,推荐。
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
你可以混合使用。
===============================================================
管理员的这句话:
“如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
“予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵! http://www.ufoit.com/bbs/viewthread.php?tid=269
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。 原帖由 Faintsnow 于 2010-2-6 14:58 发表 http://www.ufoit.com/bbs/images/common/back.gif
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢:handshake 找个APIC spec看看就知道了 不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
void write66(unsigned char Data)
{
DWORD Status,TimeOut=10000000;
do
{
GetPortVal(0x66,&Status,1);
TimeOut --;
// Sleep(1);
}while((Status & 2) ==2 && TimeOut>0);
SetPortVal(0x66,(DWORD)Data,1);
}
void write62(unsigned char Data)
{
DWORD Status,TimeOut=10000000;
do
{
GetPortVal(0x66,&Status,1);
TimeOut --;
// Sleep(1);
}while((Status & 2) ==2 && TimeOut>0);
SetPortVal(0x62,(DWORD)Data,1);
}
unsigned char read62()
{
DWORD Status,Data,TimeOut=10000000;
do
{
GetPortVal(0x66,&Status,1);
TimeOut --;
// Sleep(1);
}while((Status & 1) ==0 && TimeOut>0);
GetPortVal(0x62,&Data,1);
return (unsigned char)Data;
}
unsigned char read_ec(unsigned char index)
{
write66(0x80);
write62(index);
return read62();
}
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ] 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ] 原帖由 海陆空 于 2010-2-6 19:40 发表 http://www.ufoit.com/bbs/images/common/back.gif
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢:handshake
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
3. Then set bit16 of the IRQ to disable it.
a.. Offset = IRQ# * 2 + 0x10;
b. Write Offset to APIC base,
c. Read Data from APIC base + 0x10;
d. Or bit16 to Data;
e. Write Data back to APIC base + 0x10;
You need to check APIC spec for details. 原帖由 Faintsnow 于 2010-2-9 16:41 发表 http://www.ufoit.com/bbs/images/common/back.gif
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
==============================================
:lol 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
当然正规的做法当然是要禁用SCI 我想说两个地方:
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
2、新手不要把EC Space和EC Ram space搞混了。在DOS下,ACPI中定义的EC Space是由OS发8x command给EC去访问的,这个访问到的地方,或许是EC Ram space一样,也许是另一块地方,也许是EC ram space中的某一块地方,这个要看EC自己的做法,平常我们所说的EC Space基本上就是ACPI中定议的EC Space. 讲得很好,哈哈,学习了
页:
[1]