找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 35395|回复: 14

菜鸟的求助啊!关于winio 得到cpu温度

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
. t1 o% H" e' \#include <Windows.h>  w: \1 N7 D' O% g0 W6 R8 S
#include "WinIo.h"# b: L; z# |4 u% r7 d7 s! M
using namespace std;
; W6 P: U8 p6 v- Y  |3 R/ W9 @6 Y; h/ h0 @" A' y
#pragma comment(lib, "winio.lib")
# W( _- d. \! U8 v6 g5 F( I/ ]* l6 s& J& N
/ ~- h+ a- p' v8 q
int PMU_SC                =        0x6C;//命令端口% z; p( f! J) c( U$ P! o' _
int PMU_DATA                =        0x68;//数据端口# N* ^  z) O6 N! ?6 x3 [
int RD_EC_SMI                =        0x80;//读寄存器命令
- |  G2 B6 l" S& }/ N8 g6 dint POLLING_DATA                =        0xE7;//CPU温度寄存器号
0 F% v5 ]$ [, O
; H& R2 ], I8 ]7 l( d8 `8 MDWORD dwTemp = 0;
5 x! G5 U  m% \! w4 s6 ~: Z0 }! e! d( a% s: I2 x0 o
void PMU_Wait4IBE(DWORD *_value);
( g% u# G% a/ C+ t# a9 rvoid PMU_Wait4OBF(DWORD *_value);
$ g" P4 N0 d% ~% @
, o+ K% x! M- s  I! z* U) Q5 d9 P6 W; y
int main(int argc, char* argv[])
8 A4 }# S& V6 v: T$ H4 F{
0 [  Q3 z9 j6 c& ^        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
, H. ]5 c  P- L, G% _4 _" I3 p5 U4 ?) @* P* n
        ; g' F5 e# a, X3 B  {( A
        //1、mov            dx,PMU_SC                //6 `7 H- F& I4 ]' ~( H
        //2、mov            al,RD_EC_SMI        //) @5 C6 V- R" D
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了) v" k  D. \0 `
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。6 l; ]8 k) ?+ [- k6 q0 b
, I0 ~- @. S6 O. z
        PMU_Wait4IBE(&dwTemp);6 ~4 o7 M) d! O7 n
        * F* S0 {6 y* ^+ C4 \
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
7 g3 W9 Y* O; N" _  J( U4 s+ S
. g! l( u& ^! Z% m        PMU_Wait4IBE(&dwTemp);
& s& f0 r  z4 P5 N7 I        - ~# t1 K+ h8 }" {* n
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
9 t& A. O& j- x' Q, \/ v  o5 ^
+ V/ e, A% |5 I  T        PMU_Wait4IBE(&dwTemp);3 r; }; J5 m2 s2 W3 W+ U3 t8 G) ]
5 y* {0 z, E/ F2 \
        cout << dwTemp << endl;               
' E5 h" l! A" f
# u8 j# @7 z# u8 M$ A4 x& t        ShutdownWinIo();0 r( f4 Q3 y2 P

: b8 {9 }3 p* z: P' V        system("pause");
1 _  J1 A; f, g* ?* W0 d; ?$ y# X! C$ B$ Y" c: D
        return 0;8 w0 c7 D. P; K
}/ x; W3 A  @+ _% K7 B* K' K
; Q1 j6 t) ?* j9 |
void PMU_Wait4IBE(DWORD *_value). V2 g8 G; m, a
{
0 n2 M7 G" F0 V4 L        //#########################################################   
( s3 _  e( |3 a0 k2 X        /*
0 V( K4 {* b3 w9 s) B5 z5 o7 Y        pmuWait4IBE proc   . H4 S4 n8 f% l- m7 }
        PUSH        AX   
2 J  O. Y8 `. p# t        PW4IBE:               
% T; ?/ v  t+ g+ Q3 d/ x        IN          AL,  06CH                                //Read  PMU  status   1 S+ a3 o% T" @4 \6 w! S
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
9 l0 u5 V' R. N7 R1 e" B0 ?        JNZ         PW4IBE                                        //Jmp  if  no   ( W& F+ u# \- B7 W
        POP         AX   
6 }) z6 M; V+ m6 T& y        ret   7 b: _7 g* |0 c0 _
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
" X) f% c4 B- A        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空, p+ @$ t7 }3 n& D+ `0 |) {
        //#########################################################
0 U3 e% ^" o# E( X        /*do
" o& O& J0 p! K0 {        {; Q/ s" o3 n4 ]6 X6 O( m  I# h
                GetPortVal(PMU_SC, _value, 4);
4 \  C3 S# U# Q2 l; Z        }
2 S. I6 z' `2 f* n% `        while ( *(_value) & 0x00000001 );*/1 f$ G) J1 L4 N, z
        DWORD   dwRegVal=0;
5 x$ f2 Z% S( Z. Z  m  z3 [        do* ~6 I2 Z& ^5 F
        {  ( k8 E' [8 @% `& y
                GetPortVal(PMU_SC,&dwRegVal,1);
$ ~; z* u: C1 B! V+ c0 `        }; m$ I" t; z& E, p* g* F, t
        while(dwRegVal!=0x2);
3 h7 d6 R: g8 c. Z) G
: H8 ^/ l" ?4 L/ _9 Q" J}
4 h9 i% V$ L! T3 @# L; E5 j  _: [
4 f8 D2 ]! ?9 K$ _$ R, m, g以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
( o: K/ j" e2 M* E所以变成了死循环了。
, v: l$ H7 _) ]4 l* i/ w7 n" }
1 _# t' @2 `9 R  i$ k, |! g我对硬件编程不懂。又不知道从何下手。1 M' _8 K7 J. }" d& g3 Q3 g
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
; d; j5 o4 E3 ]  F, p( q/ T但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。6 D% ~& l9 h& c. E5 X
3 f: H  k# C+ Q$ V, \+ {
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
; T1 T4 b: L; [- L: x并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
+ {9 K; c8 a" t6 R( n
8 t$ ~* F5 T: C/ |6 W8 q感觉现在无从下手。我在网上google不到pmu的信息。比如说我想搞清楚0x6c到底是pmu的什么东西。我想这该有张表什么的吧?硬是没得。郎个办嘛?有哪位大侠给我指条明路吧!:
发表于 2010-2-6 12:02:36 | 显示全部楼层
这东西,底层实现是千差万别的。你如果没有主板的电路图的话,怎么知道温度这些东西是那种方式设计的? 一般的程序都是通过Windows的API读的
回复

使用道具 举报

发表于 2010-2-6 14:58:08 | 显示全部楼层
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
* T9 P3 x$ k5 e9 `' A6 g1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
% O) ?  T9 {7 k: t/ S- M2 F% R2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
* l, d6 o( P( e  J3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.+ w1 ]+ t1 @' o" G0 ?

# d& x! x( o( a. B+ S" |所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
) P. w0 k% t5 |# s- O8 B* u( s
% L" P; S: U2 E+ Z0 M- F那么有些什么可行的办法呢?) x( \& e3 e  M  j7 b) V
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
3 _; Y3 \& w1 U: F8 i* n
- @: C4 {- T2 {5 ~& y' h它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?9 y) P5 ?1 b; S( g! k' _- p
9 a' y% _; \+ r6 |6 |
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420# o0 ~  H1 Q6 C1 u

9 X2 C6 d9 W& E/ yhttp://www.ufoit.com/bbs/viewthread.php?tid=452
' D- M- _# j/ a; K
+ ?3 b+ a2 U. c# J% e  ^4 \$ Hhttp://www.ufoit.com/bbs/viewthread.php?tid=241
) b5 v- J8 T0 b3 b3 o' V2 @) R6 d5 l* V: Z- ^
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
1 x2 x( x8 f7 u/ y) D
/ k$ M+ i4 W, f1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
" t% {  ]/ f+ a# d" ~6 }2 c; x) g2、Driver最复杂,也需要BIOS配合,推荐。
2 A" z/ S: E/ w5 Z" v  j% i3、Windows API只能获取到特定信息,不需要特定的BIOS配合。2 k- @% V& i# E/ g
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。6 b8 O. l. S3 s( Q
你可以混合使用。
) l* x4 E- i2 w! ]! m- v& s) U6 P! E# U" {
===============================================================
; d/ I8 W% b0 r* m- m管理员的这句话:1 X: Q. @- G+ S2 ?- E' U. j
“如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?. c" V) H% j/ S9 R3 P
3 @3 [/ |6 A' B& s' D  O
“予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵/ W4 s& U5 ~6 f* O+ e. k

7 Y& d8 t- z, @3 [  C另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
. K1 y; q- D5 k" O  c( S- c
) `. |0 q" e4 C8 h( k4 B3 }这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?! D1 f2 F, ~  P# r+ t. T: u4 _% y
  Z8 C& h4 J9 x" o3 j9 u
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。7 h+ V7 @* s3 \
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
- T, N4 Y4 H, N8 h7 I' x3 O% Z" D4 Y0 z' k% r0 O' N
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
3 R! G1 q( N2 `2 C你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。/ H# j. C! t  }4 i
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
) m1 s& j- \$ |& q; ~* D

: |  m3 N4 p$ P6 m# j: d/ o- p# X您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

发表于 2010-2-8 09:25:24 | 显示全部楼层
找个APIC spec看看就知道了
回复

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
. @* e/ _4 L& k; D4 I
! g0 V* z! u! X% ?void write66(unsigned char Data)7 T4 k" x) B! o% \, }" e
{% S# e7 J$ H$ [8 F5 K
        DWORD Status,TimeOut=10000000;2 b8 }# e$ I$ [; f
        do6 w3 k" R& Y0 d2 `! q
        {: j7 c& J; f7 W; Z! e3 v# j' l2 J
                GetPortVal(0x66,&Status,1);
8 \, a5 h1 v* P                TimeOut --;* ^, v" n; |) D
//                Sleep(1);
4 C# R$ n: c* h/ W  X( ^        }while((Status & 2) ==2 && TimeOut>0);1 }$ M, T& Q: H. g  |. a
- h& j8 k% r" u7 r+ ~
        SetPortVal(0x66,(DWORD)Data,1);5 V3 G& n9 D8 F) g- S0 c
}4 l% n% T; Z6 s) v) _; C9 I
void write62(unsigned char Data)  L+ H2 V: p7 }
{
; I1 l" Y( }4 t. r        DWORD Status,TimeOut=10000000;2 ^) s6 D" j' q
        do
, D7 z& b& u9 D( L: a+ p        {
! v8 `  M# R2 x% O8 O                GetPortVal(0x66,&Status,1);% a4 M- ~' p8 J8 i/ }. J+ e. e
                TimeOut --;
, q1 d) u9 l  m8 n& U//                Sleep(1);
* X* Q" F  _! o& G% }. N% T        }while((Status & 2) ==2 && TimeOut>0);
) O" I; a, {+ T$ V; Q
3 U0 ?: n# ]- Q8 J) i  N5 A        SetPortVal(0x62,(DWORD)Data,1);3 \% J' }7 @8 C+ z
}% J! S# z) T, G1 [
unsigned char read62()4 J! V2 z8 o. ^# G. e
{, a; `4 Y4 [: F& e4 K
        DWORD Status,Data,TimeOut=10000000;. m. {; Q. H9 U4 c- X3 A' N/ s
        do. F  z" N- d  Y' J: B( s, q
        {8 O8 C8 S& n' o6 X( Q6 F# N6 q9 j6 P
                GetPortVal(0x66,&Status,1);
9 L3 h. s% u+ w                TimeOut --;! E! O: B1 C; z
//                Sleep(1);/ ?, S7 \0 |+ a! Z: A
        }while((Status & 1) ==0 && TimeOut>0);
+ M3 t- \5 n3 g, f. \5 ~$ L2 ^2 V' \% G) s- d

+ k3 {5 M+ b1 I. Q* V/ n        GetPortVal(0x62,&Data,1);
5 Z" u* M4 R& b, [8 ]        return (unsigned char)Data;6 [, j" h: g! H8 S; m8 S
}) d+ f" b5 m: y' k# k' {
unsigned char read_ec(unsigned char index)
5 p: Y7 F% ~0 ^1 {' s0 G6 F{
7 [2 `# u/ k' e! E  T! y        write66(0x80);3 {, |' r+ Q( V: w, Y5 u' _6 ]
        write62(index);* `( M4 x' k$ }0 t% R1 `
        return read62();
7 o( s8 `% r* D: L, o5 ?}: @. }# @  B1 b! u7 w# l3 G7 H
$ R: c% |  q7 N1 i1 N
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1904) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。1 G- D/ ^# O4 i3 ^+ d5 n
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。2 b& ?6 C9 N6 z, v1 q+ ?" L) R) P6 y

: [; r! @+ h4 N6 ^1 c[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 3 K+ R% `5 u$ x: s+ s

: s/ R6 c- g% g. E5 Q  F5 t, h$ D
# v4 @2 m1 P2 v, X, f, \% g& ^您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
1 }9 m6 W- H2 x  _$ u

( M, W) s/ i: F- H, }$ @+ F1 m1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
* z2 F" d# j- H  N# c3 w2 m* w$ ?
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9./ R8 C& p  o) G  R& l- b5 i8 }% [
: m( B; I; u( ?+ A
3. Then set bit16 of the IRQ to disable it.* D# B" F6 N# t$ P+ ?+ P

, x, M! w' @; g; M    a.. Offset = IRQ# * 2 + 0x10;; f/ X2 n5 j7 A) O6 ~9 T5 |& P
3 A  h4 Z* a- q  q6 s
    b. Write Offset to APIC base,
9 j6 E) a+ m9 F; F$ n( X
. q( ~; [  P; X+ z2 N% |4 Y6 g! R    c. Read Data from APIC base + 0x10;
$ ^* v# o0 b# {
+ U# q# n% z5 f3 Z: W: {8 O4 {    d. Or bit16 to Data;9 o6 N1 R% `  W: g- `9 K
3 J/ t" @) t% \# F3 b
    e. Write Data back to APIC base + 0x10;$ w. X: k0 }( Q6 L* p
7 g8 H, B0 }, m( u$ F$ J' g% v
. P& q8 l: s* Q7 F4 c7 b
$ f) R- \4 |. \! o, e' P% y1 ?
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
$ }3 K% |6 D3 M' J, ]) J545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
0 ^3 ], p$ [7 D$ t
. p. F+ k0 y. C* G
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
( t% ]7 o" M- S2 f/ @==============================================
5 M5 A' D; G) i. g2 t 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。2 x( m0 Y3 c; I0 E2 K9 ?

0 `, i7 K/ v& j9 E! w' v3 k! t因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
' |& N# E+ f/ @: M0 D4 z6 e但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。& s* U5 }5 q1 H
! c& d; d7 j' U, [8 b
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
. }8 h) D8 f) v当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
( _* h! x% k/ R2 N' o2 Q1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。. ]5 q* u+ y. `
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.
回复

使用道具 举报

发表于 2010-5-14 20:38:27 | 显示全部楼层
讲得很好,哈哈,学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2026-10-12 08:08 , Processed in 0.055289 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表