Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / June 2007

Tip: Looking for answers? Try searching our database.

Mangaged to Unmanaged code I2C device access violation issue

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Tonofit - 09 Jun 2007 00:55 GMT
I'm doing a IO Control function call to set a I2C device's frequency as the
first part of a sequence of other IO calls.  I'm getting an access violation
in unmanged code in passing PBYTE pBufIn in the function below's signature.  
I've included a description of the comments for the driver function call and
the application user code I wrote.

Can someone tell me what I didn't do or tell me how to code this correctly
so it passs the PBYTE pBufin argument that represents the frequency value.  
It is defined as a 4 byte array and the driver code casts this to a DWORD.  
The frequency value is not being set  

--Device Code ---
//
// Function: I2C_IOControl
//
// This function sends a command to a device.
//
// Parameters:
//      hOpenContext
//          [in] Handle to the open context of the device. The XXX_Open
//                function creates and returns this identifier.
//      dwCode
//          [in] I/O control operation to perform. These codes are
//                device-specific and are usually exposed to developers
through
//                a header file.
//      pBufIn
//          [in] Pointer to the buffer containing data to transfer to the
//                device.
//      dwLenIn
//         [in] Number of bytes of data in the buffer specified for pBufIn.
//
//      pBufOut
//          [out] Pointer to the buffer used to transfer the output data
//                  from the device.
//      dwLenOut
//          [in] Maximum number of bytes in the buffer specified by pBufOut.
//
//      pdwActualOut
//          [out] Pointer to the DWORD buffer that this function uses to
//                  return the actual number of bytes received from the
device.
//
// Returns:  
//      The new data pointer for the device indicates success. A value of -1
//      indicates failure.

BOOL I2C_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,
                  DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
                  PDWORD pdwActualOut)
{
   BOOL bRet = FALSE;
   
   // hOpenContext is a pointer to I2CClass instance!
   I2CClass* pI2C = (I2CClass*) hOpenContext;

   DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:
+hOpenContext=0x%x\r\n"),hOpenContext));

   if (pI2C != NULL)
   {
       switch (dwCode)
       {
           case I2C_IOCTL_SET_FREQUENCY:
           {
               if (dwLenIn != sizeof(DWORD))
                   return FALSE;

               PDWORD pdwFrequency = (PDWORD) MapCallerPtr(pBufIn,
sizeof(DWORD));
               DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION,
(TEXT("I2C_IOControl:SET_FREQUENCY + ValIn=0x%x\r\n"), *pdwFrequency));    
               WORD wClkRate = BSPCalculateClkRateDiv(*pdwFrequency);
               pI2C->SetClockRateDivider(wClkRate);
               bRet = TRUE;
               break;
           }
           default:
           {
               bRet = FALSE;
               break;
           }
      }
}

---Application User Code----

       //
       // IOCTL codes
       //
       public static uint CTL_CODE(uint DeviceType, uint Function, uint
Method, uint Access)
       {
           return(((DeviceType) << 16) | ((Access) << 14) | ((Function) <<
2) | (Method));
       }
//
// Set the Frequency of I2C device
//

Byte[] freq = new Byte[4];
Byte[] ba = BitConverter.GetBytes(i2CBus.I2C_SCLK_FREQ);
freq[0] = ba[3];
freq[1] = ba[2];
freq[2] = ba[1];
freq[3] = ba[0];

GCHandle handle = GCHandle.Alloc(freq, GCHandleType.Pinned);
IntPtr p = handle.AddrOfPinnedObject();
uint objectsize = freq.Length;

bool val = I2C.I2CIOControl(m_hI2c,
i2CBus.CTL_CODE(i2CBus.FILE_DEVICE_BUS_EXTENDER,
i2CBus.I2C_IOCTL_SET_FREQUENCY, i2CBus.METHOD_BUFFERED,
i2CBus.FILE_ANY_ACCESS), p, objectsize, IntPtr.Zero, 0, IntPtr.Zero);

Marshal.FreeHGlobal(p);
Ben Voigt [C++ MVP] - 09 Jun 2007 18:32 GMT
> I'm doing a IO Control function call to set a I2C device's frequency as
> the
[quoted text clipped - 10 lines]
> It is defined as a 4 byte array and the driver code casts this to a DWORD.
> The frequency value is not being set

Then you should declare the argument as "ref uint", which is the C#
equivalent to DWORD.

For low-level interaction with device drivers, though, I've always found
that C++/CLI is far superior to C#.

Just something like:

#include <winnt.h>

ref class PWM
{
public:
   property uint Frequency
   {
       void set(uint value);
   }
};

void PWM::Frequency::set(uint value)
{
   if (!I2CIOControl(m_hI2c, I2C_IOCTL_SET_FREQUENCY, &value, sizeof value,
nullptr, 0, nullptr))
       throw gcnew IOException("Failed to set PWM frequency to " +
value.ToString());
}

> --Device Code ---
> //
[quoted text clipped - 105 lines]
>
> Marshal.FreeHGlobal(p);
Ben Voigt [C++ MVP] - 09 Jun 2007 18:47 GMT
>> I'm doing a IO Control function call to set a I2C device's frequency as
>> the
[quoted text clipped - 32 lines]
>    }
> };

Of course you should connect to the driver in the PWM constructor, and
implement a destructor that closes it properly (C++ will translate your
destructor into an implementation of IDisposable).

> void PWM::Frequency::set(uint value)
> {
[quoted text clipped - 114 lines]
>>
>> Marshal.FreeHGlobal(p);

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.