GUI_Init() never returns (again) [SOLVED]

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

    • GUI_Init() never returns (again) [SOLVED]

      Hi to all,

      I have a self made STM32F750N8H6 board with external SDRAM, QSPI Flash and a 800x480 TFT Panel attached. Panel displays Images, code is executing from SDRAM, Framebuffer is in SDRAM, too. SO far everything looks good.
      While this hardware was being manufactured I started application development on a STM32F746 Discovery board. STemWin applicaiton was running well there using FreeRTOS.

      SDRAM is mapped to 0x6000000 to allow code execution. That worked well on the discovery board.

      Now I tried to port that application to my STM32F750 board, which has quite different I/Os and such, so I created a new Project with STM32CubeMX (unfortunately the latest version that doesnÄt support graphics initialization any more) and copied all related files from my dicovery-board project the new one (or at least I assume I did so).

      Project compiles well. But as soon as the StartDefaultTask() calls GUI_Init() this function never returns. Stopping the debugger it tells me that GUI_Init() stops in an intened endless loop! I marked the position of the program counter with an error on the code below:

      Source Code

      1. GUI_Init:
      2. 60034c25: push {r4, r7, lr}
      3. 60034c27: sub sp, #12
      4. 60034c29: add r7, sp, #0
      5. 60034c2b: ldr r2, [pc, #336] ; (0x60034d7c <GUI_Init+344>)
      6. 60034c2d: ldr r3, [pc, #332] ; (0x60034d7c <GUI_Init+344>)
      7. 60034c2f: ldr r3, [r3, #0]
      8. 60034c31: bic.w r3, r3, #1
      9. 60034c35: str r3, [r2, #0]
      10. 60034c37: ldr r3, [pc, #328] ; (0x60034d80 <GUI_Init+348>)
      11. 60034c39: ldr r3, [r3, #0]
      12. 60034c3b: ubfx r3, r3, #0, #11
      13. 60034c3f: movw r2, #1097 ; 0x449
      14. 60034c43: cmp r3, r2
      15. 60034c45: ite eq
      16. 60034c47: moveq r3, #1
      17. 60034c49: movne r3, #0
      18. 60034c4b: uxtb r2, r3
      19. 60034c4d: ldr r3, [pc, #304] ; (0x60034d80 <GUI_Init+348>)
      20. 60034c4f: ldr r3, [r3, #0]
      21. 60034c51: ubfx r3, r3, #0, #11
      22. 60034c55: movw r1, #1105 ; 0x451
      23. 60034c59: cmp r3, r1
      24. 60034c5b: ite eq
      25. 60034c5d: moveq r3, #1
      26. 60034c5f: movne r3, #0
      27. 60034c61: uxtb r3, r3
      28. 60034c63: orrs r3, r2
      29. 60034c65: uxtb r3, r3
      30. 60034c67: mov r1, r3
      31. 60034c69: ldr r3, [pc, #276] ; (0x60034d80 <GUI_Init+348>)
      32. 60034c6b: ldr r3, [r3, #0]
      33. 60034c6d: ubfx r3, r3, #0, #11
      34. 60034c71: movw r2, #1106 ; 0x452
      35. 60034c75: cmp r3, r2
      36. 60034c77: ite eq
      37. 60034c79: moveq r3, #1
      38. 60034c7b: movne r3, #0
      39. 60034c7d: uxtb r3, r3
      40. 60034c7f: orrs r3, r1
      41. 60034c81: cmp r3, #0
      42. 60034c83: beq.n 0x60034ca6 <GUI_Init+130>
      43. 60034c85: ldr r3, [pc, #252] ; (0x60034d84 <GUI_Init+352>)
      44. 60034c87: movs r2, #1
      45. 60034c89: str r2, [r3, #0]
      46. 60034c8b: nop
      47. 60034c8d: ldr r3, [pc, #244] ; (0x60034d84 <GUI_Init+352>)
      48. 60034c8f: ldr r3, [r3, #0]
      49. 60034c91: cmp r3, #0
      50. 60034c93: bne.n 0x60034c8c <GUI_Init+104>
      51. 60034c95: ldr r3, [pc, #240] ; (0x60034d88 <GUI_Init+356>)
      52. 60034c97: ldr r2, [pc, #244] ; (0x60034d8c <GUI_Init+360>)
      53. 60034c99: str r2, [r3, #0]
      54. 60034c9b: ldr r3, [pc, #236] ; (0x60034d88 <GUI_Init+356>)
      55. 60034c9d: ldr r3, [r3, #0]
      56. 60034c9f: ldr r2, [pc, #240] ; (0x60034d90 <GUI_Init+364>)
      57. 60034ca1: cmp r3, r2
      58. 60034ca3: beq.n 0x60034cd6 <GUI_Init+178>
      59. => 60034ca5: b.n 0x60034ca4 <GUI_Init+128>
      60. 60034ca7: ldr r3, [pc, #236] ; (0x60034d94 <GUI_Init+368>)
      61. 60034ca9: ldr r3, [r3, #0]
      62. 60034cab: ubfx r3, r3, #0, #11
      63. 60034caf: cmp.w r3, #1104 ; 0x450
      Display All

      Since I do not have source code of GUI_Init() my question is: What causes GUI_Init() to stop in an endless loop? I guess I am missing something very basic, a simple error I made while porting my project from discovery to final hardware, but I have no clue where to start looking for.

      I have read the threads regarding MPU settings and HardFaults. But I am definitely not stuck in a HardFault, to me it looks like GUI_Init() never returns intentionally.

      Thank you all for any hint.

    • Hi,

      GUI_Init() calls three functions accessible by the user.

      First is GUI_X_Config() in this function a memory block gets assigned to emWin.
      Second is LCD_X_Config(), in this function the emWin driver gets set up.
      LCD_X_DisplayDriver(), typically the LCD conttroller gets initialized here.

      You can check if you get into these functions, if don't get into LCD_X_DisplayDriver() but you where in LCD_X_Config(), there must be something wrong in between.

    • Thank you for the fast reply. I will try within the next few hours.

      So I understand correctly: There is no such thing as an endless loop wihin GUI_Init()? Because to me it looks like there is one.

    • Did the suggested test and set a breakpoint at the start of GUI_X_Config(), GUI_X_Config() and GUI_X_Config().

      But none of them gets called before my app hangs in GUI_Init().

      As can be seen in the assembler listing above there is not a single subroutine call between the start of GUI_Init() and the endless loop within that same GUI_Init().

      So if Segger says, that there is no such thing as an endless loop in GUI_Init(), what are the remaining possibilities?

      * Did I link the wrong library and a non-standard GUI_Init() gets called? My linker configuration says: "STemWin_CM7_OS_wc32_ot_ARGB.a" which I copied from the working discovery-board project.

      * Since the application is running in RAM, was it overwritten? I don't think so, because in the *.lst file this part of code looks exactly as it does in the disassembler.

      Any other ideas or suggestions?

    • Still not working.

      But I found the ST application note AN5426 "Migrating graphics middleware projects from STM32CubeMX 5.4.0 to STM32CubeMX 5.5.0" and there is an interesting section that states:

      Add the GRAPHICS_IncTick function prototype as extern:

      C Source Code

      1. /* USER CODE BEGIN EV */
      2. extern void GRAPHICS_IncTick(void);
      3. /* USER CODE END EV */

      Insert GRAPHICS_IncTick call in SysTick_Handler:

      C Source Code

      1. /* USER CODE BEGIN SysTick_IRQn 0 */
      2. GRAPHICS_IncTick();
      3. /* USER CODE END SysTick_IRQn 0 */
      But neither in my (working) old project nor in my current (hanging) project there gets this "GRAPHICS_IncTick(void)" called anywhere.

      Might this be a clue to my issues? Did my discovery board project run just by chance?


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

    • Hi,

      the very first thing which is called in GUI_Init() is a macro which is defined as GUI_X_Log().

      GUI_X_Log() is typically implemented in the file GUI_X.c and user defined.

      Do you call some sort of printf() (or anything else to get some debug output) within GUI_X_Log()?
      This might lock the application.

      Next in GUI_Init() is a function pointer which can be set to call some user code before emWin starts its initialization. If this pointer is not set, nothing gets called.

      Right after that a call to GUI_X_Config() gets performed.

      So, if you don't get inot GUI_X_Config() there is either something wrong with the implementation of GUI_X_Log() or you have set a pre-initi-callback which hangs.


    • Thank you for the hint. Checked it, but GUI_X_Log() is simply an empty function in my GUI_X.c.

      But I did some analysis by stepping through first view instructions of GUI_Init() and found that my problem seems to be some license check issues. Is that possible?

      The code first checks some of the FPB_Remap register contents (which are 0x449 in my case) and then calculates something using CRC unit. And if that calculation gives not the expected result, it hangs forever.

      I do use the CRC unit in my code, too. So I initialize it as as required by my application:

      C Source Code

      1. hcrc.Instance = CRC;
      2. hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
      3. hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
      4. hcrc.Init.InitValue = 0x33b2363a;
      5. hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
      6. hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
      7. hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS;
      8. if (HAL_CRC_Init(&hcrc) != HAL_OK)
      9. {
      10. Error_Handler();
      11. }
      Display All

      Is this the issue?

      I found nothing in the manuals about a special required CRC initialization for STemWIN. But it is so, which initialization do I have to use?

      Update: Just checked without any special CRC initialization. Only clock to CRC is enabled as stated in STM32 AN4323 . But same result, License check in GUI_init() fails for my hardware.


      The post was edited 2 times, last by t2ft: Updated info ().


      The problem was not only CRC usage in main application, but I also used the CRC in my boot-loader to verify application data in QSPI-Flash.

      And HAL_CRC_DeInit() does *not* reset CRC to its reset state. It keeps INIT and POLY values untouched!

      But a dedicated HAL_CRC_Init() with default reset values did the trick:

      C Source Code

      1. hcrc.Instance = CRC;
      2. hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
      3. hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
      4. hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
      5. hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
      6. hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS;
      7. if (HAL_CRC_Init(&hcrc) != HAL_OK)
      8. {
      9. Error_Handler();
      10. }
      Is there some official documentation anywhere available about the CRC usage of emWIN? Maybe I should bookmark it not to forget it in my next project...

    • Hi,

      emWin is completely independent of any hardware and any third party software.
      Also, there is no license check of CRC init within emWin.

      The libraries you are using are generated by STM , so I can not say if they build in some sort of license check (although they shouldn't).

      Maybe you should try to contact STM.

    • Thank you for the clarification.

      Now since I know what I have to look for, the search items "GUI_Init()" and "CRC" in the ST-Communinty Formum shows up the appropriate answers.

      Shame on ST that they did not point out their use of CRC checks more clearly. I would expect such important information. In AN4323 there is only "CRC should be enable" but not "has to be in default configuration".

      Thumbs Up for Segger, will visit your booth on embedded world in February.