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 18, 2012 at 10:12

Hi Marco,

Context.wTransferSize is set during LaunchOperation.

I guess it does not work because Context.szDeviceLink is wrong.

szDeviceLink is a single byte - not an array. It does contain the first character of the device path.

To write a hole string into it I use a simple pointer.

- Initialize the pointer with the address of Context.szDeviceLink

- Copy the first character of the string to the place the pointer points to

- Increment pointer

- Copy second character of string to the place the pointer points to

- Increment pointer

.. repeat for every character

In the end each byte does contain a single ascii char.

marcoandarcia9
Associate II
Posted on June 18, 2012 at 16:09

Hi, Jonas! 

It worked!!! I filled the Context.szDevice with the pointers and got the erase to work! 

Man I have been working this for like almost a month! I owe you a beer! lol let me know where I can mail it! 

seriously thank you very much for all the help!
marcoandarcia9
Associate II
Posted on June 20, 2012 at 20:34

Hi, Jonas

I already got my app to work, well sorft of, I am able to Erase, download and Unlock the board; however for some reason I cant perform 2 downloads in a row. for some reason the second time it throws an exception when I launch the download. I was wondering if you had the same issue.

Thanks in advance.  
marcoandarcia9
Associate II
Posted on June 21, 2012 at 23:35

Hi, Jonas

I am working on some upgrades for my app, and I was wondering if you made an structure for the ELEMENT structure on DFUFILE.H. I am having a little bit of trouble on getting the data out of the image. 

Thanks in advance.
erik239955_st
Associate II
Posted on June 25, 2012 at 18:00

The typedef for the DFUIMAGEELMENT struct in the STDFUPRTINC.h is the following

typedef struct 

{

  DWORD dwAddress;

  DWORD dwDataLength;

  PBYTE Data;

} DFUIMAGEELEMENT, *PDFUIMAGEELEMENT;You can access each data byte in the elements with the following code:/* intermediate variables */

DWORD NbElements;

DFUIMAGEELEMENT Element;

/* initialize Element memory to  zero */

memset(&Element, 0, sizeof(DFUIMAGEELEMENT));

/* get number of elements in image and check for error  */

if(STDFUFILES_GetImageNbElement(DfuImage, &NbElements) == STDFUFILES_NOERROR)

{

/* get data for each element in image */

for(int i = 0; i < NbElements; ++i)

{

/* get image element and check for error */

if(STDFUFILES_GetImageElement(DfuImage, 0, &Element) == STDFUFILES_NOERROR)

{

/* allocate memory for data array */

Element.Data = new BYTE[Element.dwDataLength];

/* get image element again - now that datalength is known and check for error */

if(STDFUFILES_GetImageElement(DfuImage, 0, &Element) == STDFUFILES_NOERROR)

{

/* loop through each data byte */

for(int j = 0; j < Element.dwDataLength; ++j)

{

// Do something with each data byte

BYTE bSomeByte = Element.Data[j];

}

}

}

}

}

erik239955_st
Associate II
Posted on June 25, 2012 at 18:30

TarSel is a variable to select the target for programming.  For example when you use STDFUPRT_CreateMappingFromDevice() you will notice that there are two alternates for a STM32F10xx part:

Internal Flash (TarSel = 0) 

Option Bytes (TarSel = 1)

Most of the example code I have seen only targets the Internal Flash so TarSel is typically hard-coded to zero.  I would actually like to program the Option Bytes (TarSel = 1), however this seems be difficult.  

I created a DFU file that contains two images, each with a single element. The first image has bAlternateSetting of 0 and is targeted for the internal flash.  The second image has a bAlternateSetting of 1 and is targetd for the option bytes.  

If I use TarSel = 0, the internal flash if programmed without any issue, however if I set the TarSel = 1, the Option bytes are not programmed.  

The only method that I can get the Option Bytes to program is to swap the image order in the DFU file.  I am not sure what the issue is, but I have vefiied that my code is selecting the correct image based on TarSel and the image seems to formated properly until I call the the STDFUFILES_FilterImageForOperation command any ideas?

Thanks

z4gunn

marcoandarcia9
Associate II
Posted on June 26, 2012 at 23:45

Hi, Jonas

I am currently working on my app, I got it to download, upload, erase, edit option bytes ... I was wondering if you are using DFU files or Hex files for your application. I got mine to work using DFU Files now I need to use .hex files But I cant get the signature for the STDFUFILES_ImageFromFile I was wondering if you got it to work.

thanks in advance.

kaczart
Associate II
Posted on June 27, 2012 at 14:05

I'd like thank you guys very much. I'm working just on update software in C# with dfu bootloader and this discussion helped me a lot, specially correct DFUThreadContext struct definition. Still have much things to do. If I go further I'll try to help also,

Thanks a lot! and keep in touch 😉

greetings

marcoandarcia9
Associate II
Posted on June 27, 2012 at 15:30

Hi, Arthur 

Yeah, when we started the thread nobody else tried to do this, I am trying to keep the thread alive, since  ST hasn't provided any revised documentation nor updated. If you get stuck write on this thread, I'll try my best to help. Haven't seen Jonas back on the thread for a while, lol he might have finished.

Good luck.
kaczart
Associate II
Posted on June 27, 2012 at 17:32

I'm still far away from final point. First of all I need to implement firmware update working with .dfu files, next with .hex files.

I'm thinking how to implement CreateMappingFromDevice function without using unsafe code. I declared MAPPING structures this way:

[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public
struct

MAPPING
{
public
byte

nAlternate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public
string

Name;
UInt32 NbSectors;
[MarshalAs(UnmanagedType.Struct, SizeConst=18)]
public

MAPPINGSECTOR pSectors;
}
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public
struct

MAPPINGSECTOR
{
public

UInt32 dwStartAddress;
public

UInt32 dwAliasedAddress;
public

UInt32 dwSectorIndex;
public

UInt32 dwSectorSize;
public
byte

bSectorType;
public
bool

UseForOperation;
}

but how to pass pointer to reference of MAPPING structure in function STDFUPRT_CreateMappingFromDevice have NO IDEA. It should be a way to do this without using unsafe code. Secondly - how to get value of argument pNbAlternates - is it always = 0 ? greetings!