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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>' n$ ~: {5 A2 e6 O5 F7 ?- x& \% Q
#include <Windows.h>* O+ x/ }! Q* _' p; _: Z. C
#include "WinIo.h"7 X# G4 m( D3 E; J
using namespace std;
6 H4 f0 [1 t) I5 T9 _" O$ o3 X( q$ H. ^% x# v
#pragma comment(lib, "winio.lib")
' H( u  i# w& S$ [8 x5 t! s' O) f! H4 F' R5 c' Y

5 L! \" t( g. _  Q% k/ a/ Sint PMU_SC                =        0x6C;//命令端口4 y/ y' a0 D, z7 z; i* d* S
int PMU_DATA                =        0x68;//数据端口
; L5 |7 ]" B. W* Fint RD_EC_SMI                =        0x80;//读寄存器命令9 v& O- f* J5 V" y, j. E6 u0 i  C1 z
int POLLING_DATA                =        0xE7;//CPU温度寄存器号7 r& M# d$ l/ a+ h1 T

# A; o# p1 _7 H0 g% U9 B6 P  ?DWORD dwTemp = 0;! A, E4 e7 {- J9 a  z# d8 R- b# V

. O2 s' N0 C( }; N) z1 \void PMU_Wait4IBE(DWORD *_value);
) U: ?% `; N# ^* c1 g0 H: |void PMU_Wait4OBF(DWORD *_value);4 n' c; X1 N2 `' H1 P& l# P

0 u. h* J* f2 {- r* |/ ?" H3 X% g7 X* }. L& f1 J, W( ~
int main(int argc, char* argv[])
# b5 u3 l8 [! J' P5 o6 n{
2 j" ]$ |( F9 x* c$ X: b        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
1 ]" T3 H  G  m  g$ S2 _% D
# J+ B. v+ l# C4 F- |        6 B3 _5 H8 F4 n# d) |+ D$ ~
        //1、mov            dx,PMU_SC                //
0 V6 v; c  a  o5 s4 Z' `        //2、mov            al,RD_EC_SMI        //
4 s! `2 r7 A1 \, u  {4 Y        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了, A0 s( m) m) H$ ~4 E6 T1 v! j
        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
3 a- k6 C: U0 o* ?5 E/ P% L/ B& J" W# N* E0 S
        PMU_Wait4IBE(&dwTemp);' P) |2 A$ n4 g, q+ l1 @# u
       
* S9 H# a( l: Y% F        SetPortVal(PMU_SC, RD_EC_SMI, 1);. Z4 m: i7 [( `/ P& S

# p: O& P1 J# G3 h        PMU_Wait4IBE(&dwTemp);# e6 G) {2 ?$ I, x4 W
       
7 o  J  z) u! u$ W5 t        SetPortVal(PMU_DATA, POLLING_DATA, 1);) W( h% c8 T4 f( S4 [/ K

& K1 P8 D7 F. c; [        PMU_Wait4IBE(&dwTemp);
$ m8 c/ r$ s3 r
* r' W2 l! q, H* [4 o, n        cout << dwTemp << endl;               
! q. E+ v( T5 M4 q* g0 G2 ]  b* u+ s0 @
        ShutdownWinIo();4 f7 p6 f* z* ^- C" F* e. E

% r3 p/ `7 K$ H: K2 B        system("pause");
; Z1 i% ]$ X3 W/ ~$ U0 e- l7 I$ R! {4 V! |1 c" L4 M. P
        return 0;
, D& y4 p7 i) C8 m, j}) F. _6 W7 {; w9 H* @

8 Z0 G( o8 c' x) m6 v2 @void PMU_Wait4IBE(DWORD *_value)
, |0 P* y1 Y% E6 n- Y- ~3 b{8 K0 Z9 d4 r' C
        //#########################################################   ; B$ z- I& v( A5 K6 M% M
        /*- J) v) G- L0 q' ?. m
        pmuWait4IBE proc   % V6 L+ t% X& s& A4 D. Y! j9 b1 P
        PUSH        AX   
/ i7 t0 w5 O7 R9 S        PW4IBE:               
: M! L) o* h  T        IN          AL,  06CH                                //Read  PMU  status   # H7 b0 a- ?( O9 p1 O' T! u! d5 t( m
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
! h$ G& g! X" _) u        JNZ         PW4IBE                                        //Jmp  if  no   
, K- Z# w" A; R& ?        POP         AX   
. H+ f- D" A$ O* |0 I) _8 Y' C        ret   , G% Z) E3 C1 g' A: h+ ]
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
' O$ z1 q; @/ R- K, u        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空4 N) b0 S; U* O( }
        //######################################################### ) C3 M$ A1 U: a  J: f) \( x* {
        /*do
. C- S* ~+ F& ~        {
5 R/ _+ a1 n( P# ?$ i! h6 E5 z                GetPortVal(PMU_SC, _value, 4);
* I3 @7 m4 R. G& Y6 z6 @* q        }
( g* X$ T& _5 J- ?* P# }# C4 ^' S        while ( *(_value) & 0x00000001 );*/
; v9 I% D) g* ]8 ]. u" s        DWORD   dwRegVal=0;
+ p+ t* S8 M: y; L- r$ Y        do
' f$ Z- }* u: }5 y7 W# H/ S        {  2 H) S+ b9 j6 ~9 t
                GetPortVal(PMU_SC,&dwRegVal,1);
& B6 K2 u& t$ D; W. i        }
, F' q0 F" ^. p) D9 o- v        while(dwRegVal!=0x2);4 V8 a2 f: |( o  o1 B. W$ \

1 W9 B0 X5 r7 ~( _/ c4 t" }. R. ^}
% e$ X" A' S+ W- y
8 D5 u, W6 t8 U# K" I) I以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
/ m8 h4 g* Z( y5 t所以变成了死循环了。; F3 v. o/ B9 y- X4 ~
! H, X. x# t9 B8 O0 H" _
我对硬件编程不懂。又不知道从何下手。+ |# B7 D$ ]! H% e1 y
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
+ V: N7 Z0 w$ A, N, [: T但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
) i6 l- P. _; C/ H2 ^) q
3 K* N6 }: `# {+ P- f$ P我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。6 c4 A7 M9 X! V9 c- I- N3 h% q
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。& |# T6 f/ x7 i- u

9 I3 p# S6 j, o4 z感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。; R1 e8 V2 c3 ]$ q8 T1 |
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
( |7 Q) |/ \1 c. @2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突) L- M" D, y9 y1 o; Z3 r3 F
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.4 K) i7 s4 W3 l+ i0 N

. C/ m& G6 N( q$ K所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
) T# }: t& G6 Y; u% {- O/ g! ~$ d4 y" D, V) X0 D
那么有些什么可行的办法呢?' I! R9 A+ A& Q
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。0 I5 d' h# o6 N' {% e
7 ^) W4 Z% r' h- N8 Y& p
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?) D4 I7 H7 n1 C( q2 W

3 [' @4 `* M6 L; R; n& H* ^2 a那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420, f) k) L" S' C" C1 j
! {( b9 R+ c( A% [5 S+ h' P- }0 M( {
http://www.ufoit.com/bbs/viewthread.php?tid=452; c# W! B& E5 s# d& z& l

) \0 w* m! I3 m. S* |4 chttp://www.ufoit.com/bbs/viewthread.php?tid=241, b( F( C# Z. n) Y3 t3 B0 R+ r

$ m0 f3 \! u9 \( s1 l6 E* m- {看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。5 }( O1 O5 ~$ p/ O8 l9 d- k
) O$ |: T! L+ h- u0 M
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。5 v# ^- m) C" t" w
2、Driver最复杂,也需要BIOS配合,推荐。
; q, \& I/ J! T  r4 m3、Windows API只能获取到特定信息,不需要特定的BIOS配合。0 V8 ]! x: R  z+ |9 t
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
" w8 s7 {, D# T% ~1 X, @% W& T# q& T你可以混合使用。  Y7 M3 x9 h) O: I$ N7 \

  O+ o6 q. |( Y===============================================================, U& R8 V! d3 }3 A
管理员的这句话:
4 e7 X/ I1 l4 G8 r3 J如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?6 f! {; e$ R5 s
% {+ D; s- q! L6 x
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
$ h! h' }" P7 b9 \- S5 O9 p9 O$ L6 _4 _/ C1 f
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269( e! t5 {3 @8 o0 j; |7 q" D
' W+ y, Z& ]0 o* a6 M( A0 v
这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?. c- F. R5 ]4 F7 {

4 H# d9 ?2 B3 W! n2 @7 J" W" _还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。  J, q% q, j7 k
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
% v% T: ~1 r; S& C3 ?
( ]" o2 B9 X5 z; N  m我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
/ V/ f! h5 D2 g% E: ]& A8 T1 K3 T你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
1 M) M8 Y4 x9 [" i  p$ C/ P1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
( `3 J5 U3 m. `
7 {! |9 t6 I4 S# X0 _+ u$ W3 y& p
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。* }$ J# ?" u- @- P* H8 _4 V

% w! V" S; `5 B. q2 Z# X& A0 r% Jvoid write66(unsigned char Data)' j& n  q2 @# ~; ~
{2 h$ o$ o+ K9 I9 |( `. F
        DWORD Status,TimeOut=10000000;8 ~8 Q6 k4 c8 }, f
        do: F! f% t  \. s, C5 C
        {
* f* a% U" \2 P                GetPortVal(0x66,&Status,1);( }& R/ p) J- h( P9 y6 @: s
                TimeOut --;
( Q% {2 u9 k9 b- a6 j+ o9 m//                Sleep(1);0 N8 o! A* [) `% @6 w
        }while((Status & 2) ==2 && TimeOut>0);1 P# p% \- k% W8 s6 ~3 j

) Z' `6 g3 s4 C7 k8 z' I" H        SetPortVal(0x66,(DWORD)Data,1);$ ?( a) e6 k5 |% I  d1 U
}
' r$ E+ W6 h: t3 _7 n4 vvoid write62(unsigned char Data)
( u3 ^- I% X. o  C; S  s{( g' n' Z7 d6 c7 l" P- m: t
        DWORD Status,TimeOut=10000000;* r# Q: t. Q8 M/ @0 _# g' S
        do
8 Q: v) ]6 ?5 Q: m. z% ?( d        {" h+ T) B( {- f
                GetPortVal(0x66,&Status,1);
  X; f: K7 ~  B  n" a                TimeOut --;6 L& C' G1 h2 v" R4 Y( N6 ]
//                Sleep(1);3 M3 r- |' D* T/ d; T$ W
        }while((Status & 2) ==2 && TimeOut>0);
9 M- I9 p& H- h( @, |
" I' _$ h+ }& O) \3 R9 \; }, Q0 j- w        SetPortVal(0x62,(DWORD)Data,1);
/ |3 L3 |- H- t, M" W: b}6 K  m+ B  q8 f- {3 `9 q/ v
unsigned char read62()" v  G+ _! I0 F: w9 ^6 m! E
{
  m! o) `! f: U5 ]0 C$ E        DWORD Status,Data,TimeOut=10000000;
; o: v5 U7 ]# T        do( d* n) S8 e8 m3 F
        {. F+ p5 D+ k0 o& H0 L& t
                GetPortVal(0x66,&Status,1);
0 q, }$ S7 {9 t) ]                TimeOut --;, w& z8 O! O. q* x
//                Sleep(1);; \) `( L$ r/ S2 F5 }0 s
        }while((Status & 1) ==0 && TimeOut>0);
& g# m# u' @: \- B6 O: F( x) F
( {( G+ y+ r) k+ I( ~2 M4 K+ M
        GetPortVal(0x62,&Data,1);
6 k. M0 w4 W9 V9 A4 N        return (unsigned char)Data;1 ]& p  ?5 l) h1 O5 h' j
}" |; O: S7 C+ D+ r% a2 O* Y
unsigned char read_ec(unsigned char index)# e$ f( ^4 J! x3 l( ~
{
' p' n3 L$ A; {3 L        write66(0x80);% I- e( G3 Z* j6 T) p7 ~
        write62(index);; U! M4 B# _5 |. }9 R
        return read62();3 ?: ~; i0 ]; @2 T# \
}
7 I( H9 b0 i0 H- V% I' P7 r# E' t* J
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1879) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。9 T7 m" {: g8 c1 W+ d! r
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
6 n2 q# D( W2 Y# p+ d5 L* R
+ ]/ d( W+ b% ]$ x! g( f% q0 X9 r[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 $ D  l4 X, b  y' d9 _1 d, ?( t, x7 b
. E: P! \, g1 J! N+ e2 ]
1 F3 V7 G" B6 v7 c; ?5 V0 W
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
! ~$ r8 ^# I& n2 c' S  I1 n7 `8 S/ c
9 |9 {+ r7 ?5 N& Y3 G4 \0 R
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,2 l7 h  ?+ Z8 k( G

. _6 _% ~  b+ z# P- }8 ?7 K  X2 ^2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
- O  t: g: a: L9 L% I: y
  b) ~" O3 j( H3 Y5 \) H, R  E3. Then set bit16 of the IRQ to disable it.6 _# d- v* {- c3 o# G; M& Y
; `8 ^4 ]1 _7 I( M4 b9 c4 L
    a.. Offset = IRQ# * 2 + 0x10;6 q5 m2 H; ~3 Y6 q2 n1 W

- n6 H5 }! r) S    b. Write Offset to APIC base,. z- t: x7 I+ O+ W* O% C

. F/ q9 f. a  f% `% C& E    c. Read Data from APIC base + 0x10;
+ [$ a" O4 p- d$ ~) Z' z5 D! H9 b6 [+ D. K
    d. Or bit16 to Data;
! s$ {2 e; ?% R
9 k; p/ e: G& j* g- ]  t    e. Write Data back to APIC base + 0x10;
3 Y, B5 Y* ~( S* S8 @  U. t9 J) @2 f/ b, B# m* k
/ S  d% n$ r, S  g: i$ o5 t9 Q

$ `6 i( L: V  G) `# M& f+ ?, w9 NYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 # S8 ?7 M! l0 M" I
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
1 @8 C/ a& C2 j% d( W4 u9 m) j

$ X* z. `+ j1 y7 ?6 v 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。/ v8 M: ^1 z$ D/ q% P
==============================================& G4 n" |" ~* [, a
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。0 _. S' J2 Z1 [0 ~1 w; J$ k9 |

7 Q# ?' I! M6 L1 a因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id), v8 n) U  [# n, K
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
8 O" L4 L$ k( I2 k6 G3 H# ]$ s7 Y* N; H, e# Y5 j1 Q
因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。7 h! Z) G! V1 q" B1 G! ?4 h
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
5 w* Q. q( u( g% O& p! X9 }1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。3 t% _+ k& `# a. L/ `) B
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-4-19 23:49 , Processed in 0.193393 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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