SysTick doesn't increment in STM32 CubeMX samples when executed from SRAM

Sysprogs forums Forums VisualGDB SysTick doesn't increment in STM32 CubeMX samples when executed from SRAM

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #21718
    regus_pregus
    Participant

    Environment: VisualGDB 5.4 (preview 4, build 2394) with VS Community Edition 2017 (15.8.0)

    Target: STM32F746NG (on STM32F746G-DISCOVERY board)

    Problem summary: there is no increment in SysTick counter when running samples from STM32 CubeMX collection from SRAM. As a result, any call to HAL_Delay() results in infinite loop.

    Steps to reproduce:

    1. Run VS with VisualGDB installed
    2. Create new project (File->New->Project->VisualGBB->Embedded Project Wizard)
      1. Project type page: Create a new project with = MSBuild, Embedded binary (.elf) = check, Additional output binaries: bin = check, all other settings have no effect
      2. Device selection page: STM32F746NG, Execute from = SRAM, Exclude the startup file from project = UNCHECK, all other settings have no effect
      3. Sample selection page: STM32 CubeMX Samples tab, select LTDC_PicturesFromSDCard sample project, all other settings have no effect
      4. Debug method page: Debug using = OpenOCD, JTAG/SWD programmer = ST-Link v2.1, Program FLASH memory = Always, all other settings by default
    3. Build the project (Build->Build solution)
    4. Run the program (Debug->Start Debugging with GDB) – after loading, program never displays anything on the screen
    5. Break debug execution (Debug->Break All) – upon break, you will find that it sits in the infinite loop in HAL_Delay() function because HAL_GetTick() always returns the same 0 value and is never incremented by the SysTick interrupt handler (the latter is never called despite seemingly proper configuration during program startup).

    Differential diagnostics: This error condition IS NOT happening in either of the following alterations to the above described scenario:

    1. When executing the same program from FLASH (create a sibling project as above, only specifying Execute from = FLASH in step 2.d)
    2. When executing from SRAM the STM32F7-Discovery LCD Demo program from Basic samples category (create a sibling project as above, only selecting Basic samples tab, STM32F7-Discovery LCD Demo sample project in step 2.c above)

    In all of these cases SysTick interrupt handler gets called every 1 ms, the counter is incremented, and, as a result, HAL_Delay() executes properly instead of waiting forever.

    Experiments with other settings in the New project wizard show that none of the other settings have any effect on either project: LTDC_PicturesFromSDCard from CubeMX continues to hang when executed from SRAM, and STM32F7-Discovery LCD Demo from Basic samples continues to run as expected when executed from SRAM.

    I looked at the source code and both programs do the same things during startup:

    1. Enable processor cache by calling SCB_EnableICache() and SCB_EnableDCache()
    2. Calling the same HAL_Init() function
    3. Calling similar SystemClock_Config() functions with only minor differences in three parameters inside (as an experiment, I moved these parameters between working and non-working projects and the effect did not change – the bad demo still hangs, the good still works
    4. After this point the programs go on to do their application specific stuff, and, at some point initialize SDRAM, where they make a call to HAL_Delay(), where the bad demo hangs. This application-specific stuff is irrelevant, for simplicity sake you can just insert a call to HAL_Delay(2) right in main() function body, right after the call to SystemClock_Config() function. This will eliminate all irrelevant stuff and will still reproduce the problem – the bad demo will hang there, and the good demo will not.

    Questions:

    1. Why would change in where we run the code from (SRAM vs. FLASH) affect the interrupt handler?
    2. Apparently the good demo (STM32F7-Discovery LCD Demo) does something else that enables it’s SysTick interrupt to still work when the program is executed from SRAM, while a seemingly more sophisticated demo LTDC_PicturesFromSDCard doesn’t survive running from SRAM instead of FLASH.
    3. Can anyone having the same hardware and the current (stable) version of VisualGDB (5.3r8) run the same scenario to see if the same problem exists there?

    Any other ideas?

     

    #21719
    parsec67
    Participant

    I don’t have an F7 but…. Did you change the interrupt vector table for your SRAM project? If not then interrupts will not work when booting from SRAM because interrupts — SysTick included — are offset by the start address of SRAM (0x20000000 on F4). The RM for your device should have more info about this.

    #21727
    support
    Keymaster

    Hi,

    Thanks for the very detailed description and sorry for the inconvenience. The issue is actually caused by the following code in the system_stm32f7xx.c file:

    #ifdef VECT_TAB_SRAM
     SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
    #else
     SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
    #endif

    It checks whether the project is built to run from FLASH or RAM and then sets the interrupt vector table register accordingly. If the code is running from RAM, but the vector table is pointing in FLASH, the interrupt controller won’t be able to invoke the correct interrupt handlers and hence SysTick_Handler() won’t be called.

    The ST software packages use different variable name to distinguish FLASH/RAM configurations on different families (sram_layout on most families, but VECT_TAB_SRAM on F7 and H7) and VisualGDB handles it by patching the default system file on F7 and H7 to check the sram_layout instead. This indeed causes the problem you described when using STM32CubeMX samples that come with their own system file.

    We will fix this in the upcoming STM32 BSP update. As a workaround, please define VECT_TAB_SRAM manually via VisualGDB Project Properties -> MSBuild Settings -> Preprocessor macros.

    Let us know if you encounter any further problems and we will be happy to help.

    #21732
    regus_pregus
    Participant

    Thank you both for your responses.


    @parsec67
    : yes, you were correct to point in the direction of IVT location as a culprit.

    @support: thanks for pointing in the right direction towards the solution. After defining VECT_TAB_SRAM manually, the code would still hang, but I was on the right track, because I was also now able to compare what else good and bad demo do before main(). It turns out that in addition to defining this macro so that SCB->VTOR gets initialized with alternative value, you also need to patch that initialization code a bit:

    Instead of

    SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */

    you need

    SCB->VTOR = RAMDTCM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */

    becasue SRAM1_BASE would set up VTOR in wrong location in SRAM. The good demo (STM32F7-Discovery LCD Demo, the one that doesn’t hang) does exactly this (uses RAMDTCM_BASE) and never hangs, because RAMDTCM_BASE points to the beginning of SRAM where the IVT should be, while SRAM1_BASE points to 0x20010000.

    After these two changes the bad demo starts working from SRAM without any hanging, mission accomplished.

    Also, I noticed that in Reset_Handler() the first instruction is this:

    #ifdef sram_layout
    asm ("ldr sp, =_estack");
    #endif

    sram_layout is also not defined in bad demo and is defined in good demo (and therefore inline asm instruction is not executed in bad demo), but defining it in bad demo had no effect on the code execution, but it might be a good idea to also define it in the patch for consistency sake.

    So, for the purposes of the upcoming patch, here are the fixes:

    1. Define VECT_TAB_SRAM macro, as you suggested
    2. Additionally, use RAMDTCM_BASE instead of SRAM1_BASE in SystemInit() of system_stm32f7xx.c
    3. Possibly define sram_layout macro as an additional precaution

    Thank you for great support. We are on 30-day trial right now with VisualGDB, test-driving it versus other STM32 programming solutions and I can tell you that both the product and your support are winning so far, which will more than likely result in a purchase at the end of the trial.

    #21734
    support
    Keymaster

     

    Hi,

    Thanks for pointing out the missing sram_layout for the vendor samples. Indeed it was only defined when using the HAL or StdPeriph framework that is used with regular projects, but not with lightweight STM32CubeMX samples. We will also fix this in the upcoming BSP update.

    The RAMDTCM_BASE  issue looks like a conflict between the sample-specific system file and the default linker script used by VisualGDB. We will retest this as a part of our BSP tests and will ensure that the correct linker script is used with the lightweight samples.

    It’s great to hear that you are happy with VisualGDB. Let us know if you encounter any further issues, or have any suggestions and we will be happy to make VisualGDB even better.

    #21777
    regus_pregus
    Participant

    Could you also look at another supplied sample program when executed from SRAM? Same steps to reproduce as before, only this time it is a FreeRTOS_DelayUntil sample project from STM32 CubeMX Samples tab when selecting a sample project. Apply all the temporary fixes as we figured out before, compile and run. The program execution gets stuck in main() / HAL_Init() / HAL_InitTick() / HAL_TIM_Base_Start_IT() / __HAL_TIM_ENABLE(htim); (this is a call stack sequence). Of note, the program executes as expected (blinks LED) when run from FLASH.

    • This reply was modified 5 years, 7 months ago by regus_pregus.
    #21812
    support
    Keymaster

    Hi,

    Sorry for the delay. We have discovered an unrelated problem while investigating this, however it should not trigger for MSBuild-based projects.

    We have rechecked the sample and applied the following workarounds:

    • Manually defined sram_layout and VECT_TAB_SRAM (will be fixed in the upcoming BSP update)
    • Replaced SCB_VTOR assignment as follows:
     SCB->VTOR = RAMDTCM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */

    The sample did run correctly after those fixes. If it doesn’t work on your side, please attach an archive with your project (clean the project and remove the .vs folder before archiving) and we can compare it with the project on our side to see what could be causing this.

     

    #21866
    regus_pregus
    Participant

    Works fine on my side as well now, maybe previously I have done something wrong when setting up this code. Sorry for a false alarm!

    #21867
    support
    Keymaster

    Hi,

    No problem. Let us know if you encounter further issues and we will be happy to help.

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.