2010-12-08 31 views
0

Je travaille sur une plateforme ARM embarquée et je souhaite contrôler certaines des broches GPIO. J'ai de l'expérience en C et je suis un nouveau venu en C#. Il semble que le contrôle du matériel de bas niveau soit difficile à partir des applications de code managé. J'ai Windows CE6.0 et .NET Compact Framework 2 fonctionnant sur mon matériel.Comment créer des structures pour C# écrites à l'origine en C++

J'ai trouvé un exemple, écrit en C++, qui me permettrait d'accéder aux broches du port GPIO, mais j'ai du mal à implémenter l'exemple en C#.

L'extrait suivant montre comment DeviceIOControl est utilisé pour contrôler les broches du port:

const struct pio_desc hw_pio[] = 
    { 
     {"LED1", AT91C_PIN_PA(13), 0, PIO_DEFAULT, PIO_OUTPUT}, 
     {"LED2", AT91C_PIN_PA(14), 0, PIO_DEFAULT, PIO_OUTPUT}, 
    }; 
    T_GPIOIOCTL_STATE * pSetState; 
    T_GPIOIOCTL_STATE * pGetState; 

    // Configure PIOs 
    bSuccessDevIOC = DeviceIoControl(hGPIO, IOCTL_GPIO_CONFIGURE, (LPBYTE*)hw_pio, sizeof(hw_pio), NULL, 0, NULL, NULL); 

Autres définitions:

struct pio_desc 
{ 
    const char *pin_name; /* Pin Name */ 
    unsigned int pin_num; /* Pin number */ 
    unsigned int dft_value; /* Default value for outputs */ 
    unsigned char attribute; 
    enum pio_type type; 
}; 

/* I/O type */ 
enum pio_type 
{ 
    PIO_PERIPH_A, 
    PIO_PERIPH_B, 
    PIO_INPUT, 
    PIO_OUTPUT, 
    PIO_UNDEFINED 
}; 

/* I/O attributes */ 
#define PIO_DEFAULT (0 << 0) 
#define PIO_PULLUP (1 << 0) 
#define PIO_DEGLITCH (1 << 1) 
#define PIO_OPENDRAIN (1 << 2) 

Ce qui suit est le C# définition DeviceIOControl. Le paramètre de problème est lpInBuffer.

[DllImport("coredll.dll", EntryPoint = "DeviceIoControl", SetLastError = true)] 
    internal static extern bool DeviceIoControlCE(int hDevice, 
               int dwIoControlCode, 
               byte[] lpInBuffer, 
               int nInBufferSize, 
               byte[] lpOutBuffer, 
               int nOutBufferSize, 
               ref int lpBytesReturned, 
               IntPtr lpOverlapped); 

Les questions:

Comment créer ces structures équivalentes en C#? Comment les transmettre en tant que tableau d'octets (byte [] lpInBuffer) à la fonction DeviceIOControl?

Toute aide appréciée!

Répondre

0

un octet [] est converti en LPBYTE automatiquement
un char * en C# est équivalent à court non signé * en C++
un octet * en C# est un unsigned char * en C++
C# -enums se comportent assez similaires à C++ enums. vous pouvez simplement écrire

une chose importante:
[StructLayout (LayoutKind.Sequential, pack = 1)]

1

Utilisez une décoration Interop, par exemple, une structure comme suit:

typedef struct 
{ 
    char Data[MAXCHARS];//assuming a #define MAXCHARS 15 
    int Values[MAXCHARS]; 
} StSomeData; 

ressemblerait suivante en C#:

[StructLayout(LayoutKind.Sequential)] 
private struct StSomeData 
{ 
    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 15)] 
    public string Data; 

    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 15)] 
    public int[] Values; 
} 

Et l'utiliser comme: StSomeData[] array = new StSomeData[3];

Notez que vous pouvez utiliser IntPtr lorsque vous manipulez des pointeurs.

Par exemple votre appel à:

DeviceIoControl(hGPIO, IOCTL_GPIO_CONFIGURE, (LPBYTE*)hw_pio 
       , sizeof(hw_pio), NULL, 0, NULL, NULL); 

peut ressembler à ce qui suit:

IntPtr ipByte; 
Marshal.StructureToPtr(StLPByte, ipByte,false); 

IntPtr ipConfig; 
Marshal.StructureToPtr(StIOCTL_GPIO_CONFIGURE, ipConfig, false); 

IntPtr iphGPIO; 
Marshal.StructureToPtr(SthGPIO, iphGPIO, false); 


bool bSuccessDevIOC = DeviceIoControl(iphGPIO 
             , ipConfig 
             , ipByte 
             , Marshal.SizeOf(typeof(StLPByte)) 
             , IntPtr.Zero 
             , IntPtr.Zero 
             , IntPtr.Zero 
             , IntPtr.Zero); 

En outre, vous pouvez regarder dans l'utilisation de unsafe mot-clé et essayez de mettre votre code dans des blocs dangereux; cela peut être une solution sale puisque ce code ne sera pas un code managé.