0
\$\begingroup\$

I am working with a STM32F303 microcontroller with a Nucleo board and my code gets stuck in the SysTick_Handler routine of the startup_stm32f303xe.s file. (My code is based on an example Nucleo project, but rebuilt from scratch for learning purposes).

This post suggests that I need to set the Systick Interrupt to higher priority, which I did and doesn't fix the problem. This post suggests that the Systick Exception occurs when the system timer reaches 0... but I don't think I am using the system timer in my code.

In debug view with some breakpoints, I can see that the code executes to the two GPIO_TogglePin functions, after which it goes into the exception handler.

How can I prevent the program from causing the Systick Exception?

Here is my code:

int main(void) {

    HAL_Init();
    SystemClock_Config();
    LED2_GPIO_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    GPIO_InitStruct.Pin = LED2_PIN;
    HAL_GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_8;
    HAL_GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
    // Also tried HAL_InitTick(0);

    while(1) {

        HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);

        // Project code
    }
}

void SystemClock_Config(void) {
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    RCC_OscInitTypeDef RCC_OscInitStruct;

    /* HSI Oscillator already ON after system reset, activate PLL with HSI as source */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_NONE;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
    Error_Handler();
    }

    /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
 clocks dividers */
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
        | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
    Error_Handler();
    }

}
\$\endgroup\$
4
\$\begingroup\$

The ST HAL requires the systick for operation.
It increments the system tick you can use via HAL_GetTick(), it is incremented in the SysTick_Handler() via HAL_IncTick();.
It will be configured by HAL_SYSTICK_Config somewhere in the HAL.

You don't get stuck there. It just gets called every 1 ms.

If you do get stuck in the systick handler, there could be something wrong with the vector table. Eg: the address for SysTick_Handler at the position for something else.

Check the IABR registers when halted.
4.2.6 Interrupt Active Bit Registers.

\$\endgroup\$
2
  • \$\begingroup\$ Yep, turns out I was missing the SysTick_Handler() implementation. Adding the Handler function with HAL_IncTick(); solves the "problem". Thanks! \$\endgroup\$ – a2xia Mar 20 '18 at 8:45
  • 1
    \$\begingroup\$ HAL doesn't requre SysTick, it requires a a working HAL_GetTick() that can somehow figure out how many milliseconds did elapse since the program was started. HAL_InitTick() must be overridden if SysTick is not used. \$\endgroup\$ – followed Monica to Codidact Mar 20 '18 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.