Skip to main content
jonas239955
Associate II
April 12, 2012
Question

Accessing ST Dfuse DLL with C#

  • April 12, 2012
  • 52 replies
  • 9972 views
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
This topic has been closed for replies.

52 replies

marcoandarcia9
Associate III
June 18, 2012
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 III
June 20, 2012
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 III
June 21, 2012
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
June 25, 2012
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
June 25, 2012
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 III
June 26, 2012
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
Visitor II
June 27, 2012
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 III
June 27, 2012
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
Visitor II
June 27, 2012
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!
marcoandarcia9
Associate III
June 27, 2012
Posted on June 27, 2012 at 22:42

Hi, Arthur

I tried to do it without Unsafe code, but the thing is that the structure has a pointer to a pointer, for the mapping sector, I have no clue how to do it without pointers, plus the documentation isawful. The Alternate is for Internal Flash, Option Bytes, etc etc .. it goes from 0 to 4. Here is how you can create the mapping.

#region DLL Imports
[DllImport(
''STDFUPRT.dll''
, EntryPoint = 
''STDFUPRT_CreateMappingFromDevice''
, CharSet = CharSet.Auto)]
unsafe
public
static
extern
UInt32 STDFUPRT_CreateMappingArrayFromDevice([MarshalAs(UnmanagedType.LPStr)]
string
DFUNAME, 
ref
STDFUPRT.UmMAPPING*[] pumMapping, 
ref
UInt32 pNbAlternates);
#endregion
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public
struct
MAPPINGSECTOR
{
public
UInt32 dwStartAddress;
public
UInt32 dwAliasedAddress;
public
UInt32 dwSectorIndex;
public
UInt32 dwSectorSize;
public
byte
bSectorType;
public
byte
UseForOperation;
}
[StructLayout(LayoutKind.Explicit, Pack = 1, 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;
}

The arrays indexes give you option bytes etc etc, please let me know if you can get it to work without the unsafe code. Good Luck.