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

Dal*_*lal 4 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#读取和写入硬件寄存器的简单有效方法是什么?

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

Jam*_*unt 7

C#是在虚拟机中运行的托管语言.它可以在各种平台上运行.它没有内置的硬件寄存器概念.

您将需要使用低级编程语言来编写代码以访问硬件寄存器.

如果将此代码编译到windows dll中,则可以使用PInvoke访问非托管dll,将此代码包装在C#中.


Tre*_*ors 5

不支持,可能是危险的并且可能是不明智的,但有可能:

您可以(或在某些时候可以)将内联 x86 汇编代码嵌入到 c# 中。 一种方法的例子

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);
    }
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,另一个关于 .NET 中 x86 的问题不久前被问到