HardFault upon calling WM_SetUserData

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • HardFault upon calling WM_SetUserData

    Hi

    Environment: emWin + MDK + MDK-RTOS + STM32F429NI.

    After creating many windows/handles I'm getting a HardFault when I call WM_SetUserData. hWin is around 300 (not always the same). I've commented out the code calling the crash point but all that happens is the next new window fails when it tries to set the user data. I developed the code under embOS-SIM on Win32 and it works fine there so I suspected the problem may be GUI_Conf memory allocation but I doubled the allocation and made sure both (emWinSim and MDK) are the same (0x01000000 of uint32_t).

    Unfortunately I'm bringing the board up for the first time and do not yet have emSpy going.

    Is there a limit in MDK emWin to the number of windows/handles?

    Do you have any suggestions to point me in a direction which may help me solve this?

    Thanks
    Mark

    Source Code

    1. GUI_HWIN WMX_CreatehWin(WMX* pX, WMX* pP) {
    2. if (pP > 0) {
    3. pX->hWin = WM_CreateWindowAsChild(
    4. 0, 0, WMX_DEFAULT_WIDTH, WMX_DEFAULT_HEIGHT,
    5. hWinX(pP),
    6. WM_CF_HIDE,
    7. _cb,
    8. sizeof(WMX*));
    9. }
    10. else {
    11. pX->hWin = WM_CreateWindow(
    12. 0, 0, WMX_DEFAULT_WIDTH, WMX_DEFAULT_HEIGHT,
    13. WM_CF_HIDE,
    14. _cb,
    15. sizeof(WMX*));
    16. }
    17. WM_SetUserData(pX->hWin, &pX, sizeof(WMX*));
    18. return pX->hWin;
    19. }
    Display All
  • Hi,

    I think you should check pX->hWin first when you call WM_SetUserData.

    if (pX->hWin) WM_SetUserData(pX->hWin, &pX, sizeof(WMX*));

    In GUIConfig.c set memory size used by emWin:

    #define GUI_NUMBYTES (1024L * 32)

    static U32 aMemory[GUI_NUMBYTES / 4];
    //
    // Assign memory to emWin
    //
    GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);


    Regard,
    chensie

    The post was edited 1 time, last by chensie ().

  • Thanks.

    I'd like a response from the great team at Segger who are always knowledgeable and helpful!

    Chensie...
    (a) it not that I have simply set my memory up wrong. I am using the same GUI_Conf assign on emWin-SIM and that works fine. Also, as a just-in-case, I allocated it a lot more memory and it still failed at the same point.
    (b) yes, I could have a trap to check for valid pX and pX->hWin but I don't need them and have confirmed that both pX and pX->hWin are valid (hwin being around 300) when it crashes to hard fault.

    I am not saying it is not a memory corruption (that I have inadvertently written that space) but as WM_SetUserData is in a compiled library I cannot work out what it may be.
  • Hi,

    I gave it a try and on my end it is working. Please try the code below:

    C Source Code

    1. #include "DIALOG.h"
    2. /*********************************************************************
    3. *
    4. * Externals
    5. *
    6. **********************************************************************
    7. */
    8. /*********************************************************************
    9. *
    10. * Defines
    11. *
    12. **********************************************************************
    13. */
    14. #if (GUI_VERSION < 54400)
    15. #define WM_USER_DATA 52
    16. #endif
    17. /*********************************************************************
    18. *
    19. * Static data
    20. *
    21. **********************************************************************
    22. */
    23. typedef struct {
    24. int Data;
    25. WM_HWIN hWin;
    26. } WMX;
    27. /*********************************************************************
    28. *
    29. * Static code
    30. *
    31. **********************************************************************
    32. */
    33. /*********************************************************************
    34. *
    35. * _cb
    36. */
    37. static void _cb(WM_MESSAGE * pMsg) {
    38. static WMX * pWMX_Data;
    39. switch (pMsg->MsgId) {
    40. case WM_USER_DATA:
    41. WM_GetUserData(pMsg->hWin, &pWMX_Data, sizeof(WMX*));
    42. break;
    43. case WM_PAINT:
    44. GUI_SetBkColor(GUI_RED);
    45. GUI_Clear();
    46. break;
    47. default:
    48. WM_DefaultProc(pMsg);
    49. break;
    50. }
    51. }
    52. /*********************************************************************
    53. *
    54. * WMX_CreatehWin
    55. */
    56. GUI_HWIN WMX_CreatehWin(WMX * pX, WMX * pP) {
    57. if (pP > 0) {
    58. pX->hWin = WM_CreateWindowAsChild(0, 0, 80, 80, WM_HBKWIN, WM_CF_HIDE, _cb, sizeof(WMX*));
    59. } else {
    60. pX->hWin = WM_CreateWindow(0, 0, 80, 80, WM_CF_HIDE, _cb, sizeof(WMX*));
    61. }
    62. WM_SetUserData(pX->hWin, &pX, sizeof(WMX*));
    63. return pX->hWin;
    64. }
    65. /*********************************************************************
    66. *
    67. * _cbBk
    68. */
    69. static void _cbBk(WM_MESSAGE * pMsg) {
    70. switch (pMsg->MsgId) {
    71. case WM_PAINT:
    72. GUI_SetBkColor(GUI_BLACK);
    73. GUI_Clear();
    74. break;
    75. default:
    76. WM_DefaultProc(pMsg);
    77. break;
    78. }
    79. }
    80. /*********************************************************************
    81. *
    82. * Public code
    83. *
    84. **********************************************************************
    85. */
    86. /*********************************************************************
    87. *
    88. * MainTask
    89. */
    90. void MainTask(void) {
    91. static WMX WMX_Data;
    92. GUI_Init();
    93. WM_SetCallback(WM_HBKWIN, _cbBk);
    94. WMX_CreatehWin(&WMX_Data, &WMX_Data);
    95. while (1) {
    96. GUI_Delay(100);
    97. }
    98. }
    99. /*************************** End of file ****************************/
    Display All
    Regards,
    Sven
  • Hi Sven

    Sorry for delay, I was working on another part of the project.

    Thanks for the code. Yes, of course that code works as it is the standard code and the same I have been using for a couple of years.

    When I get a crash the WM_Create is returning a valid hWin and my pX is a valid address. The sizeof() is valid, too. So, if the hWin is valid, the pX a valid location and the length parameter acceptable why would WM_SetUserData fail? My only guess would be memory corruption of the allocated GUI memory not of the Heap - correct? Or can you think of something else?

    Thanks
    Mark
  • Hi Sven

    I think I have tracked down the issue and it is not emWin (no surprise, right!).

    Problem is that I am getting stack corruption during the time the _cb is handled after I call WM_SetUserData: I am finding that _cb pMsg content is inexplicably changing and the PC is also getting corrupted resulting in the code jumping back to a prior line in debug. I think the corruption is related to the MDK FS using SDIO + DMA as (a) the problem only occurs if I do a FS_Read before the WM_Create, (b) the corrupted pMsg contains 0x0A0D ie new lines (and I am reading an inifile).

    Thanks for considering my comments.
    Mark
  • Hi again

    Just to close out the problem was down to porting from an earlier version of emWin. The version I've been developing under does not call _cb when SetUserData gets called. In my _cb I had a var that was not initialised until after the SetUserData call and this was resulting in stack corruption in the _cb.

    Your code snippet pointed me in the direction as it indicated that _cb was being called by SetUserData.

    Thanks
    Mark