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

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

[复制链接]
发表于 2010-2-6 04:55:26 | 显示全部楼层 |阅读模式
#include <iostream>/ Z1 |# H2 D2 L% E
#include <Windows.h>1 U6 ]: `/ {' a8 W7 H- _  _9 z
#include "WinIo.h"
+ ^8 b0 F0 [) r3 H# s( U" n  gusing namespace std;3 d; A8 N/ Y5 |" B

7 J5 _' _0 j6 V7 [5 y1 j2 y#pragma comment(lib, "winio.lib")
5 V1 t* v3 s9 R* v
3 s3 A% `1 y) V# _. W- |& p" S" L7 b4 ]! W% {! x
int PMU_SC                =        0x6C;//命令端口) G1 k% I+ h/ D  j9 T( K2 b! b
int PMU_DATA                =        0x68;//数据端口
' r' p0 w7 B9 v! t+ G! U7 Vint RD_EC_SMI                =        0x80;//读寄存器命令
/ L# d! Q- u. f5 N! L8 z0 Nint POLLING_DATA                =        0xE7;//CPU温度寄存器号
& {# O& W$ l* B& c$ O: ]: d4 v% `; y
DWORD dwTemp = 0;( w6 |8 k/ ?1 v6 v
4 J$ ^+ Q$ w2 q
void PMU_Wait4IBE(DWORD *_value);- u; J: N/ ^+ Q# F
void PMU_Wait4OBF(DWORD *_value);, E8 W; r# ?0 ?/ u+ I

) V: T0 O1 w/ O' V: r
, g- ^% e' S: r5 H8 N: Pint main(int argc, char* argv[])! w3 I& s8 J9 V" X/ L
{
% [5 l0 u4 K( r        if(InitializeWinIo()==false)cout << "驱动程序加载失败! " << endl;
- K3 g* l) L! P- x# A' G
7 j) E* F. D# v- Z; B        * p5 R! D" {; }# c0 ?
        //1、mov            dx,PMU_SC                //% `' x) d% ~# B" u9 H8 X: B
        //2、mov            al,RD_EC_SMI        //6 N- @7 o* Q/ y. ?1 `: C. x# ~
        //3、call           pmuWait4IBE                //Must  have   输入缓冲为空吗,为空可以放命令了
) ^* O5 D+ B' H6 D/ [2 @+ e        //4、out            dx,al                        //将读寄存器命令放到命令端口中。
- ^5 ^$ @; M8 d0 X8 R; u# |% a) k# V: s' p7 H  J! O' K
        PMU_Wait4IBE(&dwTemp);
3 S9 `9 S/ {: y! b  F        8 }: t: Q7 t# M' m/ Q
        SetPortVal(PMU_SC, RD_EC_SMI, 1);; R$ |* y2 g# j4 d; j
  X- u. i9 g8 u% z$ l- A
        PMU_Wait4IBE(&dwTemp);6 `" f4 [6 k# L7 f
       
2 D) t1 [' h+ U( T; v        SetPortVal(PMU_DATA, POLLING_DATA, 1);0 L5 Q2 r/ I0 j( C

1 Q, O4 t' r+ J, q  T" }1 N- C        PMU_Wait4IBE(&dwTemp);
/ `) o1 p; {; u. w$ N; z
8 a8 M0 U; ^/ u6 [        cout << dwTemp << endl;                : x. N0 [7 {. y- c
& d/ F# o6 U& ]( m. K% o+ f
        ShutdownWinIo();
* q$ r5 I3 |8 |' d# A9 F0 b4 e) S, a
        system("pause");& k; ~) n5 x, k0 Q9 W: B9 i

, ?3 d( j; o0 `$ s; b0 T& t        return 0;
7 m1 r, B9 O( @8 J& f}: K" K! x% ^2 v. t# G. H
$ N7 B6 m. |' y
void PMU_Wait4IBE(DWORD *_value)
! ^* C2 e; H$ B{4 Q1 O) Q- e' I; O$ S% e$ N& W
        //#########################################################     R  g, M. Y0 X  u
        /*7 E+ Q" a( l! K: H0 H( \6 S
        pmuWait4IBE proc   
! W  _* P# g& C! B( ~0 ]        PUSH        AX   
; ?. C) {7 X2 U# b) g        PW4IBE:                 ~% |8 V3 b' C  i
        IN          AL,  06CH                                //Read  PMU  status   
/ I0 c2 K7 M* M6 O5 p        TEST        AL,  2                                        //Is  Input  Buffer  Empty?   
2 S/ y4 w% ?' m& w        JNZ         PW4IBE                                        //Jmp  if  no   
* f' m/ V, P, [' O* t. {        POP         AX   + {3 W" _0 r0 u, F  E9 f' L. `0 m
        ret   
  i+ x9 u7 h8 I0 D9 P7 ^        pmuWait4IBE        endp                                        //END  OF  PMUWAIT4IBE
7 N. a4 ]* E5 i' e* R        *///循环读取0x6c端口的数据,看是否为空,不为空则一直等待其为空
' h" W, l: s# m' _7 w' R        //#########################################################
$ ?6 t/ ?) }* u  n" W+ h3 z        /*do
0 ~' @0 D: x- ^5 d8 m, F, Z" B        {- L1 A2 V9 `6 ^: ?/ B% Z& a
                GetPortVal(PMU_SC, _value, 4);- \- ^% k" C: X+ {& g
        }
$ z8 r% s$ G0 H  W; p        while ( *(_value) & 0x00000001 );*/
2 [$ s, l9 m* a" q, }        DWORD   dwRegVal=0;) h" F" V, G1 R* s- ?  \0 k
        do
; D1 F. P, l% X2 n3 X* l        {  
+ Q6 F( b" L) G, R                GetPortVal(PMU_SC,&dwRegVal,1);( C, r& z  {1 l
        }
: u0 ]( J. u: D        while(dwRegVal!=0x2);
2 P1 _0 H  R/ X3 \. V& [( @2 n1 }$ }6 F
}# m$ b! P1 G8 v+ m% K4 y
; {2 M8 @8 ?' G; f5 B% {
以上是我在google了csdn还有有一些其他网站后写成这样了。但是使用getportval得到pmu_sc的值永远都不能等于2。
* t4 u( z, Y& c6 d4 ]1 w5 y4 W所以变成了死循环了。
5 `( {; `2 x0 C) f( U. W
! f6 t+ @0 c, a, G! M我对硬件编程不懂。又不知道从何下手。
+ a6 O: d6 n5 L$ m: c我自己按照amd和intel的cpuid pdf文档写了读取cpu基本信息的小东东。希望可以把cpu的温度也给搞出来,当然更好的是能把bios也解决了。
& v( m+ W0 L7 v- u但是这个温度已经搞了2天了,无果。很是郁闷。实在没办法了。
- Q& D" n2 }! Z% U- N; j3 A! k+ t
  s" [# ~$ S& x2 n; ]我就想知道如果我想写个类似于everest这样的监控软件我需要搞清楚些什么? 或者简单点,我怎么才能把cpu的实时温度,硬盘温度,笔记本电池的信息给搞出来。( \4 X( n- i  D' _; k: d
并且我需要最后软件可以运行在x86和x64的系统上,因为我的笔记本是win 7 64bit的。& {' Y4 F, A  M8 F" e! R  N
- E4 e3 F3 {' m$ H* g9 f% _4 P
感觉现在无从下手。我在网上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.但是你这样做法应该是读不到的。6 ^: ~$ w  A. j' p! `9 n# M- Y% L; Y
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACPIEC-Enable SCI,不过这种做法也不是适合所有Notebook.8 Y! G0 {+ u- E" s3 Q
2.0x6C/0x68不适合所有Notebook.EC到底使用哪个Port?.一般是使用0x66/0x62,但是0x66/0x62已经被OS使用了,会冲突
0 ?, m5 {2 Q5 ]# D/ t3.不是所有ODM的CPU temp是放在ACPI ECRAM的0x00E7处的.
/ y" e: p9 N1 W/ X# m5 j" H0 X/ h! k* u. d# U4 t3 b. \
所以.....呵呵
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:18:05 | 显示全部楼层
按照楼上的说法就是这样做的可行性不好。而且存在端口的变化分歧性。
; @/ x. I2 `% \4 P2 U9 `  l; s- }9 w3 t. O+ ?
那么有些什么可行的办法呢?
  U) m2 \$ V. W3 x, |) ]为什么类似于everest这样的软件可以识别目前几乎所有的主流机型的温度呢?而且它称这部分为传感器。在里面不止是cpu的温度。还有其他的设备。0 u; g1 z. v! b3 W0 q3 X1 D1 N

9 O' k8 H, J( E+ ]* N% }它的做法是为其建立数据库吗?通过不同的特征采用不同的方式或者端口吗?
, w) ^# w( }1 Y0 ~1 J7 b5 ?% k) y$ I0 `; P9 T+ A6 S5 h
那ACPI里面有cpu的温度吗?如果有,我需要怎样才能从这方面下手啊?有些什么值得推荐的书籍吗?
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:21:42 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=420
, }: t: {! d" G! w# ]  i0 c0 ^* s+ y$ d; C% V# }
http://www.ufoit.com/bbs/viewthread.php?tid=4525 q  p5 N+ H% [

( b$ {( V- `- U  a( i( e6 S# y, \http://www.ufoit.com/bbs/viewthread.php?tid=241! G& e1 p% I$ N* t9 C
/ Z3 t6 o7 V; z3 X( p# e+ C, t6 S
看来得先从这些地方看看了。谢谢楼上两位的回答。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:26:00 | 显示全部楼层
那你的问题,说起来,跟ACPI是没多少关系,但用ACPI的方法,也是会让系统最稳定,也是最适合用acpi windows程序开发,如低难度的就是WMI ACPI,见DDK中带的WMI-ACPI白皮书。API可以获取电池,CPU,等相关信息的。驱动,你可以建立自己的pnp device驱动来获取,如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。予人鱼,不好呀,渔才好。/ u* F* k5 [) u; v$ E) r5 p
- K/ p2 [" v: H4 p! U
1、其中WMI-ACPI最简单,但是BIOS得配合,推荐。2 P: ]: X( e/ [6 b+ v8 a7 ]
2、Driver最复杂,也需要BIOS配合,推荐。$ e" G, [( ]* T* G# x* d
3、Windows API只能获取到特定信息,不需要特定的BIOS配合。
" s2 _$ p! V& q, j2 L$ O4 M4、IO的方法,能获取到全部的EC状态信息,需要EC的文档,如果是给for end user,要出货的程序,这种方式不推荐。0 n: g% D% e. c* h
你可以混合使用。
" t9 ~8 U) q+ A1 Z) L
2 L: U) S0 U) \4 u& A! w6 d===============================================================' H* Q$ g2 {2 a; N$ P% E3 W
管理员的这句话:& e  [0 G  R; `7 S
如仅仅是EC里的数据,何必呢,用IO读写就可以,只要你知道如何读EC的space。” 如何理解啊?/ d" v# s# q) h3 l  x2 W
7 p- F1 _- k6 M8 d
予人鱼,不好呀,渔才好。”这句话又怎么理解啊?呵呵
; f0 b$ @# y9 d* V  V, B- e' V4 @4 X6 P
另外,居然复制一下有那么多扰乱字符,太万恶了!呵呵!
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:38:10 | 显示全部楼层
http://www.ufoit.com/bbs/viewthread.php?tid=269( n& S# n+ P( p% ?  Q8 M% f0 B5 }

- \0 x0 o4 c1 F这个帖子看了后,感到迷茫了。BIOS我知道是就basic input output system。EC是什么东东啊?
' K' y% K1 E! J" [) M9 r- i- i( f! F( K0 N
还有就是在里面又找到了个链接是管理员大人,小斌斌发的呵呵。. t+ W( l' W6 p  Y+ B, g( v
里面谈到了要用DDK。我对这个完全没有接触过,我猜应该是driver dev kit吧。不过我要去下什么样的版本呢?+ D: G8 q) }8 r. l8 |# h

$ u9 L% t! B( F7 @3 r9 T我目钱开发的系统是win32 xp sp2,ide 是vc 2005。
回复

使用道具 举报

 楼主| 发表于 2010-2-6 19:40:28 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-6 14:58 发表
; V) d; j, A! n0 V) o你这种办法应该指的是EC CPU Temp值存放在ACPI ECRAM的offset 00E7h.但是你这样做法应该是读不到的。" x5 A2 Y  g7 u; v
1.OS会使用 80h RD_EC ACPI CMD 读ACPI EC,可能会冲突,如果一定要这样做,我所知道的办法就是先Disable SCI-读ACP ...

* o. G& S4 }; t
" c$ R( y/ u4 @$ K( m5 C1 X$ {* n/ g您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
回复

使用道具 举报

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

使用道具 举报

发表于 2010-2-9 10:55:59 | 显示全部楼层
不用禁用什么SCI的,有是有冲突,不过马马虎虎还能用。过滤掉异常值就行了。& J4 @! a0 ^$ Q, i# i

- B  u) H! l0 R0 k9 ^# ?void write66(unsigned char Data)
7 C1 j+ U! V1 {4 y9 `! ?% X{- z/ Y) s3 B% o; U& Z- p( e
        DWORD Status,TimeOut=10000000;
; H6 S7 \" S+ X! d        do
1 b0 u; z3 v0 l5 p        {) l0 l8 d" j" W' \" g
                GetPortVal(0x66,&Status,1);
# T( C: d% o9 g2 X                TimeOut --;; ~0 O0 ~. d% ]- s3 I' _
//                Sleep(1);
+ R5 E! A* W1 t8 K) h/ A        }while((Status & 2) ==2 && TimeOut>0);
6 {1 e2 O3 A5 H1 e; K+ ?2 K3 V  N$ c
  J! i$ E- \' [7 `+ Q) g        SetPortVal(0x66,(DWORD)Data,1);
, Z5 a# U" ?  U% i}# ^( U2 L2 M. Z: x9 N2 @
void write62(unsigned char Data)
7 B- F" X* Y6 l$ b. g{
" p" o7 y1 U  \+ k* }! I3 x* t        DWORD Status,TimeOut=10000000;
1 l. R9 ?2 o5 }8 c! B        do% D9 z5 [* X- p2 V& `
        {6 k$ z' T2 D/ H( H; q* W
                GetPortVal(0x66,&Status,1);
$ j$ [# C/ D4 H! c                TimeOut --;6 T8 q; [3 A( ?# N. c9 f
//                Sleep(1);/ x1 x% x# s! W! \) L
        }while((Status & 2) ==2 && TimeOut>0);
8 |, x- h  \4 S; A6 w$ U4 f( C* R7 n6 W; N+ ]: H
        SetPortVal(0x62,(DWORD)Data,1);& v5 M* s0 I2 q1 k3 b2 B
}9 V, v( m% ?5 P" r
unsigned char read62()
, e: X) ]  Y, l& s, _{
) }& k0 I7 v8 u, ]( F        DWORD Status,Data,TimeOut=10000000;8 K6 m$ z4 o1 u. ^% W
        do! R0 s  k1 q0 G
        {  e5 c% n. C# U: ?7 @
                GetPortVal(0x66,&Status,1);
, W& A* z  J9 b3 W. P7 ?- j0 u! {) g                TimeOut --;
  T! |: z+ W# }; H//                Sleep(1);
! A% S( d- {6 Q; y" N- ~6 V        }while((Status & 1) ==0 && TimeOut>0);6 {0 G, u0 b) c, {: G/ D
9 b9 y& M3 |; [2 T: U

7 T/ r2 f0 H% G$ s        GetPortVal(0x62,&Data,1);6 m# e' Z! Q& t! D4 e! X" S
        return (unsigned char)Data;, |6 |# [& M/ _2 q% I
}
& f8 \; [$ F4 L0 I7 vunsigned char read_ec(unsigned char index)7 x+ b5 c  @+ B! S
{. D* A9 ?( W3 s2 ?# Q# e
        write66(0x80);
3 C2 [* f6 g% O9 W, h        write62(index);
3 W4 i0 U+ D0 d4 ^! D) J        return read62();9 L# W( x0 N+ O
}
: U, f7 w5 y% Z! S, S4 m, P
1 i6 M! @, p  J& m, @9 k  b9 X% h[ 本帖最后由 qdk0901 于 2010-2-9 10:58 编辑 ]
回复

使用道具 举报

发表于 2010-2-9 16:41:22 | 显示全部楼层
HardwareEditor.zip (782.25 KB, 下载次数: 711) 楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你的AP而是OS的ACPIEC Driver。你读到或者写入的值只不过是OS ACPI读到或者写入后在EC Data port留下来的值。另外你有没有发现OS的错误报告里面一直在报告ACPI错误,因为OS被迫在没有与BIOS同步的情况下对EC做读写。OS读到的数据也当作无用的data忽略掉的。
  d2 F& x' M+ k; X: i5 U  如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。$ U( ?2 p1 {/ G" X2 c
! V' {. b6 u% s6 k$ `0 X1 b
[ 本帖最后由 Faintsnow 于 2010-2-9 16:44 编辑 ]

HE

HE
回复

使用道具 举报

发表于 2010-2-9 16:56:18 | 显示全部楼层
原帖由 海陆空 于 2010-2-6 19:40 发表   b  a; Z  q# h! X* U& ~

6 b" W& x; Y4 l2 ^* ~2 E3 v, R- }9 J
您能讲讲怎么disable SCI啊?然后又怎样呢?谢谢
( Q0 ^7 J2 Y/ @. g' A/ L8 a- B

, q! [1 Y( g) _: p  n0 M1. Find out the APIC address (you may looking it in ACPI APIC table), usually 0xFEC00000,
2 D; k. O% j) {) j0 h; c4 c+ O6 m& ?+ c) c; O3 q! k
2. Find out SCI IRQ number (you may looking it in ACPI FACP table), usually IRQ9.* P6 h) I& G1 |$ y1 H9 ~
# j+ k. B4 K- X% i: Q# n/ W
3. Then set bit16 of the IRQ to disable it.' _9 F7 u6 I$ C( S9 z; W! C

3 f  p; l. n) Z- v+ K  v! m2 F    a.. Offset = IRQ# * 2 + 0x10;
2 j8 i8 E' x* }6 p  c5 X: h" z/ C9 L: @$ _+ h( W
    b. Write Offset to APIC base,
# H+ w" z% a, H9 a6 Z% K. g: [0 i* X0 `
    c. Read Data from APIC base + 0x10;
# }: P, j9 X. k% `0 \( s3 |2 J3 ~( j1 Y" w6 f% |) D
    d. Or bit16 to Data;
0 y2 g$ Z' L1 m- `* H
0 p. j: _2 }1 h0 W% Q0 @& M) Q+ S    e. Write Data back to APIC base + 0x10;+ Y7 s6 J3 ]2 s5 S& q) A) a. I

' o6 Q3 X$ y  C 8 y' @9 d( I! f+ V  V5 g

1 Y5 |8 j6 Y5 }4 x. XYou need to check APIC spec for details.
回复

使用道具 举报

发表于 2010-2-9 17:51:44 | 显示全部楼层
原帖由 Faintsnow 于 2010-2-9 16:41 发表 " |! Z6 y$ x1 T" a& Q$ @  {
545楼上的有没有发现用你的方式后出现的两种异象,你的while等待EC IBE/OBF的动作是永远退出不了的。都是因为timeout超过了你设定的值才退出来的。那是因为中断优先的缘故,每次你用这种方式读写EC其实首先读写的不是你 ...
0 k( ]$ F6 x0 g% r. @. p

2 p  m! x8 }% l 如果一定要不disable SCI在ACPI OS读写EC那你完全没有必要再去判断EC IBE/OBE了,完全没有意义。
9 h% a0 X1 a! [2 Z- {1 d' N==============================================
+ e3 r6 j  D, o 事实上却是有数据错误,但是说不判断IBE OBF,那就有问题了。
8 f) t, C" Z* N/ Q3 c6 ?0 s& d; A
因为OS去读写62/66 port并不是很频繁(至少我们的平台如此),因此有几个错误的值我们可以容忍的,而且错误的值基本是固定的某个值(就是某个Q Event的id)
6 |' p* Q9 v; i& d, n+ z& C但是如果不判断IBE或者OBF,连自己的数据都不知道是什么时候ready的了。
2 W* q5 s3 C& u
' R( N4 T* q) r6 G因为只是用了做些简单的测试工具,所以这样的错误是可以容忍的。7 d/ Z  `! X1 q1 y
当然正规的做法当然是要禁用SCI
回复

使用道具 举报

发表于 2010-2-9 18:07:46 | 显示全部楼层
我想说两个地方:
% V- W- P. ~; x/ U4 @( }' G1、ACPI OS去读写EC Space时,一般情况下EC会用一个SCI去响应OS读或写的每一步细分操作。6 s" }$ P. g8 `
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, 2024-11-24 06:38 , Processed in 0.061924 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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