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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>7 ~' P0 Q& G. M8 p& D  l4 y3 E) ]
#include <Windows.h>$ M! K4 Q0 K. V4 f
#include "WinIo.h"  b( ~5 m6 C/ O) x* D( D
using namespace std;
& {& o5 `& w+ A! C* w5 ?  s7 M) a6 G6 @; Z# Z7 N5 ^- X, c
#pragma comment(lib, "winio.lib")) |! o' f' U  [4 m: q
+ o; R# F' A* l: X% c

" W- Q2 L- X6 ^; [7 S- zint PMU_SC                =        0x6C;//命令端口4 H. D% T7 Z7 h7 h$ W( w- H
int PMU_DATA                =        0x68;//数据端口
/ K; \' s# E3 ~2 _3 l: B4 x( T8 j) z- }int RD_EC_SMI                =        0x80;//读寄存器命令3 A0 X, S6 q  @# h
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
& ?2 r. r0 z, Q# N5 S. E& C( s  S4 e( m4 p2 \3 S, G
DWORD dwTemp = 0;# P1 J+ S" L% O6 c

  k! ~3 M. w2 B7 [  bvoid PMU_Wait4IBE(DWORD *_value);/ K+ q9 ?+ }* m- J( X6 c
void PMU_Wait4OBF(DWORD *_value);
" T, p, B0 Q3 ^% ^1 g8 Y8 \4 r

! Q* T/ t( s; D7 z) z" p$ pint main(int argc, char* argv[])
  s- t* v6 o) ]9 s# Q# C0 y, T{$ n& N/ c, b% U. `
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;% _) h0 |' X5 r3 {* a2 r+ t

0 y1 ?; s4 d9 {+ Z. Z! A+ M0 ^* V       
* ?# l8 `1 j) L2 d        //1、mov            dx,PMU_SC                //1 {6 C6 ~* }0 Y6 a/ T: w5 F' K7 C
        //2、mov            al,RD_EC_SMI        //0 h+ H7 t: \6 c9 o4 T1 V
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
5 B' b( ^9 k7 ~        //4、out            dx,al                        //将读寄存器命令放到命令端口中。% A" Y, i! M3 F0 o
- g: h$ p/ [- J2 E+ C4 r8 S0 F' y
        PMU_Wait4IBE(&dwTemp);/ W3 Q& A0 _+ D4 C/ K* Q+ b
        # _2 S, w8 c# j8 P" ]" Y5 K
        SetPortVal(PMU_SC, RD_EC_SMI, 1);, K8 t  F  @8 B3 G& _8 b

( R: [! n# J" ^, {5 J" ^1 {3 ?        PMU_Wait4IBE(&dwTemp);
4 h- B% u% M* B( O' z2 K       
7 k* @$ H/ n$ B- Z, l# g8 V) [        SetPortVal(PMU_DATA, POLLING_DATA, 1);
2 ^6 _) b" T( {# M/ M( S+ ~0 H$ T% X0 I* ]
        PMU_Wait4IBE(&dwTemp);+ }, `7 @- @" F8 |8 R2 k
$ q6 e2 h: o+ z) X" F: a  U
        cout << dwTemp << endl;               
) H. j2 A5 Z) F# x
. h/ S: k8 w( `: N+ _" W% R- P7 j& t; [& C        ShutdownWinIo();$ m& D: ]/ D6 Y0 l
0 c. Q* t: G0 g  i5 m
        system("pause");9 b1 K8 j+ ]& ^% O

# a5 L- e, r6 D0 D3 l5 O7 M  i) m. a        return 0;
2 L" S. N( i  y}
( c2 W8 l, j; T8 Z; D! P
9 r6 }* j0 e; k6 dvoid PMU_Wait4IBE(DWORD *_value)* [" A. g& V. s! B/ Y& I
{
# D9 t0 l6 O* f4 m8 H3 T        //#########################################################   
% ?9 j6 G7 A; [# C8 V        /*
' v% y' Y& ?9 f        pmuWait4IBE proc   . g5 y- }$ ~# Y  {$ R
        PUSH        AX   ' Y3 ]2 `, U: G& a! M& E
        PW4IBE:               5 d5 p! w: V0 f: f* I  m2 N
        IN          AL,  06CH                                //Read  PMU  status   " ^; w% s: x, O: H+ v
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
) |* a' Z/ m4 M7 m        JNZ         PW4IBE                                        //Jmp  if  no   
) _. v" R8 h7 @7 ~        POP         AX   
& H% q$ f, r$ c* X7 S' Y  r        ret   
' u" _; \! M4 h        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE2 L1 {2 e, U: o0 w. e9 a8 ^
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空1 u; g/ j2 b8 t4 u
        //#########################################################
) i1 V( ^7 s; o' K        /*do # p" l  ~' C) U9 P; w( Z8 q
        {; r3 @, A3 Z) W+ p* J" O% S" [7 w
                GetPortVal(PMU_SC, _value, 4);
* h; z( X4 a  x( ~! _. ]1 A        }# z6 Q3 _2 f; r8 M
        while ( *(_value) & 0x00000001 );*/
' b/ Q8 e/ {% G6 W7 y* O. N        DWORD   dwRegVal=0;# O. t- n  m' h
        do
) h4 n) Q, t2 a8 ~* L" [        {  - N* D! o$ f; l9 Q5 ^% }3 a
                GetPortVal(PMU_SC,&dwRegVal,1);
* |( P7 [1 p8 s( w! }5 Z        }
( j  i% o4 Z3 b  N* s9 x, R- l        while(dwRegVal!=0x2);( V; O, U4 }. C/ i

+ d( x. ~, y6 j2 M}
! i* Y5 q0 \: g8 P- K* _. u+ N0 P# I: H# Q; R* A
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。; o+ L3 E( G& R" |+ W5 o, K
所以变成了死循环了。
- b3 R/ Q+ G5 Y( A5 {( X/ h& P5 D8 j
我对硬件编程不懂。又不知道从何下手。# s# [- m0 q4 p' }( V
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
0 F8 I1 y2 S# \; K1 L! a但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
4 c- f& Y# J/ \
$ H; E8 R, A% c5 S7 V我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
7 Y  ^( @  m/ ~% p+ N并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。. {' T3 {  Y! a
, @2 M# V2 s9 _% L, n
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。- ]8 X/ {* H. U  o9 x: ^
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.% M! O  _& w# T9 E$ m
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突  q& ]1 x% @" ~# q! W. d
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
' I( _: ^; e% ?$ A: g( H' U4 g: x& v* V5 _' w4 j0 f) ~: {
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
3 T- V* ~, O( C8 B( k7 e; ^+ j
) s; z! q9 g/ V' M4 l" p1 j那么有些什么可行的办法呢?4 }, Q/ C5 @* z! K
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。3 N2 {2 B" Q0 j+ N- R
$ X: }) u; `% I+ P! j
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
) ]/ Q' W0 F/ E9 R# E6 X& m
, n; s  x. O# b/ w7 B% R1 D) M* x) l那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420* s4 k( p, A/ e6 _* O: i. @

: s" I& R. [+ E2 H1 O& Dhttp://www.ufoit.com/bbs/viewthread.php?tid=452, q  F4 f) w" G7 F7 s) F" i: o

' P8 g- S* c  }" p9 |; B6 I+ W; Jhttp://www.ufoit.com/bbs/viewthread.php?tid=241
( n1 D! m  q2 V9 d  f
' q. E! e6 z9 V( j$ F: K0 Z看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
( e* ~1 _5 C4 Y+ K
% Q, y4 G+ n0 _+ E6 `+ J1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
2 ~9 T7 h: ?- x. S3 j& Y2、Driver最复杂,也需要BIOS配合,推荐。
2 I/ U9 f$ L- s) Z- L7 e* t. V9 i3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
, _' r, W/ `) {4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。2 L3 a! P- N, Q0 H9 D1 h. I
你可以混合使用。
3 H! [! V. d  a) n& W
' }- g. L) a- ]) k' w; j===============================================================
6 m3 X, w0 k0 D; k6 ~管理员的这句话:: D5 i( t  V2 S6 L
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?% L% m6 V/ X* |1 }
1 e" U/ L3 i% w; s
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
+ B. R) N/ @  l/ ~! {- \; q4 T! J" A! e' U6 @3 R6 |
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
( R0 Q+ v2 |, v# w0 E$ q$ b$ T5 t( g. }5 G$ O% E- W
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
2 J1 s4 t# q  C0 s' v2 A
7 p7 n9 g1 s" p  B2 g3 e# E0 R还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
3 _) s+ n( @- x3 G里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
& T, z9 s1 Q1 C
6 Q' W0 t/ }. A( _我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 ) @5 h. z9 Z& O! W- E9 s
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。4 M  L+ c& C; Q, {: C8 o
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

% A: q9 _7 e- z  w6 d* R/ n# a2 I( u6 B+ _4 R( m5 k! o. Z
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
3 f! S+ Y: K+ t- t# b& n6 q8 A& @' c3 t2 w$ [7 ?* m" K
void write66(unsigned char Data)
' {4 H4 K5 m" R9 _+ ]' X8 y{
. y. p8 l5 x1 _) e/ b6 j        DWORD Status,TimeOut=10000000;$ M7 j: {) ]% M
        do# n  Y. y* }+ t: ]3 V% l( k
        {/ M4 X/ o$ V1 W( L2 P/ I& R
                GetPortVal(0x66,&Status,1);9 O3 D7 T. b6 u' z% d3 @3 Q; q
                TimeOut --;( ~+ ~4 ?7 p; F- |
//                Sleep(1);
7 A) T, U: L" Y( G& u$ z* g0 [        }while((Status & 2) ==2 && TimeOut>0);6 @7 w6 Z8 p+ Z$ y$ L% Y' Q. h) z9 A
  o6 ?0 l0 M5 ^; l# T2 n8 i
        SetPortVal(0x66,(DWORD)Data,1);
8 r1 k; E8 `/ n) a/ ~, x}
3 P9 X7 A7 h3 y& Q9 mvoid write62(unsigned char Data)' f9 k- ~8 t2 {! l9 n* t6 \& S
{$ c( u* X6 U6 n* s
        DWORD Status,TimeOut=10000000;
- {3 \; \$ ^! @) r+ g5 J( N- z        do  m) M/ O+ i7 z4 c& }" |
        {# ~! C1 s1 g% n. j6 o
                GetPortVal(0x66,&Status,1);
' g, s% M) S0 f' I                TimeOut --;
' L8 m' n6 L& s8 y& W" J: Z//                Sleep(1);. _8 l1 N% h+ i% v
        }while((Status & 2) ==2 && TimeOut>0);' D/ B+ `5 Y7 A5 `) N' o" R
) }5 V, e( a! m
        SetPortVal(0x62,(DWORD)Data,1);  a2 ~0 }  I$ c2 f$ o- i
}
- Q; r, ?9 B5 S7 b( j( @unsigned char read62()
) M/ y7 K, B( ]: F, N* {8 m{
) l2 H+ z" N+ o! a, ]* A& M        DWORD Status,Data,TimeOut=10000000;
! m1 E: o! z' Q; d; g        do" U: f' b1 [) N
        {4 A- {, Q6 r3 e( w5 _
                GetPortVal(0x66,&Status,1);
1 v9 S1 q! a- H- F5 v  C5 V( L                TimeOut --;: @# I& B/ X3 T' `
//                Sleep(1);
2 ~2 w  b4 S1 c( _        }while((Status & 1) ==0 && TimeOut>0);
5 j* e2 R+ O8 ~. q: Y
6 p, X, ?  e5 t- X9 E9 y! k% b4 G6 K
        GetPortVal(0x62,&Data,1);) n  j+ G3 _1 s6 b) G$ r) u
        return (unsigned char)Data;% i& \9 B  y9 b9 `# N( R
}
4 F, I7 R" u' @  r6 b; v5 ~unsigned char read_ec(unsigned char index)' X% o1 t3 t! T
{! Y7 A* ]2 s/ a( L: ?! ~
        write66(0x80);
( S4 R( F/ ~- S4 Y        write62(index);
& M9 q: Z/ l5 t  q1 t* f! B+ p        return read62();
6 C3 X1 ?0 A5 A}
/ p: ?; J' _, \+ Y* b! S1 H" v' u3 Z- M, p+ A" X* h
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1470) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
7 W  |: B- e+ P% H5 x( k  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。9 |: Z% N# M8 ~' M/ H! v) I4 t5 I
$ X$ {6 X1 |7 J3 I5 N* P: u
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 - G8 z8 Y0 Z/ C- r. t# G  {

" |- M) ?* K) A7 m- W- r% I5 U! s: Y# g) C. ]4 {' C
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
" I! x2 K: ~: f8 M' r/ U& D# o

0 Y6 ~$ L# ~/ r. H2 N/ K. x1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
  \! N/ T- }. E- O; J. A( d8 A9 O; m$ z0 K
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.5 S, ^' f" j& Y5 z! [( t: ]
+ |' ]1 Y) V# U( g) s/ e; |  x; M
3. Then set bit16 of the IRQ to disable it.) N0 m$ v% g! X% e2 c( V  E3 k* J

# s2 z% S4 [0 U% L' C    a.. Offset = IRQ# * 2 + 0x10;
" T8 ]' ]8 T& P* p" O1 N6 ]; x8 `+ ^7 V4 e5 ?! P9 q5 d7 M
    b. Write Offset to APIC base,  {/ x& Y! D5 x8 K! a0 E* ^  y

! c0 Z5 H- M- o+ j( {1 \8 X& X0 q+ }    c. Read Data from APIC base + 0x10;
" K# a: \# J+ `; N6 N" R  ^
" n$ Q: E: T# n% j# z    d. Or bit16 to Data;
* L9 R2 ~0 |1 J* I3 ?  y
0 }+ _3 m& t, j7 ]* T    e. Write Data back to APIC base + 0x10;
/ z' z6 A, @7 h2 g2 x. C+ r( k( w( u6 ^/ b

* V# g/ E  A" e
0 x4 L* r/ f, e: c& d8 U2 O& bYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 0 D% m9 S: l- P! x) N1 S
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
7 u  P) q# _' i4 c$ m) _

; K+ u8 S7 V: M8 R. r# ?3 M 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
0 P  y9 ?5 V1 V3 F==============================================
- Y7 G! q1 G+ z 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。# X6 M8 B$ M- O$ E+ Y7 f' z7 ^& s) d

' Q5 a$ B/ `7 F! M* H0 ^因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)% q; `) x9 c5 F' F" E9 [
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。( ]  o% Q4 X! ^% a3 H) S

3 ^  ?( C  f! C7 P8 `) X1 [因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
; l, U5 B& P7 T2 ^* M  t5 d当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
9 v2 D: O. [7 E1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。- R* `6 K: d) \
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-1-18 21:20 , Processed in 0.096534 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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