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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
5 z' R, |3 }; o# A3 H#include <Windows.h>
$ n' \! C/ t( d: O#include "WinIo.h"
5 o0 A+ r% G2 v. L) r1 _/ xusing namespace std;
8 i2 D) }- T: S/ @6 D5 }
5 r0 n% ?6 [4 L' B  \#pragma comment(lib, "winio.lib")
4 H9 V2 ?2 f; H# Y) A( q) ~- _9 G. b) D$ A4 o5 K

. s7 B0 P6 o/ I6 O4 `4 v2 U9 Pint PMU_SC                =        0x6C;//命令端口, {3 ?7 G' H2 _7 p) F# r2 n) e
int PMU_DATA                =        0x68;//数据端口) E0 A% ?. G' V  e4 R) B! h. ?; S
int RD_EC_SMI                =        0x80;//读寄存器命令/ F7 R$ Q# t/ D
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
3 r5 n$ v7 R- b$ a# ~
- Q0 ?; @+ F/ Z0 iDWORD dwTemp = 0;  u3 k5 B; p' H: d
( t$ d! g4 r/ x' X) x, g! y( W
void PMU_Wait4IBE(DWORD *_value);: m2 D( m3 ^( i7 K/ ^; K3 \$ ~
void PMU_Wait4OBF(DWORD *_value);
/ c: f1 A) d" m  k( y, \% Y- |" v6 O( {" H& @7 Z, I
7 L9 U: k* x; @! I: k& k
int main(int argc, char* argv[])
- q. N! Z8 r. V4 i2 i4 {8 s' i{
& F3 D- p' k7 u  D. \5 D        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;9 O' }  f* s/ _- q5 p
" F# T3 M: J; P' k
       
7 {9 M8 J/ e- Z9 g. U        //1、mov            dx,PMU_SC                //9 {1 _9 n0 c0 i1 v
        //2、mov            al,RD_EC_SMI        //4 `+ \5 o; w5 w3 Z! J
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了; w# `1 b5 ]/ F& p; N- N- m& j9 _2 n9 X
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。) @  m/ v4 f  Z7 K+ Z

+ w) _/ u7 R% m% V        PMU_Wait4IBE(&dwTemp);9 [. Y. d" Z* D+ D: D- I
       
7 U- d  }1 R& G" T+ T1 @        SetPortVal(PMU_SC, RD_EC_SMI, 1);, `5 t8 h9 @( J  H2 z. _7 H
4 ]/ T# M6 X4 {
        PMU_Wait4IBE(&dwTemp);
, g: l  Y4 |9 A0 T       
+ t) E" H6 X0 i1 D4 W0 ~. _4 h        SetPortVal(PMU_DATA, POLLING_DATA, 1);
8 K$ ~$ L. H$ O& Z' x/ \- ?
$ H% w. q+ I; N1 n        PMU_Wait4IBE(&dwTemp);
0 m. q* r- [* t/ d+ l
) ^3 l# J) s( R4 \$ F$ G; o! s" V. j        cout << dwTemp << endl;               
9 p" t, F2 y. s) f( U+ k4 K
" d, W) ~/ _: C* l3 Z& r        ShutdownWinIo();
  T4 D6 n! ]% E8 w  F5 [2 W& m# W  z3 N: a7 `
        system("pause");
7 S: S1 [7 y9 x' E* O( M7 V! s7 v# N" q6 s3 ~# p1 }. C
        return 0;
% F+ j% J9 F& o}) e' D5 f* y/ a( q- c! c; p4 J/ @

4 t# t; W7 z8 n$ D7 x  J% b' rvoid PMU_Wait4IBE(DWORD *_value)2 E8 S7 u! T0 v& z9 }" C# M
{' L& M0 u% _0 A: y1 y8 [
        //#########################################################   ! @  H& l+ D4 _6 b. M: Y1 ^
        /*
% l( v* e0 Q# b" g% t& B; t8 q        pmuWait4IBE proc     p- ~; h& b2 _( L# C
        PUSH        AX   
+ Y8 u% O2 D; R  h& l! I/ l        PW4IBE:               
, u" l' i4 n( p8 B! k/ ?        IN          AL,  06CH                                //Read  PMU  status   ! n* v9 W+ N( |  W" I
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   " H/ n/ x( D! M& [
        JNZ         PW4IBE                                        //Jmp  if  no   
5 y8 i6 I1 F3 C$ M" w3 Z        POP         AX   8 K. @/ K$ r  s9 x
        ret   
! B4 R) d. B# a; K( j        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE8 L5 _6 ]1 k+ _8 }& w* Y
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空$ I# a' q. E0 p
        //#########################################################
; m' Y5 I) \6 B1 O" ~0 ^        /*do ; S5 I! U+ i# N# h! t7 D6 g$ z
        {, }# A# X$ U; s; a
                GetPortVal(PMU_SC, _value, 4);
# }: e$ T* Q1 P) ^- Z' C        }
3 M6 @4 Q5 T4 f* @& m# y8 T        while ( *(_value) & 0x00000001 );*/6 S+ P9 y+ I& R. @9 L$ h3 t+ b7 t  W
        DWORD   dwRegVal=0;
) @+ A! a6 q2 [: a! g        do2 a6 F% M1 A. y) C0 j2 R7 z4 x
        {  
* r# K/ u# a. j) t- ]2 c& M                GetPortVal(PMU_SC,&dwRegVal,1);) I' T' i2 T* z9 m4 F0 g# y2 U0 D
        }) ]9 ?. U7 t- l$ l' Q# W
        while(dwRegVal!=0x2);
) S9 @! Y' P0 U( c, x2 a* ~' _1 V. H$ O$ n! W* V% C
}
% K  f7 S6 A: G& t4 J1 m: J
3 |8 n% R& Q' C以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。& S) _2 u. b, Y/ o" y: `- r
所以变成了死循环了。! C+ L  G5 U6 [* V: F- `
/ e  U) f3 \4 v) G$ L
我对硬件编程不懂。又不知道从何下手。" t0 D8 q: X4 Q3 q# w
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
/ i* g$ b. V* f3 P9 O+ A) x, |) e但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
( r, p2 f& S8 t0 g7 ~9 K* C/ k! i8 H! ^7 S8 V
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。. m& b5 P# Q( Q% i' T
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
3 r# J8 O- {0 K6 V( t
% a) G# z1 E% @- Z3 |7 r3 B6 m感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。3 ~5 `7 I% g4 O, O; i( [9 w
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.7 C7 P" h0 G7 T& x
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
% C& |) f7 n8 r7 a% ?- y3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.; n% Q4 h9 h6 U9 H4 A3 C" e
2 m7 C' m. ]6 L+ W( y  O
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
9 _7 W! T4 ?$ X* P' }4 N
' f0 g1 s! t0 d+ C9 l0 m. W那么有些什么可行的办法呢?. S& H: P1 e/ B! i
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。& |3 \  I. `/ I% O$ X9 G* r+ l
- J- `* F! [/ ]
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?. B8 e+ |% T& T, ~' g2 C( }9 h

" Q" ]) r: p$ x# O( J那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420" p9 M# K2 |' f. |
5 \+ n  q& z+ M3 r
http://www.ufoit.com/bbs/viewthread.php?tid=452
; J& M0 ?* i% i( |+ x3 X6 P- X! ~/ b/ M' H2 X( H( e
http://www.ufoit.com/bbs/viewthread.php?tid=2417 v' D, J! J5 @
" z. _4 n  w7 n% L. x! f
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。( F' V- q( S4 ~; F
6 F. d1 _7 `% V0 J# ]
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。8 t$ w' Q9 o* U; P
2、Driver最复杂,也需要BIOS配合,推荐。( n1 f  [2 A1 N% n5 S1 M
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
& x# ~8 P1 P8 ^- G4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
) k! q* Y! t0 r( _: |) x你可以混合使用。
  s9 k: d! I* P7 P4 R2 G$ u: l  C2 c+ H
===============================================================& F$ D, h/ `" P: R1 @
管理员的这句话:3 c4 o$ Z. P. E% a
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
  H! t; G  d  O( }6 L5 ], H+ n
8 o8 T' `, P3 N& f/ w予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
% n3 x8 u  h( W; M! g+ H5 ]& c5 Q; q! m7 O. r2 V2 ]
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
& V6 ?# @0 t! u6 j6 ?* `  D
# |" R3 a5 s. H$ p$ m这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?. Q4 B' x: A- d3 V- j

. j. A0 b  ~% i5 r3 O+ [- E还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
5 y$ g7 Y6 i; R# B2 K3 ?) t里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
  W2 V" D8 ^4 y
* f  O4 o, [9 S" e3 F我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
. G' z7 {2 v) z6 ?2 o你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。  J( J' |7 W: n3 A! f8 m
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
" R! Z$ J9 ^, w! D2 K- o% s, {
, b. z2 W9 v& `2 S
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
5 j# g: d  l6 X0 t/ i/ r" w; r# b, [9 m# {
void write66(unsigned char Data)
& p  ~4 n  D: d$ N{# h4 g+ F8 m, n8 W
        DWORD Status,TimeOut=10000000;
! ], B4 N$ Z5 a: D# r        do% B& [1 i+ x7 Y% n! u$ j
        {# R4 g4 D" m: d* f8 m2 l
                GetPortVal(0x66,&Status,1);. [  T+ T6 {- y4 x. U' v. A: q8 i; D
                TimeOut --;
) q, e* q7 G0 j& n//                Sleep(1);' `! i6 z' r8 T& [- N
        }while((Status & 2) ==2 && TimeOut>0);) G& Y4 I& v. K8 b7 j" ~& K

) Q, R2 n9 g8 m  @& `        SetPortVal(0x66,(DWORD)Data,1);9 Z, o- T$ @0 f: R5 E. Y
}
' B' o! x: s. K& d3 [& Q3 A$ gvoid write62(unsigned char Data)
: F5 w  X1 J# a{
0 E* O* H; S5 k9 @* @, ^        DWORD Status,TimeOut=10000000;  S# j( L  ?: z' P( F  h& Q9 n: ]
        do' R# M  z8 c; U2 I% k9 w; K+ l
        {0 M# A- m/ J$ o" B
                GetPortVal(0x66,&Status,1);4 X" ~0 z% p# R( F# F
                TimeOut --;
9 Y8 r$ {9 x! f8 Q; A" R) O//                Sleep(1);( l. \! s# K8 p- e
        }while((Status & 2) ==2 && TimeOut>0);" M. @" X3 y& B; S  I

( A- W" d4 l6 C4 u3 y" j        SetPortVal(0x62,(DWORD)Data,1);, ]; ]0 o# U* t( Z9 r  z3 V$ S
}- N( P7 e- [2 }( y7 _. U4 v3 q; Y
unsigned char read62()
( a% y( E7 M7 G7 N1 M9 {  [/ P* i{" v- g- V& y2 n8 l4 I
        DWORD Status,Data,TimeOut=10000000;
1 N- H# y) F9 }; P* B        do2 I$ F$ A. a5 P  y& R
        {2 q8 n. ^; p% y& S' y
                GetPortVal(0x66,&Status,1);
) ^2 J/ V" |. K; m( t+ M                TimeOut --;
% n2 k. ^+ h1 Z3 K2 W+ \; o//                Sleep(1);' _: @4 [$ u; @* |
        }while((Status & 1) ==0 && TimeOut>0);
0 e7 ~; q; |# i0 y
6 R" t4 v$ @" q3 q7 [6 j
7 |& @1 V$ j; ~        GetPortVal(0x62,&Data,1);
* u! g  `0 O/ ^5 O        return (unsigned char)Data;
5 F) j( d) J4 u. s2 A& Q}# z/ w5 @/ d1 U0 J
unsigned char read_ec(unsigned char index)& X" k$ O9 t- u: Y( W- K) D: k0 [4 E
{* f( @) Z& v. K# N5 }1 o8 s! `& z
        write66(0x80);+ Y9 y. n. T  X
        write62(index);
1 l+ \: C7 i; u7 |0 \& ]; N9 H        return read62();  o  B1 w8 o* G5 r) E0 |  H
}
* x7 m4 S- A" B3 T  i: L# W( L8 L( ^$ r$ ^) u2 ]0 o" `/ z; _
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
+ I3 Z5 a+ t  s- x" b/ ?
5 h5 @+ x$ s# g0 [5 Y3 S
- ^% f6 r' q  p/ K: \4 B+ |您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
& j" H" {: l  \9 c! A, H
5 i1 z+ d! M/ V* ?7 X" D+ }4 A, b+ O
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
; W4 j3 T5 f: i6 ~
/ K# R3 b9 K5 ?& y+ e& y  E; [2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
! B, `: z+ U/ P% A! S! d9 c* i9 ?8 e2 |# F8 m! j8 L
3. Then set bit16 of the IRQ to disable it.
3 P7 j* e" Q4 j; Q
3 r" l+ ~4 `; J5 J- G    a.. Offset = IRQ# * 2 + 0x10;
: e. h+ i* o. z( J9 k) r
% e( I; o0 p* J- W    b. Write Offset to APIC base,, u& k* s5 p+ h8 c& U5 @2 M
/ m4 N4 b4 B$ A+ R$ N
    c. Read Data from APIC base + 0x10;
+ `2 ~8 L1 B- s6 U" i5 I  ^
# \6 C* F+ c" S' Z    d. Or bit16 to Data;
8 P. q. a/ r% i4 V. E
+ c& x8 l) ~2 |* o    e. Write Data back to APIC base + 0x10;
8 f2 e/ P4 W/ U: |; E
1 u" y+ b( R9 A; K, p   B7 T; e( w% v& f) _

  x1 j" ~9 V- ]8 \. y. E6 k/ EYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 % F: A# c& C% A
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...

! ~- i6 P8 w% D! A. e" s( u/ p" |* {
3 |1 ?% ?- D* X8 |# O 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。( R+ v9 K  C% x+ L) M& N  V1 A
==============================================5 |8 M/ a: }9 O2 {8 ^2 L5 j7 I
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。3 o/ x1 h- r% O5 `; @/ s  s

4 U! w3 h" p) d* a" G* `2 ?因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)' |; l6 X7 P# P& f, u5 E9 \
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
; I6 h; T2 d8 ~1 D5 E( i. @
1 {  _5 P5 Q) T. Q7 a因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
' s/ B/ p, U  c$ G5 S当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
  i- l7 }; p( P6 O1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。) x: K9 o% t3 h0 r6 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, 2025-12-1 08:35 , Processed in 0.664170 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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