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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
7 Y: R" f6 `& x2 u( b* r#include <Windows.h>  `: ^& _7 U  L- c* i" ?# X# J
#include "WinIo.h"
" s+ f: p( R2 P6 kusing namespace std;
3 ^3 X* S6 O8 f, I6 l3 x* R; q8 }  G0 Y' K5 |" f) ~. p
#pragma comment(lib, "winio.lib")& P5 I2 ~$ E, V: |3 u
7 D1 x- ^% O6 \5 B

; N; Y( |. H8 N' g8 lint PMU_SC                =        0x6C;//命令端口" o5 l; ^8 B# E% a
int PMU_DATA                =        0x68;//数据端口$ D0 k3 ^3 {: r- q
int RD_EC_SMI                =        0x80;//读寄存器命令
  q& I) x) F# e. J% C3 fint POLLING_DATA                =        0xE7;//CPU温度寄存器号
0 y3 s# s' v# T  C5 G
# U  c' Z! T$ fDWORD dwTemp = 0;* x+ O7 u/ |5 b$ z1 g; ^: P
$ a$ U4 n5 j$ s/ C5 _& ^# g
void PMU_Wait4IBE(DWORD *_value);! {! O4 W  w( I
void PMU_Wait4OBF(DWORD *_value);1 k/ v" \3 W1 n. N) b

4 I: x/ j8 @5 c, [- a2 y$ W, w
% @( D. T4 P3 G$ Q8 O6 R- ~int main(int argc, char* argv[])
% G- K+ C/ e3 a{
. p4 Z/ _! N0 u( K+ D        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
& g  W3 X& ]8 M- h( u; v$ Z7 J& a: n, S- e1 b# b6 U3 i7 m
        3 z7 f$ T- o. w& _0 ^
        //1、mov            dx,PMU_SC                //3 h$ j  b. X3 Y+ L% ?
        //2、mov            al,RD_EC_SMI        //1 N. M0 Z* E: l1 Y
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了8 u4 D, \; a0 f3 J7 `4 {
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。. I. i# s( t  b; {( |4 D! A

- @9 p( {' l) m3 n+ ?0 H        PMU_Wait4IBE(&dwTemp);0 W( C4 e4 S8 c; _
        + p7 B2 M9 {2 u* e- o
        SetPortVal(PMU_SC, RD_EC_SMI, 1);
8 Z4 i( o) u3 o! A8 x0 _- B. {5 p1 ^# t' E% ?
        PMU_Wait4IBE(&dwTemp);- a' f: @8 V$ m/ z
       
' N# m$ j1 Q! H9 j& E2 P6 g9 J* y. t        SetPortVal(PMU_DATA, POLLING_DATA, 1);
* d- s, \- w4 c3 [, l9 l) F& d
7 e/ ~3 i' Q, G/ z        PMU_Wait4IBE(&dwTemp);8 G" Q5 U# k% j( s+ d$ n0 `: f; k
* Z  h0 E, B! w/ _0 O: x* h' S$ N
        cout << dwTemp << endl;               
% \# s7 R- e* _3 [. n/ J
6 v1 z2 r: X( a- b- H2 n4 A        ShutdownWinIo();6 A: i4 F3 ]' ~" n7 g+ p

- j" |4 [. B6 `        system("pause");
; V( d$ O/ w, h* X& G* _. Z9 o5 D& u0 W$ Q8 M1 r
        return 0;
; Z. m6 S$ e2 t% v" d}
0 |+ z# T. |7 P) V) }
( A3 D/ i+ p" R  G1 rvoid PMU_Wait4IBE(DWORD *_value)
& a; R9 z  |* G2 \0 M* ?{
$ {$ N: F, ]( @. \1 [; b4 }) i" u        //#########################################################   
* r$ H! B) N/ Z        /*
9 @$ t! x: S3 {) k% \        pmuWait4IBE proc   . a7 |6 {; Y, S' S9 j
        PUSH        AX   
; c: R8 B6 S" r) K        PW4IBE:               
* m+ E# b: h( H/ L        IN          AL,  06CH                                //Read  PMU  status   
0 V1 s% q% I- F* l$ g        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
' B% |. K6 V2 h8 _% B% }        JNZ         PW4IBE                                        //Jmp  if  no     e3 \& f# }( t, g1 D3 O. t+ k
        POP         AX   
& i+ h7 H; ?7 i1 U, V        ret   
) V: l( S% n; f        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE, T* n/ B2 [1 U+ d
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
& z0 u$ t7 f& a) K        //######################################################### : r# f- R9 s6 @) V1 l8 g
        /*do ; ?8 h& {1 t/ P) \5 z$ q
        {# f5 M/ S- g, g/ P3 a
                GetPortVal(PMU_SC, _value, 4);" H7 U6 k: A3 o! @: |  M6 q
        }
5 c$ o/ w! m0 \9 v5 _* r; F, z; a. x        while ( *(_value) & 0x00000001 );*/  ?) R* U  w' X0 n# u* s0 K
        DWORD   dwRegVal=0;) P' z( [5 ]% S% x
        do1 O; b8 J5 ^5 q) G  |; B8 j1 Z
        {  " _  W. n6 y* [4 w  J
                GetPortVal(PMU_SC,&dwRegVal,1);
( _: A+ W) E5 i0 S  ?! D        }
$ T  i1 j- I! b5 [% i/ j# F        while(dwRegVal!=0x2);
7 T1 W$ ]8 u. d0 @; Y) G$ l/ F3 T! B) m
}: L$ ]# O" O$ e
/ Y" y% Y& P' _, X  n6 N* ~$ u
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。  a. }2 C- A. o& R( k: |8 h
所以变成了死循环了。) K' u+ }: R; |) _; I+ J( s
; M7 f6 w" D9 O6 y
我对硬件编程不懂。又不知道从何下手。4 h; e$ Y. G( M5 F: y$ R
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。* Z5 H: D! i  ~  S, |0 l  K
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
% D7 H2 M. L+ J7 x7 z3 t$ a& N5 k/ Q3 _( D
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
+ V4 A3 t# D3 D" d& [: n并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
9 Z( q; y3 ^' ^3 }9 s' k1 O& v3 h# r  _0 N: E
感觉现在无从下手。我在网上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 d& [( @8 _, ]" I' H+ r9 U. g1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
" t# H0 k: x, U& r: M2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突8 y, D5 x3 J/ C' O) h8 Y
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.0 m' S. u+ }* C: B

* u5 {$ f6 k3 l$ ?! u所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
7 k. w$ g# F  y" N0 D
- K1 E" z! H. s那么有些什么可行的办法呢?( R4 \' N0 _2 P/ D# w0 C; K+ n  _
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。( w, g/ {  n' `+ T: t

; F* N# G$ o) Y& d. s它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?; }4 w, s6 A$ K
' E- i; Q. e- \
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
+ z9 I& N& V$ W) V9 z; ^: h" c- V* e# t( V  K9 p. l9 ]# x1 [
http://www.ufoit.com/bbs/viewthread.php?tid=452
& b! N0 K( `' `1 M0 O* F
7 `1 L' z3 v) k6 k2 y+ ghttp://www.ufoit.com/bbs/viewthread.php?tid=2416 _- k# |' b4 R. y$ [

4 W' }1 B' P& n6 _看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
5 V4 ?! j( D0 U. a& O' c. f, w
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。
8 ~* ?  ]- Y9 Z2、Driver最复杂,也需要BIOS配合,推荐。
: i+ k. a0 c5 w6 R  Y& i3、Windows API只能获取到特定信息,不需要特定的BIOS配合。/ ?2 ]) C$ u  g+ G- G( y7 I
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。/ S3 S& q7 R1 z
你可以混合使用。9 o" d. s9 L- }& ^+ ~- ~

' |+ z) ]+ I7 b! ?' C4 u& d  j===============================================================6 w! n# Z' @' C
管理员的这句话:5 k- Z- B8 D1 D, a
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?; q6 F  B# k: g) J

  N, D" \% x9 f4 b; i) `予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵# o# y4 V; y7 E7 k) Q
+ e( F7 E! L* b( E3 q
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
, }) p9 l3 f1 K4 F& \2 S) b* D" ?, E) w# ?6 y: j$ m* M1 H
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?( |+ ?; [* I' T
; w7 e- G  W* m% V
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。' l/ ~$ {4 U7 o8 W! u8 r
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?6 e% ?( X3 u4 F! b

) X. @/ }; S5 r. e我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
4 F' B0 ^! l1 h4 L5 j2 h1 A0 ~你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
, U) l! m' V" {( F6 O# f1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

: R0 }4 i& p4 p  y$ ]' W/ y2 q# o( h3 s2 ^
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。6 M3 H. P# [% J2 Q& S

2 @9 A* H; V, C! N) P& B3 `' mvoid write66(unsigned char Data)' m8 p2 S, Z; m
{
$ \: ^  @& b! N/ h        DWORD Status,TimeOut=10000000;" H9 d% z; j- V& w
        do. K6 t, Y  N, l) q$ t
        {8 y) b$ j# D, ?2 Y9 G
                GetPortVal(0x66,&Status,1);
, T! K/ d% E, L2 S* c' N                TimeOut --;
# V9 X' a5 D  g+ p0 G//                Sleep(1);
9 _6 V; U+ D1 o' I/ o; @        }while((Status & 2) ==2 && TimeOut>0);
' Y4 B5 l4 S7 |0 R6 M
/ F/ Y. F% t2 W        SetPortVal(0x66,(DWORD)Data,1);
' t" x2 E" z, k: m( i' {}- O5 M4 {3 Q* r0 q: I  ?! o
void write62(unsigned char Data)
  a2 X% j8 h' B6 Q+ {: C{9 P# |( n$ u7 x1 b
        DWORD Status,TimeOut=10000000;
/ h* c/ z5 `* u% g: t        do
: o' R5 n/ e* d        {
3 W' B7 [( f2 s% _$ E                GetPortVal(0x66,&Status,1);
! E. U& o+ H8 B2 c                TimeOut --;
" y' ^$ o9 M* e8 V% ~//                Sleep(1);6 k4 r% C" Z6 A4 b8 Z; y
        }while((Status & 2) ==2 && TimeOut>0);, u6 `% ?$ O1 r  P
/ z$ @. [1 Z! H% u! w
        SetPortVal(0x62,(DWORD)Data,1);
0 u( Y1 n0 R7 s9 T}
, v8 R& X& G4 `3 Q+ Bunsigned char read62(); m$ n# \# C# W# E. h
{8 ]! B) Q  N7 h5 g
        DWORD Status,Data,TimeOut=10000000;: o* s! N4 }$ p, ^3 E0 e9 t
        do
6 p4 I$ @# z* H" X1 v        {* y; }2 L/ d. l3 c- J7 `, |& W
                GetPortVal(0x66,&Status,1);- ?6 d( Z7 H* U/ n7 a" k2 u
                TimeOut --;
3 B: k4 S8 {- i//                Sleep(1);( V2 x! _0 X/ C# f$ A+ v' d: G( m
        }while((Status & 1) ==0 && TimeOut>0);
& U7 r+ h7 O8 [7 @  q  L3 Z1 H4 @9 d$ S7 M* t1 B7 \% a; G
$ @5 f& {( L8 K7 S  m
        GetPortVal(0x62,&Data,1);& L& d4 g( J, a0 Z+ G$ j
        return (unsigned char)Data;
4 @$ O; W2 P1 c9 ^, f% [}
4 \* a$ J- }, a6 k' i" ounsigned char read_ec(unsigned char index)
0 [) z# C* ]$ S{, `$ d5 t- D' k0 d; a  h& \
        write66(0x80);9 T5 g! |" l: Q% e/ E3 ~
        write62(index);
# f+ W' H- a. u7 i' X        return read62();1 p( a" o- p% C' H& ~9 |# U9 n
}$ B4 i) C1 K; @, D4 Y% e

# F0 S; U* r$ C[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1154) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
. P) Q7 t" J( S6 m. [+ N' r: W" c  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。, V; J6 V2 z) n; _( d9 \
4 ^1 r# J4 G  i: [! y  z
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
; L6 B4 h3 U2 q  u' u
8 |' t' i  N8 b" X) d  k+ d' x1 v+ j
* E9 B. y+ n! G- T  s5 t您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
7 M9 @# F: s- Z$ J9 y

  Z/ x! V: A% @+ H1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,+ e1 g/ q7 ?7 `/ v( ~# U3 M

- t3 p. f, v$ l& ~3 Q2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
+ P9 F! W% }3 o4 a) l' Y, U. c. E  L; N: j7 w
3. Then set bit16 of the IRQ to disable it.% f% J( ?# T6 `" G7 @+ s
6 \; y6 U0 P1 V; Y) B! r
    a.. Offset = IRQ# * 2 + 0x10;
2 G. {  a3 V1 b3 h# o6 W
9 \9 Z. Q: p" [9 m. R    b. Write Offset to APIC base,
. p* A4 B( @7 e# |; y& X$ ?! W7 b  q- A" c/ d. Y; v, u0 ?( `
    c. Read Data from APIC base + 0x10;
9 G& P2 m! T* w- j% `' b! L& L  k: \5 P% S5 r3 \  U2 b3 d" ]$ j
    d. Or bit16 to Data;
) O/ L  r/ a+ k: C, @; D: ]
  m% B- a* ^+ |# N; x    e. Write Data back to APIC base + 0x10;
: p$ G, H3 ~$ d4 {. ^7 ~) k5 M
9 ~% e1 i, F, Y   L8 p$ m2 C+ P

0 E; c7 ^3 w1 }3 oYou need to check APIC spec for details.
回复

使用道具 举报

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

5 r. p' t( J* I, n2 {. h5 V, [3 M+ p6 j+ Q+ o4 T. V
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
9 _* X" _) E7 k==============================================
, n# E: z, G0 U; @ 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
! \! H: ?0 R- a0 ?& ^8 A/ s
; A) c6 `1 _5 Q$ Q$ a因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)2 V. m6 F* Y0 h: a
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。2 H" E1 D3 u6 {8 ?* Q  z, R: C
7 ~6 l! Q* ^4 S
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。; j8 s3 q1 i8 B7 d
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:; q* B. \: W0 J5 t2 E1 K! M/ s* D- ?' ?
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。! {* a) q7 `! _; h+ O5 G9 z! N
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-6-14 05:10 , Processed in 0.060173 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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