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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>- l) n# s! |# u8 o
#include <Windows.h>5 m0 g2 a" S1 M8 k* H- ?. ^7 C
#include "WinIo.h"
' h% ?0 y$ s5 z7 @using namespace std;8 l2 l7 C+ X. P/ V0 F9 r* r

2 X" Q5 A$ K5 ?1 {- ?) p#pragma comment(lib, "winio.lib")
, x6 v% _& b" D4 _* z! y  u# B% d% `0 M- G8 e& ~: \: {  {' C! @' y

3 d' _$ H4 v+ y$ Cint PMU_SC                =        0x6C;//命令端口# a1 e: x, S, ~  ]8 b/ n( q4 o) D
int PMU_DATA                =        0x68;//数据端口$ E: ?9 p- Q  ~+ j( |
int RD_EC_SMI                =        0x80;//读寄存器命令
; d( O- ~$ X, M+ M2 ~8 M0 Z! N$ }int POLLING_DATA                =        0xE7;//CPU温度寄存器号
2 w! E( g1 _! f! |/ m- Y4 a4 }) H+ [) K3 H9 u! Z- }
DWORD dwTemp = 0;
. |4 r1 w" O# S3 A0 ]' ~
; x% C0 @. A: H  o( J- e) i/ F. Uvoid PMU_Wait4IBE(DWORD *_value);
. T# X6 j( V/ k$ n' j. e! A9 Wvoid PMU_Wait4OBF(DWORD *_value);
$ X  e' ?" X: l2 h# e# A+ ^$ h2 M0 w/ a

, ~: ~. L' n9 f$ M7 cint main(int argc, char* argv[])% t2 j2 J# R3 o% @8 s& Q: V
{
+ R% N6 ^  W$ Y( U* Y        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;1 u& y  d/ t" ?9 G5 A6 q7 m

( ~1 l% d" y5 O/ r- Z& Z7 s6 Y: `        + a' A. r1 N; A- q
        //1、mov            dx,PMU_SC                //* r% F: {. z( f' H7 J
        //2、mov            al,RD_EC_SMI        //( W8 f. n- S% s
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
2 [7 [) s2 D( Y8 @; d$ j2 N+ a        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
% \! d& r3 I, G& |
7 K1 G- ]# G1 H7 f% [$ K        PMU_Wait4IBE(&dwTemp);
: A+ @% b* N# F( [! s1 |        9 ]% a! l( ]* b
        SetPortVal(PMU_SC, RD_EC_SMI, 1);3 S' t. O. h7 Z- Z2 R' M7 M  T
& c1 p* {* b6 |+ X' g1 r# U
        PMU_Wait4IBE(&dwTemp);. G2 f9 u( q: t* A0 g8 K
        ( K- z. T' }1 \* h) [- W
        SetPortVal(PMU_DATA, POLLING_DATA, 1);
- }( t8 b3 \. p( D8 f. B1 q$ v2 m0 C) I
        PMU_Wait4IBE(&dwTemp);* S' l3 j$ C$ K% R1 l$ i& n4 |
1 e: _; J# o. x/ F) f& N
        cout << dwTemp << endl;                * t3 `% Q4 u) }- ?2 C& W/ M+ A. M

  W7 D+ [2 ^% t: w: {% ^        ShutdownWinIo();
! Q$ B$ H: I' B$ N5 s& _6 O' @: F7 P0 X6 c" O7 Y0 ]
        system("pause");
; j+ E8 R+ @+ `% x8 G5 r; r4 \; [: R4 S  A! X* c6 ~! T
        return 0;
+ A0 K- K9 q- H7 a/ A1 r& y}" \. O, u; S+ X5 E

$ E4 r- j' X0 Z% Gvoid PMU_Wait4IBE(DWORD *_value)  p$ o5 m4 T* g5 Z
{
1 D* H4 {1 o# ]* e! W5 A        //#########################################################   
3 E! K4 g1 e( v% I8 _# L: i        /*
5 g- @: d& c; ^8 U9 ]% l& o5 G        pmuWait4IBE proc   
+ i8 [  c  Y+ X! Y. a        PUSH        AX   
% I' `/ k8 L2 |) y6 W+ Y% M1 f        PW4IBE:               ! g; d4 w; a3 ]% c
        IN          AL,  06CH                                //Read  PMU  status   
. G: D5 a, r/ U9 L) |  z! l        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
. G8 I5 p2 j$ Y9 A        JNZ         PW4IBE                                        //Jmp  if  no   ! A, i0 N# {6 K6 R
        POP         AX   
( V8 y& g1 ^2 m# v3 S        ret   + a% P: n& W- v2 h+ h2 i
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
" V/ O+ }4 P6 r* f. I- O8 R        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空( ~' I2 w6 T8 q) O% B" e; |$ H- |
        //#########################################################
- I. @) W) t: {8 }: q* t: c/ K        /*do
+ c5 i3 C9 B0 u. O        {( J  U4 L$ k' v( j+ K
                GetPortVal(PMU_SC, _value, 4);
0 t, V+ X; ~/ b  E' |% c/ v9 t" A3 c        }
  {" W* V3 Q. g$ J  b        while ( *(_value) & 0x00000001 );*/7 P6 @/ R3 a0 X0 S/ x
        DWORD   dwRegVal=0;
0 P5 q* T9 r( T3 D9 ~$ {/ A! ]        do
/ c4 P# B4 z- l& g        {  6 s! ], U2 c' o, Y) M6 x6 ?
                GetPortVal(PMU_SC,&dwRegVal,1);. W$ K$ Z* ?' n1 }* J8 s3 O
        }* i( u+ q1 u4 h+ Y$ I
        while(dwRegVal!=0x2);
& |' J3 u+ Z! ], }, h# y
' y6 y0 _" C2 A+ L# P7 ]" r}
2 C- h7 H; ?/ D6 _
( D2 q. j- O- N7 e以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。$ v% O) c" H. K9 g3 ~. V% {
所以变成了死循环了。
) i- B7 D+ o% C' _3 ]% L- n# {  h( R/ |/ F3 a+ x
我对硬件编程不懂。又不知道从何下手。
" k" B0 |0 m$ d$ Y0 G+ S我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。1 I/ n3 t& ~5 X
但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。' Y# s/ S9 j& \: t6 r
$ b: f  }! |  m0 Q. C
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
' a' t& i- N# [3 R5 D  p并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。0 y, h7 y, A1 z( A" h" N7 h
' ?& D9 H) s6 Y" T& Q
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。; o7 u, E* ~$ b" W7 n) `
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook., h3 o5 a4 e3 v: G( r
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突( ]9 z+ q4 d0 E6 y0 ^* N+ r4 q
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.' w( d6 e& S6 s, O5 }
9 M  r2 _1 Y  y0 G- j
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。/ u( M* T* D% i! B
! y2 G$ I+ h) u# `& e
那么有些什么可行的办法呢?. p* j; u+ \3 C2 J
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
- T2 e) P2 L- H+ A! }' i5 K/ y  o! `: u$ f
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
7 x0 S( R8 X/ Q# E0 Q
# k. \# ]  X" M' s+ S那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420  Z  L& v/ A5 W  M! r

- R6 {; ]8 D6 Nhttp://www.ufoit.com/bbs/viewthread.php?tid=452
' b0 A4 m2 c* N/ S6 A* i6 |8 T% ^5 Y7 O; v( |1 _" j6 Z7 C" \
http://www.ufoit.com/bbs/viewthread.php?tid=241# d% |* H; l7 Q3 }

- n" |6 K& e& O& S9 S! S/ K看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。1 ^/ n& r3 X) G7 I
/ g) _/ I& u5 {( o+ d; @
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。% L. @, A; p$ ^& x; V; S) x  ~
2、Driver最复杂,也需要BIOS配合,推荐。
5 ^5 v  x# ~( L- c5 V: t4 ?, W3、Windows API只能获取到特定信息,不需要特定的BIOS配合。9 w) b6 C; X0 G8 r' ]9 A! i
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。; y( ^) i2 l: r. _
你可以混合使用。  W- }$ K( o2 ~  J: Y( x
7 c3 b( n; I* p9 ]' P
===============================================================" s' d% {! l: L: t; O) h
管理员的这句话:
$ h0 ~5 {- [* f7 \) T& x: `如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?; [! |3 a$ K. [

; i3 k* Q6 X. B5 Y  [2 o# R  }予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵5 _: g& N  M; ?% Z- t) y/ D

, p  X( F3 E5 y& k另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269' z9 D7 a- W% P" p. E" i7 |' F4 k

, E5 B& l3 B& ^0 k4 U8 X2 V6 L这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?" _: M1 A2 H- l9 y, i0 Z
& U' V0 R, _/ }% i
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。/ [  O% C! _: D& e: l( }5 c1 c7 j
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?
" ~: b. T: X) j% f5 H
2 |( m4 V& W; y, e& x4 h我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
1 D% P  A  r1 R你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。5 B1 C5 \/ {  ?) T
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
4 {8 p6 m: [9 h

& Y% f0 L5 D8 F( t* O5 \7 H: @+ x您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
- S% u7 a  o# I5 c* y6 d! N  \" c3 |6 z
void write66(unsigned char Data)& J& _  p9 F3 j  v, |% L" k2 _* e
{3 g& L" M8 m0 p! W5 T4 c' W5 ]; C
        DWORD Status,TimeOut=10000000;) `9 J" ]8 A8 a4 a% `. C8 b
        do
4 E2 t; r* O3 m        {
- _- ^2 i% Y* c& m                GetPortVal(0x66,&Status,1);/ l& Q0 m/ h+ _8 U$ ?( |( q
                TimeOut --;
  w2 y" x" D5 h! B3 _+ a//                Sleep(1);
, P# h* G3 Q; V! Z/ j        }while((Status & 2) ==2 && TimeOut>0);0 K' [/ ~. X8 |

/ d6 K/ n7 |4 j( j3 b1 `        SetPortVal(0x66,(DWORD)Data,1);
* ]( |9 S  @. ?1 A# C. F4 A6 t}
, R! z/ Y) G7 [1 @4 |void write62(unsigned char Data)" ?' H: P8 e. L9 U2 G" h
{
/ s7 a7 Q0 a) ]5 x9 I! w+ V        DWORD Status,TimeOut=10000000;
% y6 G9 J% M# q3 r& m3 s        do
5 }( c( E" }8 c7 Q        {
% C7 U( o  w' J) D                GetPortVal(0x66,&Status,1);
% z( P7 x+ b. M+ H( A8 \+ z& |. D: d                TimeOut --;' k, L, ~4 l' q$ R; i6 z
//                Sleep(1);
# T# w; ~! B+ F        }while((Status & 2) ==2 && TimeOut>0);
% k2 a/ ?5 [% ?
9 z) o2 H, U( N% m5 S        SetPortVal(0x62,(DWORD)Data,1);6 n! T/ \0 O& L3 p
}( h% ?9 m! w& N3 w- Y3 F
unsigned char read62()" r) |7 i3 U$ L$ f& k- a; ~/ f% S0 ~! |
{) ?: h1 R. I- @: v6 j
        DWORD Status,Data,TimeOut=10000000;, x4 M2 t- E8 u! t  \! K
        do$ E' o& f+ a. Q7 O5 z
        {1 t" A' r) X1 Z: @3 R7 E1 ]
                GetPortVal(0x66,&Status,1);
. F/ T# r' L1 _2 j7 _0 k                TimeOut --;' I3 r- n+ s$ I  V3 N
//                Sleep(1);5 c2 M) T+ r7 b0 F& ?
        }while((Status & 1) ==0 && TimeOut>0);
+ k7 H+ e. n; v1 i" p" ~2 s6 n% z1 @. q% q+ B
1 |7 d# I/ B8 W. L7 O& m' w
        GetPortVal(0x62,&Data,1);8 _+ I8 P- n9 Q1 O) D
        return (unsigned char)Data;- s7 m& m+ M6 ^# S$ a7 X% ?
}3 D* J# B$ L3 X4 u
unsigned char read_ec(unsigned char index). G' f/ ~8 R3 t: N3 f- {
{
! A" j% \$ a* u- E0 G        write66(0x80);- \& D, I5 m1 ]. z1 H
        write62(index);
  R- l2 ]5 V% N2 i* @# w        return read62();
5 @/ w+ i7 y; t' A}
8 r( Z" y3 r% ^9 L0 i. f( G% F+ M1 m3 z7 V" t. M4 x
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1947) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。" _( X  |9 ]0 f" C% [. T* }! T
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。4 i# s& A! P0 A& d0 T3 v) ^$ b

3 }$ u! F$ }% I2 [7 D; B[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
, p7 b  e+ v3 e* h7 F, x0 b0 ?2 }3 g1 u# ?
( S1 ~8 |, F7 q' u3 f8 i
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢

, B' d' j8 s2 h0 f5 X% o" s  f* _( y0 w# J( r7 w
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,2 B/ \* C& A+ z# C/ N1 \( S

( G5 s$ ?; k1 j, w8 I$ M1 n2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9." o( O  L2 h" F1 F3 U6 N
/ X* x) n- E" j! k. u4 Q: r. `/ m7 Z. P
3. Then set bit16 of the IRQ to disable it.
( u0 m" Q# h- B/ Z, R3 {
2 a5 ], l2 O$ Q' @) w+ C. z    a.. Offset = IRQ# * 2 + 0x10;
8 w" r: c, l+ V% ^/ ?
6 E8 i7 H4 k( e3 A    b. Write Offset to APIC base,6 D' a1 e! R1 r; f' b4 p

/ z$ v, b! e! U( ?% J' ?+ R    c. Read Data from APIC base + 0x10;
' D6 {- z2 R; b- F/ i7 i+ i
/ O! Y8 T2 J: r( X  {8 @6 l1 ^9 f    d. Or bit16 to Data;6 I& c4 a) t8 f* s  f& i
6 d& k+ t% X2 _: n% s$ y
    e. Write Data back to APIC base + 0x10;
- y$ T% R: E$ ?5 X, K& _2 C6 L
1 c$ l( c( `( g1 G( N $ z4 l& r& L3 t

0 l/ E' O; `: [( n6 C% p0 vYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表
! T! [9 H5 o; o4 o2 c" }) L* T545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
) o, W& h  k4 Y5 w) m% ^# d+ O
: e2 P% h- Q6 S! L6 r% f
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。- ?- Z) Z, D% D$ \$ M5 n
==============================================& G- a7 x; `0 @5 x2 z
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
8 t" x+ V$ d- H& h2 T
8 t6 a) @! r# @1 x因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
5 W3 X" z! v1 p9 e$ D但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
3 g% g. o2 B% M3 J
% [' L8 d2 x$ T7 n% j因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。& r* i# y; L- \
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:/ y! T) l) Q* V  u' q' @: Y
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
( D  H( s0 E0 e. U; g& I2、新手不要把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-6-15 17:12 , Processed in 0.052333 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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