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
jonas239955
Associate II
Posted on June 08, 2012 at 14:07

Finally I realized how to handle the mapping-pointer stuff. I used a simple, unmanaged struct for the mapping (because I need to set pointers to that struct). Here my code:

        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)]

        public unsafe struct UmMAPPING

        {

            [FieldOffset(0)]

            public byte nAlternate;

            [FieldOffset(1)]

            public char Name;

            [FieldOffset(261)]

            public UInt32 NbSectors;

            [FieldOffset(265)]

            public MAPPINGSECTOR* pSectors;

        }

UmMAPPING UmMapping;

UmMAPPING* pUmMapping = null;

error_code = STDFUPRT_CreateMappingFromDevice(Context.szDevLink, ref pUmMapping, ref pNbAlternates);

UmMapping = *pUmMapping;

error_code = STDFUFILES_CreateImageFromMapping(ref pHandle, ref UmMapping);

...

You will find the first two ascii letters in the property Name (0x49 = ''I'', 0x6e = ''n''). For my device the name of the first map is ''Internal Flash''. I used STDFU Tester to check that.

However it doesn't do anything. No exceptions/errors but also no erasing. I'm wondering if the example from ST is correct (complete) or if perhaps another function call is missing ....

jonas239955
Associate II
Posted on June 08, 2012 at 16:20

Struct DFUThreadContext seems to be wrong and therefore STDFUPRT_LaunchOperation() doesn't do anything. I did a simple test with the following code to check if the values in DFUThreadContext are placed in the correct order.

List<UInt32> test = new List<UInt32>();

test.Add((UInt32)(UInt32*)&Context.DFUGUID);

test.Add((UInt32)(UInt32*)&Context.APPGUID);                    

test.Add((UInt32)(UInt32*)&Context.Operation);

test.Add((UInt32)(UInt32*)&Context.bDontSendFFTransfersForUpgrade);

test.Add((UInt32)(UInt32*)&Context.hImage);

//test.Add((UInt32)(UInt32*)&Context.szDevLink);

test.Add((UInt32)(UInt32*)&Context.dwTag);

test.Add((UInt32)(UInt32*)&Context.percent);

test.Add((UInt32)(UInt32*)&Context.wTransferSize);

I expected the pointeraddresses increase constantly but they don't! It does not place one value after the other like in the definition of the struct. So I defined the struct with LayoutKind.Explicit and checked again - now they are in a row.

With this new struct STDFUPRT_LaunchOperation() returns error 0x12345008. There is no description of this error in UM0384. Does anyone know something about this error??
marcoandarcia9
Associate II
Posted on June 08, 2012 at 16:27

Hi Jonas! 

first of all thanks for sharing the code! it really helps a lot, I am having a little bit of trouble fixing the signatures for the dll import right now I have this. 

 [DllImport(''STDFUFILES.dll'', EntryPoint = ''STDFUFILES_CreateImageFromMapping'', CharSet = CharSet.Auto)]

        public static extern UInt32 STDFUFILES_CreateImageFromMapping(ref IntPtr handle, ref STDFUPRT.UmMAPPING* puMapping);

but is not compiling, I am not sure how to place the pointer parameter in the signature. 

I was wondering if I could see yours. 

Thanks. 

Marco.
jonas239955
Associate II
Posted on June 08, 2012 at 16:37

Remove *. It's already a reference because of ''ref'' 🙂

Ps:

In c++ source code I found those lines:

#define STDFUPRT_ERROR_OFFSET                (0x12340000+0x5000)

#define STDFUPRT_BADPARAMETER                (STDFUPRT_ERROR_OFFSET+0x0008)

obviously error 0x12345008 says there is a bad parameter. hmmm.. doesn't help me a lot. Two months ago as I started this discussion I had the same error - annoying.

marcoandarcia9
Associate II
Posted on June 08, 2012 at 17:05

so you declaration looks like this?

[DllImport(''STDFUPRT.dll'', EntryPoint = ''STDFUPRT_CreateMappingFromDevice'', CharSet = CharSet.Auto)]

public static extern UInt32 STDFUPRT_CreateMappingFromDevice([MarshalAs(UnmanagedType.LPStr)]string DFUNAME, ref STDFUPRT.UmMAPPING puMapping, ref UInt32 pNbAlternates);

I am super confused with this,  because when you call your function you pass the pointer. 

''STDFUPRT_CreateMappingFromDevice(Context.szDevLink, ref pUmMapping, ref pNbAlternates);''

 

sorry if these are too elemental questions, I don't have too much experience with this.

thanks in advance. 
jonas239955
Associate II
Posted on June 08, 2012 at 17:23

you probably mixed up the two functions. they need different parameter:

CreateImageFromMapping: it demands a reference so put ref but no *

-> ref STDFUPRT.UmMAPPING puMapping

CreateMappingFromDevice: it demands a reference to a reference so put both * and ref and use unsafe

-> ref STDFUPRT.UmMAPPING* puMapping

marcoandarcia9
Associate II
Posted on June 08, 2012 at 17:42

ugh, sorry man you are totally right. 

Thanks! 

I'll let you know If I have any progress by the en of the day ... lol forum time seems to be european time ... here is just 10:40 AM ... 

Have a good Weekend!

jonas239955
Associate II
Posted on June 08, 2012 at 17:52

There must be an error in UM0384 table 13 DFUThreadContext class.

Field Operation has a size of 4. If I change this I do not receive the error above but an AccessViolationException. There are probably even more mistakes in this manual.

Could anyone from ST PLEASE verify this???

PS:

Good luck marco

cheers, till Monday

marcoandarcia9
Associate II
Posted on June 08, 2012 at 21:53

Hi, jonas 

I've been working on the launchOperation function but it's giving me the bad parameter error all day. 

This is how my signature looks like. 

[DllImport(''STDFUPRT.dll'', EntryPoint = ''STDFUPRT_LaunchOperation'', CharSet = CharSet.Auto)]

public static extern UInt32 STDFUPRT_LaunchOperation(ref STDFUPRT.DFUThreadContext Context, ref UInt32 Operation);

I am not sure if I should pass the pointer as we did before for Mapping.

Another Question is for the Operation Code what number did you pass? I passed 3 as they did in the source code.  Also do you know what the variable TarSel does? there is no reference whatsoever in the manual

jonas239955
Associate II
Posted on June 11, 2012 at 09:26

Your signature is okay - nothing wrong with that. How does your DFUThreadContext struct look like? I did receive the same badparameter-error like I wrote some post ago and therefore looked through the source code of STDFUPRT_LaunchOperation(). There is only one way to get that error: Context.Operation must be anything else than 0 - 4. I used to set Operation to 3 (erase). If you set bDontSendFFTransfersForUpgrade to false the error doesn't show up (but I get an access violation). So I assume the size of the Operation-value must be 4 and not 2 like UM384 tells us.