如何使用C#读写硬件寄存器?

时间:2011-08-10 19:34:20

标签: c# hardware cpu-registers

我完全没有关于硬件寄存器的经验或知识,以及如何通过代码与它们进行交互。但是,我目前的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#读取和写入硬件寄存器的简单有效方法是什么?

另外,如果你可以提供有关我从芯片读取的具体问题的任何反馈,这对我来说是一个奖励,我非常感激!

3 个答案:

答案 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);
    }
    }
}

Also, another question about x86 in .NET asked a while back

答案 2 :(得分:3)

您无法使用C#等托管语言写入硬件寄存器。您可能需要使用C或汇编程序。该芯片可能会附带一个devkit以及如何编程的说明。