cancel
Showing results for 
Search instead for 
Did you mean: 

SysTick interrupt does not work

TMark.14
Associate III

Using St Cube IDE 1.6.0, I create new project for STM32G491KE.

When debugging the project I noticed that Systick interrupt is not getting called. Systick STK_VAL register is changing, and STL_CTRL register COUNTFLAG bit is set. Interrupt in stm32g4xx_it.c void SysTick_Handler(void) is never called as a result uwTick is never incremented and HAL_Delay() function hung up because of this.

What could be a reason? The project is autogenerated, nothing is done to it manually, only hal_delay() function call in for(;;) loop.

7 REPLIES 7
TDK
Guru

Is the NVIC SysTick interrupt enabled? Is TICKINT set?

Are interrupts disabled in general?

If you feel a post has answered your question, please click "Accept as Solution".
TMark.14
Associate III

I believe that Cube IDE knows how to initialize systick, so "Yes" to all questions.

Vector table did not seem right to me. Systick interrupt vector at address 0x0000003c (RM0440 page443) did not have a value of the handler function location that I got from elf file:

[ 200] 080008c7 0000000c FUNC GLOBAL  2 SysTick_Handler 

Turns out the problem was also because of the boot pin state. On power up MCU would bootup into sysmemory, debugger would make it jump into flash memory but it would not change vector table. So the vector table was not correct for my application hence systick interrupt did not increment my variable.

Issue is solved.

juozas
Associate III

I'm sharing my solution in my case. Using Stm32 Cube IDE 1.12.1 and Nucleo G491RE. Systick interrupt stopped to work after I switched from HAL to LL version in Project Manager -> Advanced Settings for all peripherals including RCC. Later, during the investigation of this problem, I found that CubeMX dialog shows tooltip stating that system interrupts are always allowed, not need to be allowed. But, after I add following line in User code zone, systick interrupt starts to work:

LL_SYSTICK_EnableIT();

My issue solved.

> tooltip stating that system interrupts are always allowed,

> not need to be allowed

This is slightly misleading.

Interrupts are generally enabled at two places: at the source (here: in the Systick module), and in NVIC.

System interrupts indeed don't need to be enabled in NVIC, but they still need to be enabled at the source (except HardFault and NMI (although sources of NMI may still need enabling)).

Corollary is, don't blindly trust the clicking interfaces. Mcu works out of the registers, not out of whatever you've clicked, not even out of C source code nor libraries.

JW

This fixed the issue for me -  Thnks!

Hi Tmark.14,

 

I am having the same issue with STM32L431CBT6. I am using STM IDE cube 1.14 and STlink-V3. 

I checked the system tick. it is running. 

DKhan1_0-1701459589879.png

 

DKhan1_1-1701459675952.png

DKhan1_2-1701459699405.png

The SysTick_Handler(void) is never getting called. 

Can you suggest any solution.

Kind regards,

Dibyendu

 

 

For anyone like me who wants more of an explanation to this solution, here is what the problem is and how I fixed it.

Problem:

The systick interrupt is not working because the MCU would bootup in system memory and the vector table was not properly mapped. The reason it is booting up in system memory is because apparently, ST made a revision where the nSWBOOT0 pin is set high - STM32G474 default option bytes configuration - STMicroelectronics Community

 

CamTheMan_1-1716389358532.png

When nSWBOOT0 is set high, if BOOT0 is also high, the controller loads into system memory. 

The really messed up part is that I was originally using a STM32G474RET6U ( U suffix means it's from nucleo board) and this would load correctly into FLASH. Then I purchased some individual STM32G474RET6 MCUs and wouldn't work with the same exact code. So at some point ST decided to change the option bytes register that enables nSWBOOT0 by default. 

Solution:

Referring to table 2.6.1 above, there are multiple solutions to start loading in FLASH memory. The easiest option is to pull down the BOOT0 (PB8) pin but I am using this pin for CAN GPIO pin. The other options are either setting nSWBOOT0 to 0 by rewriting option bytes, refer to RM0440 section 5.4.2. Or Setting BOOT_LOCK high to override all other combinations.

In case you don't want to download STMCubeProgrammer to do this, or spend hours writing your own routine for this, I have provided what worked for me. I clear nSWBOOT0 and set BOOT_LOCK bit but you could fix the problem by just changing either one. 

 

 

int main(void)
{
  /* USER CODE BEGIN 1 */
    if(HAL_FLASH_Unlock() == HAL_OK)
    {
        if(HAL_FLASH_OB_Unlock() == HAL_OK)
        {
            /* Instructions found in section 5.4.2 of rm0440 STM32G4 Series manual */
            FLASH->OPTR &= ~(1<<(26)); // clear nSWBOOT0 bit
            FLASH->SEC1R |= (1<<16);  // set BOOT_LOCK bit
            FLASH->CR |= (1<<17);       // set options start bit OPTSTRT
            while((FLASH->SR & (1<<16))); // wait for the bsy bit to be cleared
            HAL_FLASH_OB_Lock();
            HAL_FLASH_OB_Launch();

        }
        HAL_FLASH_Lock();
    }
  /* USER CODE END 1 */

 

 Simply flash it to the MCU and power cycle, this should fix the issue and you no longer need the code above.