cancel
Showing results for 
Search instead for 
Did you mean: 

Structure confusion DMA_HandleTypeDef vs __DMA_HandleTypeDef

T J
Lead

This code is from STM32H7xx_hal_dma.h

what is __DMA_HandleTypeDef describing ?

is it weak ? for what purpose ?

typedef struct __DMA_HandleTypeDef
{
  void                            *Instance;                   /*!< Register base address                       */
  DMA_InitTypeDef                  Init;                /*!< DMA communication parameters   */
  HAL_LockTypeDef                 Lock;             /*!< DMA locking object                             */
  __IO HAL_DMA_StateTypeDef       State;  /*!< DMA transfer state                */
  void                            *Parent;                     /*!< Parent object state                 */
.
.
.

Now please, the confusion;

What is DMA_HandleTypeDef describing ?

how is it different ?

.
.
.
DMAMUX_RequestGenStatus_TypeDef  *DMAmuxRequestGenStatus;  /*!< DMAMUX request generator Status Address       */
 uint32_t                         DMAmuxRequestGenStatusMask;   /*!< DMAMUX request generator Status mask          */
}DMA_HandleTypeDef;

11 REPLIES 11

It is the name of the structure you are typedef'ing

Useful if you're referring to it in another structure.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
T J
Lead

the structure reference/name ?

DMA_HandleTypeDef

and this is ?

__DMA_HandleTypeDef

The first is the name of the typedef, the latter is the name of the structure itself.​

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
T J
Lead

I was just trying to gain more understanding by looking through the code.

when I search for that "name of the structure " __DMA_HandleTypeDef

its used within the structure, I guess like a pointer (index=0) relative to itself.

anyhow, this line from within snippet below, is confusing

void  (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);

/**
  * @brief  DMA handle Structure definition
  */
typedef struct __DMA_HandleTypeDef
{
void  *Instance;                                                        /*!< Register base address                         */
.
.
void  *Parent;                                                          /*!< Parent object state
void  (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);         /*!< DMA transfer complete callback 
void  (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma);     /*!< DMA Half transfer complete callback  
void  (* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma);       /*!< DMA transfer complete Memory1 callback 
void  (* XferM1HalfCpltCallback)( struct __DMA_HandleTypeDef * hdma);   /*!< DMA transfer Half complete Memory1 callback
void  (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);        /*!< DMA transfer error callback                   
void  (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma);        /*!< DMA transfer Abort callback 
.
.
 
}DMA_HandleTypeDef;

I have also wanted to know what this difference was.

I think that the __DMA_HandleTypeDef name at the beginning may be optional ??

Bob S
Principal

Yes, the structure name (__DMA_HandleTypeDef) is optional, but some coding standards require to be present.

The line:

void  (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); 

from the structure definition is declaring a pointer to a function. This function takes one parameter, and that parameter is a pointer to this structure. The function has a return type of "void". The name of the function pointer is XFerCpltCallback. Note that this declaration has to use the "struct STRUCTNAME" construct because at this point in the structure's definition the structure is not complete and there is no concept of "DMA_HandleTypeDef". Which is why they needed to provide the optional structure name.

Gudgel.boB
Senior

Bob, thank you ! I ~think~ that I understand that ?

If I'm reading your description correctly, and going on what I think I know (which is lacking), the structure name __DMA_HandleTypeDef can be used as a pointer to the structure, for instance,

__DMA_HandleTypeDef spConfig

spConfig->Init = xxxxx

but using a reference to the bottom name, DMA_HandleTypeDef can not be pointed to and would require usage such as...

DMA_HandleTypeDef sConfig

sConfig.init = xxxxx

???

Not quite - it is not a "instance" vs. "pointer to instance" issue. It is about compile-time information and when the compiler "knows" about "struct __DMA_HandleTypeDef" vs. when it knows about "typedef DMA_HandleTypeDef".

When dealing with "pointers to structures", which the callback function declaration uses, the compiler only needs to know that the structure is GOING TO BE fully defined, even if it is not fully defined YET. For example, this is valid code:

// This is a partial declaration of the structure, and serves the same purpose
// as the forward declaration of SomeFunction() below;
struct mystruct; 
 
// Forward declaration of SomeFunction(), and also serves and the function prototype.
// We cannot define the body of this function yet, because "mystruct" is not
// yet fully defined.
void SomeFunction( struct mystruct *p );
 
// Fully defined structure.
struct mystruct {
   int something;
   long somethingelse;
};
 
// And now we can provide the full function definition.
void SomeFunction( struct mystruct *p )
{
   // do something with p->something
}

Now, in the "struct __DMA_HandleTypeDef" definition, when we get to the callback function line, "struct __DMA_HandleTypeDef" is known to (eventually) be a fully defined structure. That means we can declare a pointer to that structure. At this point, the compiler has not yet processed the typedef name "DMA_HandleTypeDef", so as far as the compiler is concerned, "DMA_HandleTypeDef" does not exist. And this why they can't use "DMA_HandlerTypeDef *hdma".

It there were a different structure that had a callback function that took a pointer to a DMA typedef structure, you COULD use the typedef name "DMA_HandleTypeDef", because this is outside the structure definition, so the typedef name is known to the compiler.

Hopefully this is a little bit clearer. Compiler internals sometimes take a while to wrap your head around.

Gudgel.boB
Senior

Thank you Bob. So, the "forward reference" to the struct to be defined is the prototype (what I would normally call it) but forward reference might be a better name...

I'm still unsure if the compiler (preprocessor ?) throws away the __ in front of DMA_HandleTypeDef

or just interprets the DMA_HandleTypeDef with and without those two designations as having any relevancy to each other after the structure is fully defined ?

I suppose that if I could watch each and every step of the preprocessor and compiler handle the actions taken in "slow motion", I might understand it more fully.

Yes, it does take a bit of wrapping my head around... I can make structures work for me but I don't always know exactly why.

Really appreciate the time you have taken here !