cancel
Showing results for 
Search instead for 
Did you mean: 

Accessing ST Dfuse DLL with C#

jonas239955
Associate II
Posted on April 12, 2012 at 10:26

To integrate firmware update functionality into a custom c♯ application I start to use ST Dfuse dll from c♯. I managed to enumerate and identify the device (UM0392 - 3.1 and 3.2) but now get stucked  while trying to erase the device. Out of the manual:

DWORD OperationCode;

PDWORD pNbAlternates;

PMAPPING pMapping;

PHANDLE pHandle;

// Programming the operation contex

lstrcpy(Context.szDevLink, DFUName);

Context.DfuGUID=GUID_DFU;

Context.AppGUID=GUID_APP;

Context.Operation=OPERATION_ERASE;

Context.bDontSendFFTransfersForUpgrade= TRUE;

STDFUPRT_CreateMappingFromDevice((LPSTR)(LPCSTR)DFUName,&pMapping, &NbAlternates);

STDFUFILES_CreateImageFromMapping(pHandle, pMapping);

STDFUFILES_FilterImageForOperation(hImage, m_pMapping+TargetSel,

OPERATION_ERASE, FALSE);

Context.hImage=hImage;

if( STDFUPRT_LaunchOperation(&Context, &OperationCode) != STDFUPRT_NOERROR)

{

Printf(�Erase error�);

}

The call of STDFUPRT_LaunchOperation() does always return a STDFUPRT_BADPARAMETER error.

Is there a way to get some more information about this error? Which parameter is bad?

The first parameter in LaunchOperation() is a pointer to the struct DFUThreadContext. I rebuilt this struct in c♯ using the information given in UM0384.pdf chapter 4.3.4. My UM0384 is revision 1 - June 2007 - wonder if that user manual is still up-to-date?!?

I did not find UM0384 on the webpage (my copy is out of the package UM0412.zip). Does anyone have a newer one?

Thanks in advance for any help

#st-dfu #st-dfuse #dfuse
52 REPLIES 52
assaf2
Associate
Posted on August 29, 2012 at 15:51

Hi Arthur,

Please try the following implementation:

        private Mapping[] getDeviceMemoryMapping()

        {

            int         stRetVal;                           /*ST's error code*/

            int         numberOfAlternates;                 /*The number of memory units that are exposed for DFU operations*/

            bool        sectorsInitialized;                 /*Monitor the sector initialization process*/

            byte[]      devLinkArray;                       /*Holds the device path*/

            IntPtr      pMapping, currentMapping, pDevLink; /*Various pointers*/

            GCHandle    byteArrayHandle;                    /*Prevent GC from moving the byte array while passing its address*/

            DFU_Mapping dfuMapping;                         /*ST's mapping structure*/

            Mapping[]   mapping;                            /*return value*/

            mapping             = null;

            stRetVal            = 0;

            numberOfAlternates  = 0;

            sectorsInitialized  = true;

            pMapping            = IntPtr.Zero;

            pDevLink            = IntPtr.Zero;

            dfuMapping          = new DFU_Mapping();

            devLinkArray        = new byte[Utilities.BUFFER_SIZE];

            /*Prevents GC from moving devLinkArray while it's address is passed to ST's unfriendly function*/

            byteArrayHandle = GCHandle.Alloc(devLinkArray, GCHandleType.Pinned);

            try

            {

                pDevLink = Marshal.UnsafeAddrOfPinnedArrayElement(devLinkArray, 0);

                Marshal.Copy(new ASCIIEncoding().GetBytes(usbDevice.Path), 0, pDevLink, usbDevice.Path.Length);

                stRetVal = DFU_Wrapper.STDFUPRT_CreateMappingFromDevice(ref devLinkArray[0], out pMapping, ref numberOfAlternates);

                if (stRetVal == (int)DFU_FilesReturnCodeType.NoError && numberOfAlternates > 0)

                {

                    currentMapping = pMapping;

                    mapping = new Mapping[numberOfAlternates];

                    for (int i = 0; ((i < numberOfAlternates) && sectorsInitialized); i++, currentMapping = Utilities.IncrementIntPtr(currentMapping, Marshal.SizeOf(typeof(DFU_Mapping))))

                    {

                        dfuMapping          = (DFU_Mapping)Marshal.PtrToStructure(currentMapping, typeof(DFU_Mapping));

                        mapping[i]          = new Mapping(dfuMapping);

                        mapping[i].PMapping = currentMapping;

                        sectorsInitialized  = mapping[i].InitializeSectors();

                    }

                }

                else/*ST error or illegal state*/

                {

                    if (stRetVal != (int)DFU_FilesReturnCodeType.NoError)

                        onDeviceError(usbDevice.Identifier, ErrorType.DFU_CouldReadMemoryMapping, new object[] { stRetVal });

                    else

                        onDeviceError(usbDevice.Identifier, ErrorType.DFU_CouldReadMemoryMapping, new object[] { ''Memory units for DFU usage were not found'' });

                }

            }

            catch (Exception e)

            {

                mapping = null;

                onDeviceError(usbDevice.Identifier, ErrorType.DFU_CouldReadMemoryMapping, new object[] { e.Message });

            }

            finally { byteArrayHandle.Free(); }

            return mapping;

        }

Hope this helps,

Assaf

assaf2
Associate
Posted on August 29, 2012 at 16:02

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6bO&d=%2Fa%2F0X0000000bra%2FjDn3.1g.dFJaXngC4RtexiFDjnmD7NjMRdMIkjUYgNI&asPdf=false
markmclean9
Associate II
Posted on January 18, 2013 at 16:36

Hi,

I'm also trying to write some C# code to do the ST DFU erase and download.  What you've got here looks very useful ,and I'll have a dig thru it on Monday, but I wondered if any of the posters had a complete working .net app they they could post somewhere (eg. Code Project), I'm sure it would be very useful to other people too.

Cheers,

Mark