cancel
Showing results for 
Search instead for 
Did you mean: 

Incorrect time elapsed using SysTick

ZTan.2
Associate II

Hi, I'm currently using STM32F401RE Nucleo-64 Board.

My purpose of this project is to configure ISM330DLC Accelerometer, taking reference from STEVAL-BFA001V1B sample code on Vibration Analysis.

As a summary:

  1. After enabling the accelerometer FIFO FULL FLAG INT, I have initialise a variable StartTick = HAL_GetTick();
  2. At this point, the accelerometer will trigger an interrupt every 60ms (from my oscilloscope), and it will read everything from the Acclerometer FIFO (limited by the watermark and stop on fth) for roughly 30ms. As I'm using the codes from the sample reference, the BSP STEVAL-IDP005 isn't really efficient in reading from the Accelerometer's FIFO, but that is not of the concern for this post.
  3. In the main loop, it will keep calling another layer. In that layer, it has initialised a variable ActualTick = HAL_GetTick(); and checks if (ActualTick - StartTick is more than 5000ms). If condition is TRUE, then disable FIFO INT.

Nevertheless, the current problem I'm facing is this:

  • The actual time elapsed is around 10 seconds, instead of the expected 5 seconds.
  • The debugger shows the value of ActualTick - StartTick is slightly more than 5000, which is expected.
  • I assume that SysTick is properly initialised after HAL_Init() is called. I've checked and it seems that HAL_Init() has configured SysTick with a pre-empt priority of 0.
  • I made a simple check in the SysTick_Handler by using HAL_GPIO_TogglePin to see if the SysTick is triggering at 1ms through the oscilloscope and it seems correct before interrupts from the accelerometer comes in.
  • Once the accelerometer triggers the series of interrupt, my oscilloscope shows erratic behaviour, so i'm assumming its a priority problem. But all the other interrupts have a pre-empt priority of >= 1 after double checking.

Sorry for the long post. I'm only just 2 months into STM32 and I would appreciate any kind advice and tips. Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> Once the accelerometer triggers the series of interrupt, my oscilloscope shows erratic behaviour, so i'm assumming its a priority problem. But all the other interrupts have a pre-empt priority of >= 1 after double checking.

Check again. If you're getting regular 1ms systick interrupts that are then interrupted when other interrupts happen, the only explanation is a priority issue or if they disable interrupts entirely.

While debugging, you should be able to hit pause to see what interrupt is being handled. If it's happening frequently, you should be able to spot it by doing this a few times.

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

View solution in original post

4 REPLIES 4
TDK
Guru

> Once the accelerometer triggers the series of interrupt, my oscilloscope shows erratic behaviour, so i'm assumming its a priority problem. But all the other interrupts have a pre-empt priority of >= 1 after double checking.

Check again. If you're getting regular 1ms systick interrupts that are then interrupted when other interrupts happen, the only explanation is a priority issue or if they disable interrupts entirely.

While debugging, you should be able to hit pause to see what interrupt is being handled. If it's happening frequently, you should be able to spot it by doing this a few times.

If you feel a post has answered your question, please click "Accept as Solution".
ZTan.2
Associate II

Hi, Thanks for the response.

I think the reason has to do with HAL_INIT();

HAL_StatusTypeDef HAL_Init(void)
{
  /* Configure Flash prefetch, Instruction cache, Data cache */ 
#if (INSTRUCTION_CACHE_ENABLE != 0U)
  __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
#endif /* INSTRUCTION_CACHE_ENABLE */
 
#if (DATA_CACHE_ENABLE != 0U)
  __HAL_FLASH_DATA_CACHE_ENABLE();
#endif /* DATA_CACHE_ENABLE */
 
#if (PREFETCH_ENABLE != 0U)
  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif /* PREFETCH_ENABLE */
 
  /* Set Interrupt Group Priority */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 
  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
  HAL_InitTick(TICK_INT_PRIORITY);
 
  /* Init the low level hardware */
  HAL_MspInit();
 
  /* Return function status */
  return HAL_OK;
}

HAL_INIT has initially set to priority group 4 - which is 4 bits for pre-empt priority and 0 bits sub-priority.

BUT HAL_MSPInit() set the priority group again to priority group 0 - which is 0 bits pre-empt priority and 4 bits sub-priority.

/* USER CODE END 0 */
/**
  * Initializes the Global MSP.
  */
void HAL_MspInit(void)
{
  /* USER CODE BEGIN MspInit 0 */
 
  /* USER CODE END MspInit 0 */
 
  __HAL_RCC_SYSCFG_CLK_ENABLE();
  __HAL_RCC_PWR_CLK_ENABLE();
 
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
 
  /* System interrupt init*/
 
  /* USER CODE BEGIN MspInit 1 */
 
  /* USER CODE END MspInit 1 */
}

I guess I've learnt my lesson for not checking on HAL, but that implementation of initializing priority group twice just doesn't make sense.

Fasaw.3
Associate

I became looking to switch among simulator and a specific goal within the identical task while not having to create a new/second project detail article. But the "Import GUI" option does help too.

Piranha
Chief II

NVIC is already set to a maximum group priorities after reset. Therefore for a typical usage there is no reason in calling NVIC_SetPriorityGrouping() at all.

https://community.st.com/s/question/0D53W00000XHZKb/nested-interrupts-stm32l4