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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
; S: R* J" s* c$ i7 C6 V9 r8 t: `8 J#include <Windows.h>
) k& Z6 O3 ?9 ~#include "WinIo.h"
( a4 S* t8 X& @! pusing namespace std;! _& ^1 y# Y* b7 t3 H% e) z
: R4 S6 v3 L4 x* M6 c7 f( a
#pragma comment(lib, "winio.lib")+ n2 _! A/ s2 E: W2 G6 ?  }
8 {9 _* f9 M$ k- `4 p/ o9 H

" J$ C" d0 q( i+ i# j( g% O6 tint PMU_SC                =        0x6C;//命令端口3 b8 v& B/ |+ d, ?2 t$ K1 C
int PMU_DATA                =        0x68;//数据端口) c/ G" u% ]$ X) ?: a# e
int RD_EC_SMI                =        0x80;//读寄存器命令& |: @( J: o2 C& ?' q% Z
int POLLING_DATA                =        0xE7;//CPU温度寄存器号4 n- ^& D5 K8 I0 H1 b& g6 `8 P
  ]4 i; _- K" X1 Q$ ^% f! v
DWORD dwTemp = 0;; F/ ]+ S, \/ f1 u: Z1 `
* m% i" S5 @+ O+ Y4 N
void PMU_Wait4IBE(DWORD *_value);" f, X; |1 T4 v
void PMU_Wait4OBF(DWORD *_value);  Y- p( G6 W: m- d  q
* K1 ^4 }/ f& W1 ?- ?# j, ^) g
0 j, i3 b0 t. i
int main(int argc, char* argv[])3 ?6 N/ P' r7 L& M) ~
{
- F8 u( s# @$ B( {% C1 n, d2 X        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
! j1 |) ]2 ]* X0 {
/ K& L# h  M+ i) X( x       
$ ^0 f0 ~: P4 X  ?7 Z- F9 K$ p        //1、mov            dx,PMU_SC                //
5 {6 p6 M- Y7 w( }& D0 v+ v+ o        //2、mov            al,RD_EC_SMI        //
9 s2 u- l; V4 h- U. @. M' F        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
/ @. }+ H! q1 F3 j        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
4 ]( D( O5 R  F$ W' ?1 X  o+ _$ \8 Y$ T" _
        PMU_Wait4IBE(&dwTemp);) }% a0 Q- U% {, `; o* V
       
9 L: w: f. ^) z, |  c* C" Y3 e4 f        SetPortVal(PMU_SC, RD_EC_SMI, 1);+ b0 G" F8 O' [' _& c
! Z: z3 x$ Q9 f5 x# q" |% n
        PMU_Wait4IBE(&dwTemp);; _# c( D) }: g; t
       
" ~  Z1 S* ~+ j5 z# ]        SetPortVal(PMU_DATA, POLLING_DATA, 1);0 M+ ^- N& {: J) j# ~

7 R" k6 B) z. M5 ~/ D        PMU_Wait4IBE(&dwTemp);
: M7 F6 U9 W7 h2 ]* f6 Q
- ^4 E! i* ]5 {# F6 R        cout << dwTemp << endl;                . X8 z) u. R5 d$ |8 {

& H. K$ }! P/ g& g) k        ShutdownWinIo();
8 L. q$ Y/ a8 T, T( q5 `* l
) k1 C. b. o5 z9 P" a8 O        system("pause");9 e- t4 Q. S4 Z" C4 d" {4 W
3 m  d+ P" H/ O  R+ i+ I
        return 0;+ B0 }1 I( c# i4 V1 ]8 U
}
. n9 s# V7 e4 X2 b. e& q' B& C" A# R+ Y' ~
void PMU_Wait4IBE(DWORD *_value)$ J  A1 t8 a8 u+ u( Y$ q
{0 Z" [& G7 l6 f. i! t) e0 E
        //#########################################################   2 E* [- @8 g3 [5 p) g$ I5 d
        /*# B! {. J& d7 m) v1 {) K
        pmuWait4IBE proc   
2 g, z3 x7 L' k# ^        PUSH        AX   
, `( t$ g  k9 e; h% q# _' Z. Q  Q        PW4IBE:               3 I" I0 |9 B) h& w# Y& x: E
        IN          AL,  06CH                                //Read  PMU  status   
' i, \' j+ U* P8 _( Q" p        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   ( a  l4 i: ?9 @6 R3 h
        JNZ         PW4IBE                                        //Jmp  if  no   
: t3 T/ v/ H" V- _% h        POP         AX   $ s* @9 }! u5 Q) t7 z/ J
        ret   4 K$ b) j: O/ e& O$ P) K
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE9 X; R0 G& T9 U( ]! f* L% E0 k! W
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空. Y: Q2 ?( b0 a4 I; g0 a
        //#########################################################
6 {/ |$ c! }* _; A        /*do
0 u. Q; l+ ]3 J% \0 ]. G2 V1 g. o4 }        {
4 g  I6 }! r5 H5 h7 Q0 ~2 {                GetPortVal(PMU_SC, _value, 4);
* _; }4 Z+ R% h4 R; J        }3 o; @/ g7 n& a3 S
        while ( *(_value) & 0x00000001 );*/
2 k3 x& Q3 i# E! Y        DWORD   dwRegVal=0;
/ n' U+ i* s" r1 q9 F        do
8 n1 f6 l* W7 L. n' r: ?3 O        {  ; E$ t% S2 |( W! P: }' C% P2 Y
                GetPortVal(PMU_SC,&dwRegVal,1);
( Q- a5 c' H1 T' }/ f7 N* G4 e6 f        }; ~9 [8 ^3 o* C: H) N
        while(dwRegVal!=0x2);% z7 M8 I- @6 z  r: T- ^3 G
  N& \+ w; p  v8 n8 ?
}
; M% B' f( L4 m
0 O1 J' L8 b  X" e2 x) ~* E以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
! v, j5 q/ n+ A  [; O& H所以变成了死循环了。
6 o9 X3 J2 t; W* J6 f% R- P
# I, a8 p5 \; ]- K) [我对硬件编程不懂。又不知道从何下手。
( k9 d2 U  P7 J, ~% n我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。  B, u! Q# `4 u3 ^2 l% W0 B+ A" n
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。( e& z9 k  k9 v8 Q; I

* H0 J3 Q, o4 j# l4 Y9 [& c我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。+ w# H0 W( S9 p  [3 W8 I  O- \# v
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。
7 l6 F8 H7 d5 M$ r+ o! s# O- k5 ]" U% h( W) P% r
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
' {+ Q! ]- A  @2 p5 J1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.3 Y, D: T+ ~& |
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
: m/ l1 o. c4 B* M3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.$ D* f9 ?8 w5 r  {1 m5 x
/ {: m' Y3 m9 D
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
' H  i- b6 Q  Q5 Y. x& M
& u0 h: x+ K. J) i3 d那么有些什么可行的办法呢?& I) L  P. T, w5 C7 [, `2 A
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
$ X/ Y- t2 X% m9 N2 s9 O0 V9 R+ g( x& W, ]2 p* Y% B0 |  A
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?5 s" ~: W! t6 f2 ^! f5 m# h

. V( p) q2 S' T. ^0 E4 F' k那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
: Z4 o/ {; }8 @3 |
4 D, S6 ~, p( Shttp://www.ufoit.com/bbs/viewthread.php?tid=452
0 a- P. ^1 F9 R/ g5 b
# I, D; N( H" n) Whttp://www.ufoit.com/bbs/viewthread.php?tid=2415 s1 k# c+ G% M  L$ N

0 q8 `8 y  P, G# I看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

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

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
8 L5 j, ^! k& i2 T9 r3 j/ L
* Y. n! K) N* U' S1 G* R( D这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
" Y# l- W' V6 i6 S7 X, k( J
/ U& B# e7 S: F- b, \& p还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
% E1 ?( M" f! p+ u0 N. E$ Q' i里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?- R5 f) F9 V# P+ o# p4 z, H, F% G2 @2 g
/ e, H$ ~: \: N* q: E
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
% {  N+ h5 s% A9 i( S2 V你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。; Q, w# y; n* ]1 W8 d" V( m
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
7 f  z* J2 X3 Q( L8 |1 f1 x, q! m
# w9 J" `# W' b: R# |
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。  ?8 d+ ^3 C% x: R
" u8 `' L) ~* z+ |
void write66(unsigned char Data)
* f  ~( E; M( o# g) G) z" P{7 g  ?' g; K1 u$ p2 q+ Q! H
        DWORD Status,TimeOut=10000000;! W, U) Z- A* y8 J/ o
        do
" C& f+ v9 C4 O$ `( H        {% |7 v: L- b' S: C6 s2 v0 k
                GetPortVal(0x66,&Status,1);
* i! E# V6 o& Z                TimeOut --;7 [4 x# _, G2 z! k
//                Sleep(1);
4 R" A7 Z2 |* B$ R# i" R        }while((Status & 2) ==2 && TimeOut>0);" \/ [7 u$ D1 [6 _+ M# z
( j7 V! v, E" l# F- E( @, A9 _; l8 r
        SetPortVal(0x66,(DWORD)Data,1);
: ?2 H2 W0 S$ j. m( g, q0 l# }7 n( P2 G* z}8 d$ w1 u! U+ X$ _6 U$ {
void write62(unsigned char Data)
0 B7 Q6 V& x0 G9 A{1 n: X& ^, Z! [- R# x  W; d
        DWORD Status,TimeOut=10000000;9 d7 j: o0 I9 z/ [3 ]+ M, T6 r
        do$ r" ?$ {9 J; B; G' w' C
        {
6 W6 d8 W. x5 t$ g( {                GetPortVal(0x66,&Status,1);3 t7 |* z7 j3 D# A! U' j' z* N
                TimeOut --;6 X3 C) a. A: m
//                Sleep(1);
1 ?, y. T5 @. I! R+ B        }while((Status & 2) ==2 && TimeOut>0);2 n# I. y- }, q1 ]3 {3 X
# j' G3 c6 I9 I/ n. j" W6 F
        SetPortVal(0x62,(DWORD)Data,1);
: F. U3 d0 a% b+ U0 z$ v; a}  `( W+ T% {. L
unsigned char read62()9 K7 i3 ?) k* W3 l8 Q: x
{
$ H8 _$ F: _. S5 M        DWORD Status,Data,TimeOut=10000000;
% v, P* n0 H' z9 a        do
, u( A0 K8 H( D+ |        {
& m. A# ~" T& e; j4 m+ ]1 ^$ V  l+ N                GetPortVal(0x66,&Status,1);
" f. V" f  q* P                TimeOut --;9 _' a! G  B7 @* K6 l5 z
//                Sleep(1);
- h$ U. K3 y2 _  C5 v$ ~        }while((Status & 1) ==0 && TimeOut>0);# Q! @- R1 Y8 h) o$ N: j
3 Q+ T! N. \- b  K
: R# M. G1 n" B7 a) e! ?5 P* d
        GetPortVal(0x62,&Data,1);' d& Z* e( e3 f* k5 w
        return (unsigned char)Data;
0 D" W# h  E' k: V, i! j+ r}
* v' C' s  w9 ?3 @( \0 }unsigned char read_ec(unsigned char index)
6 e4 Y  F3 S) A* K{; G2 I0 V& j$ m& R" H4 p9 o
        write66(0x80);
* n# f+ @4 o$ K3 |3 X' }; g        write62(index);
$ N0 @% ?4 n0 \5 Q+ A$ p, L7 o8 e        return read62();
/ r5 _6 a' \( u$ l8 \}( y: e0 |' D" g" t
& k# x* \% u8 C: w: P! |. C! C
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

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

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 & j) W3 H& v2 w% C" ?% g2 q0 u5 E

. E& f% C- j6 Q; `/ o# f! X% ?$ Z) W1 }  M2 o( @
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

( X" \5 _8 A, i% |0 S- y- l6 |
( }- A; F7 @% |; \6 L$ ]1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,4 m* g8 q2 ?  J* q: R& c

& V6 U+ j' R8 [8 x2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.
/ }" R9 B  P, s7 Y5 V# ~2 L) f4 \" I
3. Then set bit16 of the IRQ to disable it.  h" A# v* b# `! v

2 x+ [6 h0 c4 T- Y* n    a.. Offset = IRQ# * 2 + 0x10;
0 O! A0 w. x' o1 |3 i. i3 Z) j' {7 W
    b. Write Offset to APIC base,' f4 C( c& E6 U2 j5 b9 Y
  G# K' K( Y. r' ]
    c. Read Data from APIC base + 0x10;- s" X9 J' V) I' }$ C) O& z7 O
+ X( z: X5 I2 O/ Z9 x) a- O  v( J
    d. Or bit16 to Data;0 X2 O) r( V0 x/ J2 c" |

$ k" C) `: ]/ ?9 w# C7 N$ a    e. Write Data back to APIC base + 0x10;
! ]! a% u8 B/ |4 ~: q8 Y
, H* X7 P& b/ \ / [; a; A7 @. e" @6 L, @6 i
6 W. d) a4 N7 j2 `
You need to check APIC spec for details.
回复

使用道具 举报

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

' V. R8 K1 D4 s8 z3 I. a6 l. H1 E6 Z' x4 v# A0 X) Q; G6 n
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。3 F# P' p2 B0 N: D8 R' a* b# Y
==============================================
0 j$ i' f: X* ?1 g, V 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。* q7 Y1 v% [; n
$ u  [9 g0 \" \5 R4 ?2 p
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)' e! [/ o' y6 z  `$ w
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
0 y( d2 ?$ L9 @5 T4 g
' ^# V6 O5 a. Q/ n$ c! {1 N因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
# i$ T8 B  k+ j. w: D% D9 ?* P7 {当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
: |. \2 n/ h6 `6 H, \1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。/ r  h3 F' v6 a3 v4 p' y' f+ x
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-2-21 03:05 , Processed in 0.094391 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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