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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>4 r) g# V& `( Y% Z8 k$ m# ?
#include <Windows.h>
( T  x8 t" ?2 h2 \8 @3 Z#include "WinIo.h"; Z3 K, V- W+ \) S! c& `( M
using namespace std;
2 I3 [! V) k# o0 U7 m! P: \. E
  S) a  y8 ]+ S5 q7 j4 m#pragma comment(lib, "winio.lib")& @7 O( o6 l/ k1 x. G9 Y  b# E
- m: B, G2 |( E8 ^: w

+ z! G% d& V$ yint PMU_SC                =        0x6C;//命令端口
' i% U: E7 C; g/ L8 Y3 |int PMU_DATA                =        0x68;//数据端口
/ W2 w0 ~3 K: {4 Uint RD_EC_SMI                =        0x80;//读寄存器命令* X- C/ O: S, N& y
int POLLING_DATA                =        0xE7;//CPU温度寄存器号
" f. {9 g& ^: i3 j+ c) J) D) p4 @" O! h: W& j9 S. Q
DWORD dwTemp = 0;
5 w  T  B2 O1 h5 ?: _1 F: `9 K# L; d# \" b; w8 X+ C3 O4 z/ n& `0 l% {
void PMU_Wait4IBE(DWORD *_value);
' N: M) K' {0 K) I" Mvoid PMU_Wait4OBF(DWORD *_value);
( [, w1 O0 L9 E. Q# X5 }5 [: K7 M
* Q! H* R: Z) C8 q$ v5 h
int main(int argc, char* argv[])6 c2 y5 O& A# S5 D3 S6 Z
{
" }+ C$ Q' w" Q+ @$ l/ b        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
0 U- l7 D9 s9 r- _8 E. J
. R0 P) T# D. F- D. {7 b       
' W9 e& f& P, I% v9 Y        //1、mov            dx,PMU_SC                //
& z. A8 K6 ^8 ?5 a* k0 ^        //2、mov            al,RD_EC_SMI        //
8 a" i) {8 O2 f8 s# m        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
3 V. y! d8 b% V5 Q6 R+ k7 p        //4、out            dx,al                        //将读寄存器命令放到命令端口中。  K! {2 s  Y. U; |' Q$ V5 D0 E* n) n6 c

0 e! r/ e' X$ S* C0 q0 U1 D' S$ G$ P  H9 O        PMU_Wait4IBE(&dwTemp);
0 O& e1 K, O/ O6 B8 ~2 I       
  c" e* N& r9 a4 u" L        SetPortVal(PMU_SC, RD_EC_SMI, 1);" o* D; b. K% l! w9 `$ N
. E3 n4 K3 t. Q
        PMU_Wait4IBE(&dwTemp);$ i7 S/ H. q! o: N5 w
       
& q' q4 _0 p. F/ c# E% A        SetPortVal(PMU_DATA, POLLING_DATA, 1);( o' [- r" q& O1 W0 {+ K

9 X( d) o  F! L        PMU_Wait4IBE(&dwTemp);$ a  e4 M7 k+ s

3 Q& I+ l. m) v& J, i; }; D        cout << dwTemp << endl;                : \. W2 h$ R% G5 E; _* p

$ O& O2 u! p4 l* p8 v4 s$ ~- N        ShutdownWinIo();
7 I2 o, {2 ^% W) e2 ?! f# f
3 j3 |8 f5 t4 j7 A! K, R! {        system("pause");
5 e! N3 V8 N6 K8 U# l
$ U* ^) @* Z, Q        return 0;
6 y4 v7 y/ Y+ C9 o" r}- ~* A1 d2 g6 M: \# X. ^) Z

2 L1 _$ K8 L: I4 K, Q( @- Ivoid PMU_Wait4IBE(DWORD *_value)5 z2 S- ^1 Q! X4 s
{
) D+ p3 ?; ^1 v' P* V3 Q( F        //#########################################################   
# X) K  f" C8 r/ R        /*% J* W. s3 _' y
        pmuWait4IBE proc   4 L* [- X$ x7 E/ E' o
        PUSH        AX   
0 ]! |- v/ V- z& V        PW4IBE:               
8 Q! a6 I9 g+ t- Y+ R        IN          AL,  06CH                                //Read  PMU  status   
# k# ^' l5 k+ `0 H' q+ o        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
. ]0 q9 X- n% C        JNZ         PW4IBE                                        //Jmp  if  no   
. N' w4 d  x& q0 Z        POP         AX   + F% O0 B4 J2 {. Q9 g* T0 l  M2 @; ]
        ret   3 r5 [6 |. w: A" H
        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
5 x8 F: ]: p) u        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空* v( s! h- G0 \6 s0 C
        //#########################################################
/ k% I& b' O% ?9 q7 N$ F        /*do 4 D: a. N4 G6 T3 i; r% V
        {
( i' J/ J* K0 Y                GetPortVal(PMU_SC, _value, 4);
4 ~5 L1 ~8 q0 c& b        }: t, W! [/ n+ ?5 k" {
        while ( *(_value) & 0x00000001 );*/' o2 \. a" C! A9 F
        DWORD   dwRegVal=0;7 T3 X, S8 Y' G7 {$ F
        do' P6 b" v; e4 Z2 ?6 G" p
        {  
- ]; g% D) H& Y+ T  y" z                GetPortVal(PMU_SC,&dwRegVal,1);
' D" R; \! }' t        }
) C& Q; F' P& i+ U3 i        while(dwRegVal!=0x2);" h* p0 C# b; J0 i- d
2 |2 P. ~& G. o2 n. M7 g+ `5 |
}
4 Q* `8 k9 B) r3 A
$ J3 w6 ^9 \) L4 U: O以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。7 E' ]' p  R* M$ s" D
所以变成了死循环了。
6 b7 {. [7 k3 d. k
/ p6 P% F* Z/ @; t, |( r我对硬件编程不懂。又不知道从何下手。% _/ ?% g. R& r0 S
我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
  H# d; N8 F3 i2 T但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。: [6 I' {5 t/ {  {$ \: a* I
; {2 m7 C" i9 d5 Z# k% Y& a8 W
我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。
- M7 n+ [4 H$ J并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。1 }0 P. G6 J% Y1 m8 \  y
+ B* A4 u6 t5 n/ @5 @% @! E7 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.但是你这样做法应该是读不到的。
  {2 {2 y. d% [5 U) f' p1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.
0 c* t- d4 O7 l+ h2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突+ I  u4 Y  K- d  y( S0 S% d
3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.  {0 D. f! m) X

! J" U# f4 J6 D4 d# c8 f所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
4 W1 o4 e7 g+ |
& R  N6 r" c/ G# t4 F那么有些什么可行的办法呢?$ t2 l- v+ n3 V5 M" U/ B" D
为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。4 I+ J3 _' J) D* m- C( I8 \7 s6 n! E
, n9 @, S" y$ r9 [- C
它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?) _4 \2 f$ y! r  v0 |- E

0 e" \  c) _" a1 j9 j那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
( [2 {$ @9 [8 a, z3 j2 I0 }* T; P- R: {. h9 z" ]5 P
http://www.ufoit.com/bbs/viewthread.php?tid=452  w, m- F, \7 ~- X* Z0 D8 b

! h( X, p# E# h3 k0 Lhttp://www.ufoit.com/bbs/viewthread.php?tid=2410 q; h  x9 F" r
- B9 U  j0 h/ _. k/ u
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。
- b, f1 t! M- K! k& V' ^7 ^
! Q$ I4 I! w/ V; @6 A1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。- B3 d1 T5 K- M' x8 g
2、Driver最复杂,也需要BIOS配合,推荐。
( H! |+ S9 ]( [- W  k, Q+ N% P5 E3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
! y, ~; I, U7 A4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。, j  h1 T: i' P% d0 j; R* ?
你可以混合使用。, ?# p: {3 ?3 K( J

! r0 r& G! J: c4 J& y===============================================================
+ v$ M# D) H9 n% v2 i# o3 Q管理员的这句话:# H+ Y' i1 l3 R# x
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?9 V$ _: t+ h3 ~$ m4 i

  }3 H' E1 n3 i' \9 ?6 v) m予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
* _" w7 f/ a- I/ _$ U* R" r0 Q
% a9 {( c! Y/ k: {0 B% k另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=2697 @0 H" u- n' M; @( E# a: {

5 L1 Z- v; j! j这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
& a8 c; f; s$ ~. l% `; B, A
7 z" n& s8 J' f" |还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。
" K" L: ?9 B+ U. o3 n里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?' a+ b2 Y: o9 j3 \2 y: {7 @% y
, ^  x/ T, [& z  O5 w
我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
: v6 d. t: i( T) ?% ^- b& D你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。: j# k% |3 q$ p% D$ c' e
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...
7 i2 l9 R- Z6 Y4 c2 B4 \
8 z0 P' k  v3 K5 S
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。$ Y5 E2 F8 c8 J6 ^* R

8 i4 O& d5 h; b  p! v& N- rvoid write66(unsigned char Data)
+ j7 \, U) {! Z3 l, s2 y, K1 q. J{/ D$ o% I* k5 O
        DWORD Status,TimeOut=10000000;
+ F" z$ N) l0 w+ a6 p7 m! `4 W: @        do, E( ~! h2 a% B& P
        {, C+ G2 {5 i. E+ a# M4 T1 Q- w
                GetPortVal(0x66,&Status,1);
* _: K# P" R0 m                TimeOut --;
+ e  ~8 }1 O! Z, A//                Sleep(1);
3 H3 B$ s; m' f' n        }while((Status & 2) ==2 && TimeOut>0);" d- w* d8 p2 c
. U/ p6 R8 F  {: M) M
        SetPortVal(0x66,(DWORD)Data,1);
3 L/ Y: T5 [6 y! _4 p+ }}9 k' l% p" o$ ^. M' z
void write62(unsigned char Data)) b; v5 B1 y. N. e2 y* a" E8 X# K0 a
{, ~3 |, Q8 ]) N( p2 Q
        DWORD Status,TimeOut=10000000;. K( b& F' S2 i
        do/ l5 D: ^6 W: R7 `- ~# G8 J
        {
. j( s$ _5 _( y! f                GetPortVal(0x66,&Status,1);
) N! ~7 u1 `8 p# l+ r* q! ?, K$ D2 g                TimeOut --;
: p' ]! o) t. c, l//                Sleep(1);* C# E1 B/ v3 e7 L0 P7 k
        }while((Status & 2) ==2 && TimeOut>0);  i) O) ?, v, x1 h; W8 w7 f

+ ]6 a! e+ T2 D) R; t        SetPortVal(0x62,(DWORD)Data,1);
) a- i" k3 n" [9 }* L}
4 L6 _2 ~/ }$ ~9 A/ e- B! b; l9 junsigned char read62()
! T, R$ b) b, a  F{- Z: E* [; K7 ~6 R2 T# t
        DWORD Status,Data,TimeOut=10000000;) N( g& D" I1 u( \. Q6 A' w
        do
# H* c/ q& ^' h# ~        {* l7 ?5 t" r) }
                GetPortVal(0x66,&Status,1);, Y& d* @5 a$ W: T1 f
                TimeOut --;
* }9 O6 @  T" C% s7 h* P5 K$ O* \//                Sleep(1);
6 W; [! q2 [& v" R7 i% `0 z        }while((Status & 1) ==0 && TimeOut>0);- `+ C6 g8 t" |8 y

" ^+ e# y5 r1 p# E$ i. b1 Q; e3 d: \$ V& |+ R
        GetPortVal(0x62,&Data,1);8 v+ O! E9 H( ^4 Y
        return (unsigned char)Data;
. I# R# K+ \% n( r1 Z8 c; o! L}# C4 @. X2 ?/ B/ ?9 G) ^+ q+ }
unsigned char read_ec(unsigned char index)& j5 ^2 e/ |5 W  g6 t6 c7 M- S
{
# g1 X8 N; U9 a; z5 c/ H% J8 O" P        write66(0x80);
! I0 L9 h. }& [0 C        write62(index);# m; j0 s* [1 K8 L: f8 F, B
        return read62();
) {$ T, _" L% p, v. u& \}
/ n0 S; W' E) _: M: B: m( [# [" m: @4 A' U5 v2 w
[ 本帖最后由 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忽略掉的。2 M0 V$ U3 T! F8 _) ^
  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
. w, F2 `9 S; @+ V- h/ Q! [9 j0 W* T! Q- x: F$ C. Z* n
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表 6 d( q& M9 R0 s
% O  @" I4 }# T. s/ G

/ h0 s  F( Y7 F. I( t+ v您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
9 T( z6 e& Q' O
4 r) J. i& Q% O7 q
1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
/ f* W& }. b9 f. w* l2 n) o% {) ?6 {; v: i+ l" u
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.' I" K: |' w5 K. ^" h

& r: P4 T  t% m5 p( t3. Then set bit16 of the IRQ to disable it.! A2 w% _8 @+ ?7 A" Q& \
5 X$ o9 Q6 t5 e6 _( T
    a.. Offset = IRQ# * 2 + 0x10;& x1 m+ i% }/ x( n4 r+ v! N

; \; Z+ P* W2 P- m# A$ Q4 t    b. Write Offset to APIC base,
' n! O+ W2 s8 n+ M: A) {: ^5 O. d
% {9 q# S9 j: Y2 B6 h$ {- V    c. Read Data from APIC base + 0x10;
: a0 o; z( c- k) V; f( d
  t( q4 x7 Z9 S/ G8 z    d. Or bit16 to Data;- Y+ s4 b" [' G% U9 X& v

( \) [: S# {7 B5 @# a- A5 ]    e. Write Data back to APIC base + 0x10;$ [4 c* k/ W/ @4 u; }  t- v+ K
) x2 C( i) M1 d5 i' i5 J
+ s8 t6 s* |3 q$ B4 ?3 g/ F

1 ~) i( @% N3 n  j$ U( yYou need to check APIC spec for details.
回复

使用道具 举报

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

4 G  S9 S4 z2 K" l8 r, }: @
5 F' L" K# Y2 y! B) e* l* i 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。+ a8 p) P) m  Q& D1 F; L
==============================================
) B7 j/ L4 R' \. u9 Q! E( { 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
6 F& n1 y$ W. c, L7 D# {/ U: i1 R
0 I/ G" b+ d2 l$ |8 _- E7 q因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
+ _& {( m; v3 Y- k' B但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
/ ~4 x4 S+ t0 n9 H2 e% s
5 e+ z$ j# V; `/ ]. A  Z因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。
+ B: ~" N. }0 w当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:! J/ \9 S% q8 J8 D% j3 H" d
1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。
! {" _9 u6 \3 Q7 X# Z, T+ E: Q1 h. d2、新手不要把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:05 , Processed in 0.061965 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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