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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
! z# D# L# S! V; p#include <Windows.h>
( D9 S4 Y4 T7 M- Z#include "WinIo.h"
) ^+ v+ c4 }+ K. J6 R' K- `; [" ousing namespace std;' |% t2 ]# P6 Q
% D0 G( s- w- s9 j; }3 o- ?
#pragma comment(lib, "winio.lib")  I5 }( \) d4 ~: O$ H( f- }! [

+ e: U1 u" e% ?, h( X% @0 F0 C& C$ h& d' e4 P
int PMU_SC                =        0x6C;//命令端口
  }( ]2 i! G$ Z; Z# u! zint PMU_DATA                =        0x68;//数据端口2 `4 `! d- U+ _; D
int RD_EC_SMI                =        0x80;//读寄存器命令
* D1 f# X" J3 F( v! \" mint POLLING_DATA                =        0xE7;//CPU温度寄存器号
" ^; {4 i. ?: u4 {
5 y, t! Y7 U3 \DWORD dwTemp = 0;0 s+ A6 l0 m& F% ?+ y" |3 M" y
' V3 {" [2 K# M4 ?; D
void PMU_Wait4IBE(DWORD *_value);2 R. i: f# ?. w, w4 B
void PMU_Wait4OBF(DWORD *_value);# H8 T% K! D" K! D& j/ F; f

0 r: q# F0 b- c4 R4 ]; K# {2 l. x% r
int main(int argc, char* argv[])
/ [' ]1 H! t. x& K2 h{$ r4 R  A8 K! w/ q  c1 l' H
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
8 z! x1 E$ u6 G  }- P2 ~
3 |5 n7 E3 ^' ]( w0 M        - m! E( k. l# e4 n
        //1、mov            dx,PMU_SC                //% V3 [& F/ A" V( V
        //2、mov            al,RD_EC_SMI        //
* C" p" _; s- {, K* Q; m# E4 a        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
1 ]% ?! M7 m" h7 z3 }" k7 Z3 I, N) Y* \        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
$ d" Y! Q5 w4 |$ T' l6 O! C0 C/ i/ G2 \1 J1 l
        PMU_Wait4IBE(&dwTemp);
. l8 y) |- O5 @7 u' B4 W       
/ Q( Y+ b' Y# i        SetPortVal(PMU_SC, RD_EC_SMI, 1);
2 N6 j: v  C8 o  @" z# R6 E$ V. Z# |- E: {; o
        PMU_Wait4IBE(&dwTemp);/ u, I9 o/ @& H8 C
       
- k1 l% F  G3 X" ^        SetPortVal(PMU_DATA, POLLING_DATA, 1);
4 x' C7 m2 ]' L1 Q
0 V' ~5 R3 f% g        PMU_Wait4IBE(&dwTemp);
$ N( V& w' C. K8 x$ g
- D0 D8 v: z' r4 b        cout << dwTemp << endl;               
5 g" f( Z* H7 x0 Q, E0 b$ u3 l
4 O3 {6 _6 g: Q& t6 l        ShutdownWinIo();# K* \  [' P) p/ k9 w7 V1 R$ y  h

+ h% @6 P4 v3 G: i& A6 S" C7 }% K1 ]5 i        system("pause");  X6 I1 s# o/ `6 o$ p4 `0 R3 w

4 V$ u- L4 ?% v- |) ~& z! e' j        return 0;
; b  A% L  e) q. [' E+ e9 U" g}
* h. c% w$ c8 K, M% j& U5 n4 O0 I* s/ T* @0 ^4 u+ b: y
void PMU_Wait4IBE(DWORD *_value)
( ?9 ?, b" u2 i" s# H' M* g1 E{4 r$ C$ J6 M+ h/ U- D+ N# y8 ^
        //#########################################################   
9 z8 R- H0 `% o        /*8 E2 n- ]5 B, Y
        pmuWait4IBE proc   + u: c5 H  V5 }- W* R) ^
        PUSH        AX   
# ~7 }" U! s( h; b9 a: t0 v        PW4IBE:                 R" H9 n$ @4 j0 A& T
        IN          AL,  06CH                                //Read  PMU  status   
' l6 h1 S) G. E        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   7 N! |# Y/ I% g$ I  k* N
        JNZ         PW4IBE                                        //Jmp  if  no   - _) u$ d/ ]3 t) N% B
        POP         AX   
+ A9 M: T3 i2 b2 w  f# Z7 p3 X' r. G        ret   . V8 }9 \5 ]0 }' |. S/ Z
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE3 K, o2 A6 x. z# T- y. E
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空. H8 n0 @9 n: E* z3 r4 P3 m
        //######################################################### " B4 c8 r/ h- L; R
        /*do
* x# w- Y$ [" a! L        {
* n; @& m) ~+ I                GetPortVal(PMU_SC, _value, 4);
) I4 ~& ?8 ]* ?5 B- V( X        }
: W7 ?* W2 X# W' Y        while ( *(_value) & 0x00000001 );*/
* r- `( Y( M% U+ g        DWORD   dwRegVal=0;
: e% v* |5 S/ |: h1 P4 b5 p; _        do. r+ E$ `7 B# t
        {  % O! {  R0 B0 }7 t
                GetPortVal(PMU_SC,&dwRegVal,1);8 t! ~2 j2 a% L# t3 ]0 h- S% t
        }
" _& h$ h  U+ ?, L) i+ f- ]        while(dwRegVal!=0x2);6 C" A) r) L8 p3 s
' r+ N. s, f! y* `3 }% G2 F% o! r+ Z
}
1 [* d; `2 f( t
% Q/ }7 d9 n# l# K' i9 R0 C- o以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
8 |! Q5 f8 U1 s/ t所以变成了死循环了。
+ q  N0 b  A" ~
- G( T* N! n! |3 c! P! s2 O我对硬件编程不懂。又不知道从何下手。6 v8 k2 I4 o+ P6 N5 K- i5 B# ^' `
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。& `4 i1 C% d/ F8 n  N! o7 o( p
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
" F4 H# D# F3 e# x! L* S' _. f) ]6 B8 [3 D
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。/ D) g0 g  G) }) F
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。0 z4 i% W/ v' p& b/ K* q2 Y

. r! o0 V$ ^! X' J5 b感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
! V% V' S- ^* a: w  e) F1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.7 g, c- o# d  e& ~
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突0 B) V) V& N" X% F# L5 U* c9 C
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
) w* Z0 t5 B0 _; Z& y% ]' \
2 G' C, W7 n$ c& P+ _. I% t所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
1 U/ b! z" V+ g/ O) \* ^( e5 J) k' e0 E* w1 h3 [
那么有些什么可行的办法呢?
: L0 l- v* C; `" z为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。: K6 [2 {8 }$ z; U' S: V2 [5 a

  m+ N4 W9 }" E* Q5 f" h9 Q2 B它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
7 o7 @. X% H0 s6 t) ~; O! M6 j& c& P: ?+ ~1 {2 x
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
6 m5 n8 R9 T, S4 Q0 b" v! A5 M  O
  y5 R" h6 k. n7 H" P, Ohttp://www.ufoit.com/bbs/viewthread.php?tid=452+ P3 o9 M4 o% [. ^0 O. L0 Q! ?
* h4 P0 d- A/ L- ^  [4 ?& Y
http://www.ufoit.com/bbs/viewthread.php?tid=241" A3 }3 t- O( h( L2 K4 E
+ Z! ~- V1 }5 B& R
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。! E6 t! y+ C- X9 k( ~# x
4 l  l; {" }( q! w
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。! j1 U# J1 |; I% _! Z- H& r+ d$ D) X
2、Driver最复杂,也需要BIOS配合,推荐。
7 s. G1 [' C: k' h3、Windows API只能获取到特定信息,不需要特定的BIOS配合。! F: u' q( O" ^& u
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
0 u1 o, i! H. c* @你可以混合使用。
/ Q% |: Q0 d% y0 @. t* J
1 m1 i4 d; s8 @6 Y& }% ]===============================================================: s' P, K2 J" ~3 m
管理员的这句话:
) r% M! |; K# t  Z2 o$ F; @如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
2 r5 t# \2 L; {. D : v/ X0 d% u5 c& d
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
0 i( j! U3 \$ p; W" b! r5 z  {* r. a; r. P9 j
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=2697 ~2 v  y( O$ b1 o* }

# k6 I( Q* _; j8 q4 h' Z8 z这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?, j1 t! E& x' Z: Q2 S0 k2 ?  Q

" n" Z# ^" A- ^  f2 k: f还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
7 d& Z; G. C# E, f" _  U0 O里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?; ?2 z3 R8 c" q# N& ^
1 N% N+ F# w# k4 a7 x, ?; A' h
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
8 n) @; c7 L9 V你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。3 H$ f: u$ ^" b$ F) e- V, H
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
5 k( s+ t$ |: q" z2 Q; o
/ S) A5 p- g; q& l
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
# {$ F. k8 Y% ^% U4 A# o3 K* Q# P! Z9 B$ {4 W* Y0 y0 g5 A9 t, P& `4 y; w
void write66(unsigned char Data)2 ]/ C- ]1 a" x5 f2 Y
{# Y$ p% P+ L- b5 B4 d& w
        DWORD Status,TimeOut=10000000;" K7 b# `& b9 A6 D+ Z8 b& M" O
        do: {* j$ G2 p7 y4 v
        {
; o) V8 x+ }4 z7 y( _2 M& q                GetPortVal(0x66,&Status,1);$ S1 C1 f6 w$ F: ]+ R' M3 W6 a
                TimeOut --;
! y. A* q+ o3 h0 B! j9 ~/ g) m3 T1 N3 J//                Sleep(1);
+ P4 t' U7 W! L        }while((Status & 2) ==2 && TimeOut>0);
) Q  _. F% N4 @+ n' H0 b" Z% B7 `; j' b) m  h% C8 k2 H# w2 S* ~
        SetPortVal(0x66,(DWORD)Data,1);
/ j% Q$ |  @2 R$ E}# v3 o7 X' Z. }/ g* g" t
void write62(unsigned char Data)7 n) T5 g2 h! y% ?/ W# |
{4 F% z) _  I7 g1 z7 `) I* ]. K
        DWORD Status,TimeOut=10000000;4 @/ A5 s" F0 {  i
        do
3 J4 h5 J( E5 m0 _0 F0 d        {* b6 {, R1 `) i! v% d- g& W+ D
                GetPortVal(0x66,&Status,1);
) A- E) y. Q6 H4 m; \, d                TimeOut --;
  f# R/ P' C$ c2 p! P  s//                Sleep(1);
  t5 V/ v; `2 `$ A2 j7 F        }while((Status & 2) ==2 && TimeOut>0);
; e6 R5 H, W  c  n: Q( S0 [3 o# I  H6 }1 G8 b& A( C
        SetPortVal(0x62,(DWORD)Data,1);
' k8 r# i' R! U4 I7 f, A}6 N, M! M2 j  s0 u1 C5 G! ]
unsigned char read62()
7 q" x/ G" g& l7 a( ~{: `. L7 x  R1 I' g& y
        DWORD Status,Data,TimeOut=10000000;
3 ?) K7 @3 L, B$ o+ v0 N$ r. f, L        do
* t) x8 E2 r6 U2 K        {) g0 R3 H' M# D6 R4 i
                GetPortVal(0x66,&Status,1);
) u  C# I; Z9 D                TimeOut --;
. w3 ~+ @- p1 s* s6 c+ V//                Sleep(1);
' L  f: H/ S& w5 W- R) n- s0 }" L9 ^        }while((Status & 1) ==0 && TimeOut>0);. u7 k7 J8 {7 q$ g+ f- |, b' Y

) d' c. ]  u* f7 Z" h% ^: R% L
1 H0 U) n0 f6 w        GetPortVal(0x62,&Data,1);
; j+ }6 q+ E& e        return (unsigned char)Data;
( J" z) w) c" s3 G}
' m9 F) ~; l$ z! {+ Xunsigned char read_ec(unsigned char index)
2 I" v( {4 B0 z' B* i$ |" ?# O{
/ P, `$ {/ x3 J$ |6 S7 x        write66(0x80);
" `8 D7 ^1 M' U        write62(index);5 `+ u( ?( Y, u9 ?+ U3 _
        return read62();1 k! R( A: d6 V1 A
}
& O, }4 f$ v+ X2 o9 q
" O- }8 U, J/ C4 D2 T9 Z: z" h[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1860) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。  o+ v* X. I( m$ x: Q0 U
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。$ U: W  R" f% Q9 c+ S3 E  c5 Z: D+ H7 G

1 S2 ]9 i- p+ I% P: q4 X# W( u[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 2 |) m0 Q/ w6 a' x( R
$ R2 i; H" I& k6 K. s

) l" |, X% H" @+ c& ]您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

6 b  v) S$ L8 c1 w. d/ t; ~' ~. t5 p$ O
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
+ X  K4 }% ]' u) C/ T4 b/ u" f" l0 W1 o2 |) o: D" u) G( H
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
7 i; Y4 ?  p7 I# h* n3 U4 b! x" w1 g4 k$ @$ o/ n
3. Then set bit16 of the IRQ to disable it.
5 K1 j; Q! J8 o2 |1 K. K; m6 L" [. \# G& u9 g8 x) h# P
    a.. Offset = IRQ# * 2 + 0x10;8 C  O8 k9 A1 Q% z6 H
+ x5 ~% Z2 f4 n1 ~' [1 `
    b. Write Offset to APIC base,; T0 g7 R- H  q* k1 k

- `0 u) C9 P; p3 H! v; E; p  z0 R: }- }3 _    c. Read Data from APIC base + 0x10;
1 ]* _: @" B6 ^( Y: Y& j$ M. H
& @- r! C/ C- a, ?9 `    d. Or bit16 to Data;
5 h* y  T2 ]5 U( R3 i
1 Q7 J4 @! m1 M% r    e. Write Data back to APIC base + 0x10;- M* U4 R( v2 Z, e1 k  [
; m. D  m  c4 z5 l; \) ]
7 G. [) H" ^! m
0 r4 Y" a% f6 U2 J2 S
You need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
( v8 {7 ^! g9 P" n% x# H. G545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
" Y4 c  p7 H/ k/ M

5 U5 E; O! @9 E/ ]$ g% a 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
# L2 K0 Q8 F* v5 i==============================================
) G$ K. V7 j2 h" m' o9 @( Y% Z 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
6 S' `) O5 C* A
7 _, d  `( ^+ G& s因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)3 [3 y# r' ]2 f6 E$ v3 }0 _
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。' a& g' }7 u$ F3 r

, X2 M+ [" g- W% v) k7 ~! Q因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。+ \4 j# }9 F- d4 V, S
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:2 I$ C! x. M& d; `1 A
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
" \4 G; b8 i; b1 t- R: p2、新手不要把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-8-11 17:56 , Processed in 0.979755 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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