我完全没有关于硬件寄存器的经验或知识,以及如何通过代码与它们进行交互。但是,我目前的C#项目要求我从SMBus上的芯片读取温度,我想我将不得不弄脏手。如果您想知道,温度传感器是Winbond W83793G。
我还有很长的路要走,但我已经开始在第5页上查看此文档了: smbus.org/specs/smbb10.pdf
完成任务的第一步似乎是写入以下硬件寄存器:AX,BH,BL,CH,CL,并从以下读取返回值:Carry,AH,AL,BL,CH, CL,DX。使用此功能,我可以确定“SMBus BIOS接口”是否可用。更重要的是,如果我可以在C#中管理这么多,我可以按照其余的文档最终从Winbond W83793G中读取并从温度传感器中提取出我想要的值。不,OpenHardwareMonitor目前不支持SMBus,所以我不能将其用于代码。
总之,我的基本问题是:使用C#读取和写入硬件寄存器的简单有效方法是什么?
另外,如果你可以提供有关我从芯片读取的具体问题的任何反馈,这对我来说是一个奖励,我非常感激!
答案 0 :(得分:7)
C#是在虚拟机中运行的托管语言。它可以在各种平台上运行。它没有内置的硬件寄存器概念。
您需要使用低级编程语言来编写代码以访问硬件寄存器。
如果将此代码编译到windows dll中,则可以使用PInvoke访问非托管dll,将此代码包装在C#中。
答案 1 :(得分:4)
不支持,可能是危险的,也可能是不明智的,但有可能:
您可以(或在某些时候可以)将内联x86汇编代码嵌入到c#中。 Example of one way of doing it:
using System;
using System.Reflection;
class Program
{
public delegate uint Ret1ArgDelegate(uint arg1);
static uint PlaceHolder1(uint arg1) { return 0; }
public static byte[] asmBytes = new byte[]
{
0x89,0xD0, // MOV EAX,EDX
0xD1,0xC8, // ROR EAX,1
0xC3 // RET
};
unsafe static void Main(string[] args)
{
fixed(byte* startAddress = &asmBytes[0]) // Take the address of our x86 code
{
// Get the FieldInfo for "_methodPtr"
Type delType = typeof(Delegate);
FieldInfo _methodPtr = delType.GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance);
// Set our delegate to our x86 code
Ret1ArgDelegate del = new Ret1ArgDelegate(PlaceHolder1);
_methodPtr.SetValue(del, (IntPtr)startAddress);
// Enjoy
uint n = (uint)0xFFFFFFFC;
n = del(n);
Console.WriteLine("{0:x}", n);
}
}
}
答案 2 :(得分:3)
您无法使用C#等托管语言写入硬件寄存器。您可能需要使用C或汇编程序。该芯片可能会附带一个devkit以及如何编程的说明。