开发者

How to read from and write to hardware registers using C#?

I have absolutely no experience or knowledge regarding hardware registers and how to interface with them via code. However, my current C# project requires me to read temperatures from a chip on the SMBus, and I think I'm going to have to get my hands dirty. In case you would like to know, the temperature sensor is the Winbond W83793G.

I have a long way to go, but I've started by looking at this document on Page 5: smbus.org/specs/smbb10.pdf

It seems the first step to accomplishing my task is to write to the following hardware registers: AX, BH, BL, CH, CL, and read the return values from the following: Carry, AH, AL, BL, CH, CL, DX. Using this I can determine whether the 'SMBus BIOS Interface' is available. More importantly, if I can manage this much in C#, I can follow the rest of the documentation to eventually read from the Winbond W83793G and pull out the values I want from the temperatures sensors. And no, OpenHardwareMonitor doesn't curr开发者_开发知识库ently support SMBus, so I can't refer to it for code.

In summary, my basic question is: What is an easy, efficient way to read from and write to hardware registers using C#?

And in addition, if you could provide any feedback on my specific problem of reading from the chip, that would be a bonus for me and I'd appreciate it very much!


C# is a managed language running in a virtual machine. It runs on a variety of platforms. It has no inbuilt concept of hardware registers.

You will need to use low level programming languages to write the code to access the hardware registers.

If this code is compiled into windows dlls you could then wrap this code in C# by accessing the non-managed dlls using PInvoke.


Not supported, probably dangerous and potentially unwise, but it is possible:

You can (or at some point could) embed inline x86 assembly code into 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.


You can't write to hardware registers in a managed language like C#. You may need to use C or assembler. The chip will probably come with a devkit and instructions on how to program it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜