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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>
- P8 j" \6 \- j" }1 q7 u% c/ x#include <Windows.h>
8 v. D! e4 c/ m. M" ~- a9 E% T#include "WinIo.h"  u5 ]/ N% f) b7 @$ m
using namespace std;
* {* E# r% K) s2 b) O5 w1 f- t. ]$ V8 }" ~3 h3 j
#pragma comment(lib, "winio.lib")( J* e5 n) F' z7 n; e! C/ v
/ r" H+ u! h) ^& U

5 C8 I" c1 l" _! R* D5 `, gint PMU_SC                =        0x6C;//命令端口# @9 H' s$ Z% |
int PMU_DATA                =        0x68;//数据端口
2 d" U8 F# T* j% t, Mint RD_EC_SMI                =        0x80;//读寄存器命令
1 o5 V0 d2 R0 V- _3 L1 v: p/ eint POLLING_DATA                =        0xE7;//CPU温度寄存器号
. {: W/ ~! j2 q7 T% s
0 M7 m- b8 J/ ^" eDWORD dwTemp = 0;
: ^% L( e5 C* }
) }9 ?# t1 C- N$ K( B  kvoid PMU_Wait4IBE(DWORD *_value);0 W7 ]0 E8 [# }' v5 t
void PMU_Wait4OBF(DWORD *_value);9 E3 k3 g' c1 i# y

% v# g9 ]* P" l  f5 S1 W' H
5 [- e% _, f% X: P7 w  }int main(int argc, char* argv[])( C! @2 Q/ T! M
{! U4 o( I4 R/ \, h3 q* R7 B, }7 b
        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
7 a9 z' f/ W4 ~: j& N! R
/ N9 U, Z% h8 o5 m6 V/ i        ; Y9 E( z: D; L) [  \. y$ i
        //1、mov            dx,PMU_SC                //
' @. K8 i4 L2 j3 h  D        //2、mov            al,RD_EC_SMI        //3 k% m% }! v/ C8 u1 ~5 ?
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
2 z7 @. R9 Q0 u8 z& \9 R        //4、out            dx,al                        //将读寄存器命令放到命令端口中。! m/ M- |" `3 p3 j' E
. }) c  V$ Q! U6 l9 [' m
        PMU_Wait4IBE(&dwTemp);
  Z. Q, N: L) q+ \! y       
% B3 G/ F# u0 M' _1 T; U- B; M        SetPortVal(PMU_SC, RD_EC_SMI, 1);8 B/ B) j& W/ [* j0 G- F- i
3 c. K7 y0 q4 ^* K( s' H1 U
        PMU_Wait4IBE(&dwTemp);; _* h, W% T' N7 A( \
       
2 t8 ]! t/ g5 w7 f        SetPortVal(PMU_DATA, POLLING_DATA, 1);
1 p( X3 f% b/ j) q2 ~
2 E9 _- ?# ^) C( l        PMU_Wait4IBE(&dwTemp);
: K9 {  x! H2 \4 N- m, p( ~2 t& x% h+ u8 B% b+ A8 K
        cout << dwTemp << endl;                : ?# o3 k" f2 `  v9 [
* h2 L0 i& s; d$ _
        ShutdownWinIo();/ L6 z& [6 f7 k9 }# [* y
0 D# l, W9 W( c4 y# b& I
        system("pause");& c1 D1 O8 P. I8 E* V3 x% m
8 a; ^9 k) ?0 Z8 p/ O* o! r5 }" L
        return 0;) B0 L5 u3 n2 |& |
}
2 V; c! O& u9 I
2 o" ]$ D! n6 H, K  pvoid PMU_Wait4IBE(DWORD *_value)
! t8 q$ H, b7 _4 j- B1 S+ M8 \{
% U$ `/ X) l& o' o  y* i8 K. {        //#########################################################   % |2 n& E" ^- p" R, @9 r
        /*% p# s0 U4 O5 [6 A: c' ~! i
        pmuWait4IBE proc   " Q3 f+ X' }8 R, @3 |& l4 O  {% I9 t+ d
        PUSH        AX   & `) O# P! |5 i9 X, @
        PW4IBE:               2 A+ i  M  M, |6 c/ x7 Y' p& j- [0 ~
        IN          AL,  06CH                                //Read  PMU  status   $ Z+ z+ T; N0 m6 b: T1 q; H
        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   4 r9 m" Q- U3 W3 u3 B9 t6 }9 k
        JNZ         PW4IBE                                        //Jmp  if  no   
/ V7 j1 l  a5 g4 C9 q1 d% F        POP         AX   
& B4 ~& i7 r  ~, `        ret   ! B. _& x$ V! Y5 T5 I& m" e! b
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE6 p% L0 L  ?1 O
        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空" ~% ]5 S7 ], {6 S! G" `( R
        //#########################################################
& V6 V9 M. R- t' ~5 g        /*do 4 _* x9 l. C2 v0 f: K
        {. R; Z% q: t! O/ ~2 Z% y
                GetPortVal(PMU_SC, _value, 4);
" i' o- v! {* L" \9 d2 A1 R1 P! @        }2 B( l8 z& g8 ?' R, ?
        while ( *(_value) & 0x00000001 );*/5 U3 L+ d8 ^" M8 J
        DWORD   dwRegVal=0;' Z0 C1 F& ?8 k
        do3 N! t, V: D* H8 v+ Y
        {  
* a5 ]( X+ J9 d% C) H, z, t7 ?/ j- q; o. @                GetPortVal(PMU_SC,&dwRegVal,1);
6 m/ c8 c; A6 v. u        }
% Z) T2 ?% k: P4 z7 V' Y. E! L        while(dwRegVal!=0x2);
' e. L( I' o7 n; E$ a" B# x( ~# h7 @8 B$ g* t
}
+ D0 c4 Z6 b5 \2 n4 ]7 O' [6 Q
; F+ _( C5 G- J! E: [+ S以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。  Z, h+ Q1 t- n  ]$ E; N  {. b
所以变成了死循环了。
4 ?6 e& k* y! o* {; \. T% J( R- k4 s9 t$ U  @
我对硬件编程不懂。又不知道从何下手。
: _6 W. Y+ J" `+ I我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
1 [1 J  k3 s" l1 L* Q但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。9 J4 R' x, t4 {6 W

7 c  ^7 M! G9 ?4 k$ Q  r9 C我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。3 ^3 I- A/ I0 @# |! w9 Z
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。0 v7 A/ R! t3 d% z

& V( ~' S8 \1 v2 u: N3 |/ H感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。
5 U% O1 y% b0 x* P4 F4 d1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
4 p7 V; x! ?" w; \2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突( G1 N+ p# T1 G
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
4 S1 |2 [1 T  x) ]& V
2 ~  \+ g% u5 R所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
( M% `) ^  V- X. o
8 U) m- y+ h% [7 z那么有些什么可行的办法呢?
: [) O+ R$ i" K; Y+ o为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。
: H) u8 w9 H- Z! C8 W, k
% M! K# y  J7 r# W7 b! e# l/ Q  Y- w它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?1 W# ?, O* ^7 ^7 p# O8 x
, X" Z5 x1 ?6 D6 G- }
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420( U% v8 k0 S6 X+ y+ R( R. u

* `0 f( H2 T$ R5 dhttp://www.ufoit.com/bbs/viewthread.php?tid=452
" t1 {' K3 c; d8 y3 [# w; ~+ u+ p- c4 z7 {) }
http://www.ufoit.com/bbs/viewthread.php?tid=241
: o% E4 m  A; z2 I* L3 S( T& o2 @2 M; V; r" h! m; t- A2 ^
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。( @3 N% s2 m; v7 k% Z
& I$ l$ r- Y9 ^& G. [
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。. D( h! z. w# }
2、Driver最复杂,也需要BIOS配合,推荐。8 M! o9 M" x0 T9 @
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。( R8 n4 T- F& e% V9 E, \
4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。
# p' p/ F* v" y, U7 X你可以混合使用。
2 |, {6 }' F( D- G9 a. x( L1 b) n' e4 J1 h9 J2 {
===============================================================
/ G; b! v3 m% r管理员的这句话:8 @* t# f5 c7 G) K; _1 R
“如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?
  s- e  ]* w7 | $ x: S5 t$ S, D% D* `3 k
“予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵+ C, w! U+ @- X
$ e9 u# L" b0 O* ^7 h
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269
" X% ?9 u3 N6 b+ ?4 c- V( w- n
9 ], L$ ^# O5 C, J这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?! ~  |6 e2 n: G8 Z: S/ f  z

  R# J7 e) }+ a8 N/ Q还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
0 [3 d. ]- A# W里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?' ~0 I7 A. ~3 O/ o; Q/ K6 ~
8 |& a0 h  s1 d0 l) x" m
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表 ; D! ^( Q$ \- g' p4 r4 G% W. S8 U
你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。
' g+ D2 q8 u! @+ a4 X1 L9 z1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
- ~) T' F* p- L

& s2 D# q8 d# M7 J) X. J# m您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。
( L8 k9 z7 F" e: m- W! M8 a) x3 b, Y) z5 f' M& }% u6 A
void write66(unsigned char Data)
6 K4 p5 q  L' Y* \- k{
0 l; A6 B7 G. u" E* B5 k        DWORD Status,TimeOut=10000000;
& \. P" ]. ~+ ]5 O" G/ U& s& [2 `, W        do. x4 o% b  R- C  A
        {
+ Z. V3 v  U: Y* S1 c                GetPortVal(0x66,&Status,1);
$ y7 m3 J5 t0 T1 l                TimeOut --;0 x1 B. H' y( m4 ~/ X6 }( C
//                Sleep(1);. y; {3 I! l& v9 Y+ F
        }while((Status & 2) ==2 && TimeOut>0);$ Y4 n3 x; |1 T3 V
# d$ N6 d9 x6 e6 [  x2 x* k+ p
        SetPortVal(0x66,(DWORD)Data,1);5 U+ D3 n# h% I. c# R
}7 [9 Y# E$ A, h
void write62(unsigned char Data)! ?" w. j. f* P3 F1 u- r: n
{6 a' ~9 Y: P3 |% Y
        DWORD Status,TimeOut=10000000;# G# N$ H: _$ f9 z! J- h
        do
# ~# f0 q& W( g# ^" w        {  p) [7 `  x  R( F
                GetPortVal(0x66,&Status,1);6 y2 D2 w( L" B- F  v3 ]- e
                TimeOut --;
6 C) f- ]  D; }7 P+ t' D% ^//                Sleep(1);; o8 W7 B; _1 H9 ]/ W$ M* W  w
        }while((Status & 2) ==2 && TimeOut>0);
8 i# T5 [- r2 u
- b! Y/ F  Z5 i" c  j        SetPortVal(0x62,(DWORD)Data,1);
# x/ ^, g1 U5 j% n}, R0 [5 E+ T' b! l: w$ _
unsigned char read62()
' @: D& Y) {7 d- ^0 c  _6 W{0 n% U+ _/ t2 }+ X; ^) y0 Z& z" O
        DWORD Status,Data,TimeOut=10000000;/ y) d2 v8 O7 K( `
        do% q: ^2 o0 Q9 r- s7 ^
        {
7 l% L. m9 s' L0 y6 b2 ^; n                GetPortVal(0x66,&Status,1);
8 }6 e9 u* |% }' s                TimeOut --;
2 V4 d$ ?$ k  H- S, H* Y( y//                Sleep(1);6 z; V% z9 P5 V' N3 T+ M2 T
        }while((Status & 1) ==0 && TimeOut>0);5 S4 }' Y& r2 d) M  `6 B

2 p4 F! ^8 ^/ Q1 C2 [  S2 R  I' H. r1 Q$ \4 V) N! B6 l) `
        GetPortVal(0x62,&Data,1);
8 V* Q$ s! `* W$ X) r4 N8 C8 e        return (unsigned char)Data;9 h7 ?3 W, e; U) D$ U0 i4 g0 p! N
}
. `8 l) K  v1 T1 O" N( L7 _0 Runsigned char read_ec(unsigned char index)
: a5 B8 t+ e  A5 I3 |% I5 T" N$ d{
( ?$ S! L5 T% O0 @; g- m( e2 \0 _        write66(0x80);
2 U( i3 v% I* V6 T8 p        write62(index);
# L, O* q. s+ L        return read62();
$ @/ E' A2 _. \$ U' p}
5 Y  p) p0 `. F' @. v. y+ o; \* R) p4 ~+ I
[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 1939) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。- G- r6 B, U+ t
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。* T3 g3 \# a% K. R; N+ i
$ q; H/ {7 g, ^  W3 j
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表
& a9 U. z% r; C4 u8 V. R6 O! v: }2 i2 m# g4 r- q
! X1 @: e4 l! G7 T$ i
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
( E) e2 r- ]9 E7 y7 J
6 N1 h0 P: F* F: x. f% c
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
% m; q8 e/ g0 I! [" ]2 P- D9 X. U5 C6 Z! k# ^/ T
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.# L3 {4 r8 p. G3 C$ Q

* H8 h+ E: A& X  H/ P8 F3. Then set bit16 of the IRQ to disable it.7 D: [! J9 v# Q" `

$ q- @$ V  \& [  W- R& f% _    a.. Offset = IRQ# * 2 + 0x10;; M. G+ n+ {5 N( I# n

$ F+ F* I: J& e  u9 Z    b. Write Offset to APIC base,
8 H4 ]: K$ e+ y" X6 Z- K  J6 T0 ^6 m6 s9 i$ N3 t' s: h( S. M
    c. Read Data from APIC base + 0x10;/ ~  K  l6 u+ Q0 I# Q4 Y

, q- L3 v6 F: z# E( _    d. Or bit16 to Data;, R0 Q' N6 v) ^: w2 c4 z2 p

: X. s; g* _& y* k    e. Write Data back to APIC base + 0x10;
# L/ l* A# |. r- R* _8 e: a( g( p, G

  J5 g7 R6 S- z( g3 b
3 J' k/ }# ?: J) {8 UYou need to check APIC spec for details.
回复

使用道具 举报

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

+ V. Z! A; w! r6 o2 ~8 i5 w0 F' x, q% @7 f' M. y5 Q
如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
2 h$ R! k9 D- q* Z& }==============================================0 y5 y# A. t: ^% v8 \- N
事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。4 o* K; A: @) O1 [. j/ w2 W$ o  \% v

/ [/ d2 t6 n8 N8 j8 L1 n- N4 V因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)# i. G5 X& l' {( w* o
但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
, D" i( g1 q  m2 H5 w" U1 z! \. O" [8 V
: k! t% v9 g7 X1 r6 \0 E因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
  d/ p! l3 ]: T当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
) `- ~0 y. O9 t& K1 U/ q1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。; G2 v0 q4 }4 ~/ M" N" C/ Y
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-11-3 23:11 , Processed in 0.128974 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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