Skip to main content
T J
Senior III
August 27, 2018
Question

Structure confusion DMA_HandleTypeDef vs __DMA_HandleTypeDef

  • August 27, 2018
  • 8 replies
  • 3525 views

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;

    This topic has been closed for replies.

    8 replies

    Tesla DeLorean
    Guru
    August 27, 2018

    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    T J
    T JAuthor
    Senior III
    August 27, 2018

    the structure reference/name ?

    DMA_HandleTypeDef

    and this is ?

    __DMA_HandleTypeDef

    Tesla DeLorean
    Guru
    August 27, 2018

    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    T J
    T JAuthor
    Senior III
    August 27, 2018

    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;

    Gudgel.boB
    Senior
    March 8, 2019

    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
    Super User
    March 8, 2019

    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
    March 8, 2019

    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

    ???

    Bob S
    Super User
    March 8, 2019

    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
    March 10, 2019

    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 !

    Bob S
    Super User
    March 11, 2019

    Nothing is thrown away. The naming convention may be helping to confuse you. After the structure has been fully defined, there are 2 ways to reference the structure, both are equivalent:

    struct __DMA_HandleTypeDef hdma1; // Using "struct" with the structure name
    DMA_HandleTypeDef hdma2; // Using the typedef name without "struct"

    Both hdma1 and hdma2 are the same structure, and the compiler will (should?) treat them as identical types. To use the name that starts with underscores you always need the "struct" before it. To use the name that does not start with underscores, you never need (and cannot use) the "struct". That is what the "typedef" does - gives you an alias name for "struct whatever" for all of us lazy programmer who don't want to type any more than we have to :)

    Maybe if the structure were defined this way it might make it clearer:

    typedef struct dummyname {
     int avar;
     //... more variables
     struct dummyname *mydmahandle;
    } DMA_HandleTypeDef;

    Now "struct dummyname" and "DMA_HandleTypeDef" both refer to the same structure.

    Gudgel.boB
    Senior
    March 11, 2019

    Bob, thank you ! I now understand this issue clear as day !

    I knew about 1/4 of this but my understanding is MUCH better now !

    Consternation turned to lucidation

    boB (spelled backwards to avoid confusion)

    =)