Dal*_*lal 5 c# hardware monitoring open-source bus
我试图让OpenHardwareMonitor从我的Supermicro X7DWA主板上的Winbond W83793芯片中读取温度数据.问题是我没有任何低级编程经验,并且在线可用文档似乎不足以解释如何访问温度.
但是,在我一直在研究这个问题的那个月里,我发现了一些可能是解决问题的关键值和低级方法.我只需要弄清楚如何使用它们来获得我想要的东西.这就是我转向你的地方,因为你可能会理解这些信息的含义,以及如何应用它,与我不同.我已经完成了我的公平分享,导致许多蓝屏和计算机重启.足够的猜测,我需要将这些线索拼凑在一起.这是我目前所知道的:
要从芯片读取,我将以某种方式需要访问SMBus,因为这是监视程序(如CPUID HWMonitor)获取信息的方式.据我所知,OpenHardwareMonitor没有任何代码可以访问SMBus,这就是它可能无法从芯片读取的原因.但是,OpenHardwareMonitor在其Ring0类中包含以下方法,用于访问其他芯片的信息.我可以使用这些方法对我有利:
void Ring0.WriteIOPort(uint port, byte value);
byte Ring0.ReadIOPort(uint port);
Run Code Online (Sandbox Code Playgroud)在其他信息中,HWMonitor在保存报告时向我报告有关Winbond W83793芯片的以下信息:
寄存器空间:SMBus,基址= 0x01100
SMBus请求:通道0x0,地址0x2F
看起来这些是重要的值,但我不确切地知道它们的含义,以及如何将它们与上面的Ring0方法结合使用.嗯...这么多线索.HWMonitor显示的其他值是实际电压,温度和风扇速度,以及表示芯片某处数据的十六进制值数组,如果您想查看它,我将在此处重现.
最后,在W83793数据表中,在第53页(如果您打开文档),这里是我希望阅读的温度十六进制的地址(我相信):
TD1读数 - Bank 0地址1C
TD2读数 - Bank 0地址1D
TD3读数 - Bank 0地址1E
TD4读数 - Bank 0地址1F
低位读数 - Bank 0地址22
TR1读数 - Bank 0地址20
TR2读数 - Bank 0地址21
到目前为止,这就是我所知道的.OpenHardwareMonitor,W83793芯片和Ring0代码可通过上面提供的链接获得.正如我之前所说的那样,我已经有一个月了,我还没有能够解决这个谜团.我希望你能帮助我.所有这些信息可能看起来有点令人生畏,但我确信这对具有一些低级编程经验的人来说是有意义的.
总结一下我的问题,使用上面提供的线索来弄清楚如何让OpenHardwareMonitor读取W83793芯片的温度.我不需要在OpenHardwareMonitor中创建芯片的细节.我已准备好上课了.我只需要序列和格式来编写Ring0命令,如果这是我需要做的.
编辑:我发现了一些更多的信息.我从HWMonitor打印了一个SMBus设备报告,除此之外,我得到了这一行,包括在这里因为它说0x2F:
SMB设备:I/O = 0x1100,地址0x2F,通道= 0
这必然意味着我需要以某种方式将I/O的地址与芯片的地址组合在一起,这似乎是0x2F.我尝试将它们加在一起然后我得到所有温度读数为255,所以这不是正确的猜测.
最后,OpenHardwareMonitor 的作者好心地帮助了我,现在我能够从我的芯片中读取温度了。虽然这个问题的整个解决方案有点复杂,而且仍然超出了我的范围,但这里是使用 Ring0 类的基本读写,供任何感兴趣的人使用。请注意,这是特定于我的机器和芯片的。对于您来说,基地址和从机地址可能不同,但您可以使用 CPUID HWMonitor 通过打印报告找到它们。
首先,这是使用的常量:
private const int BASE_ADDRESS = 0x1100;
private const uint SLAVE_ADDRESS = 0X2F; // as we figured out already
private const byte HOST_STAT_REG = 0; // host status register
private const byte HOST_BUSY = 1;
private const byte HOST_CTRL_REG = 2; // host control register
private const byte HOST_CMD_REG = 3; // host command register
private const byte T_SLAVE_ADR_REG = 4; // transmit slave address register
private const byte HOST_DATA_0_REG = 5;
private const byte BYTE_DATA_COMM = 0x08; // byte data command
private const byte START_COMM = 0x40; // start command
private const byte READ = 1;
private const byte WRITE = 0;
Run Code Online (Sandbox Code Playgroud)
接下来,这是从芯片上的寄存器读取特定字节的基本代码:
// first wait until ready
byte status;
do
{
status = Ring0.ReadIoPort(BASE_ADDRESS + HOST_STAT_REG);
} while ((status & HOST_BUSY) > 0);
if ((status & 0x1E) != 0)
{
Ring0.WriteIoPort(BASE_ADDRESS + HOST_STAT_REG, status);
}
// now get the value
Ring0.WriteIoPort(BASE_ADDRESS + HOST_DATA_0_REG, 0);
Ring0.WriteIoPort(BASE_ADDRESS + HOST_COMM_REG, theRegister)
Ring0.WriteIoPort(BASE_ADDRESS + T_SLAVE_ADR_REG,
(byte)((SLAVE_ADDRESS << 1) | READ));
Ring0.WriteIoPort(BASE_ADDRESS + HOST_CTRL_REG,
START_COMM | BYTE_DATA_COMM);
Ring0.ReadIoPort(BASE_ADDRESS + HOST_DATA_0_REGISTER); // this returns the value
// now wait for it to end
while ((Ring0.ReadIoPort(BASE_ADDRESS + HOST_STAT_REG) & HOST_BUSY) > 0) {}
Run Code Online (Sandbox Code Playgroud)
虽然我不太明白,但这可以为那些比我有类似问题的低水平经验的人提供一个粗略的指南。