cancel
Showing results for 
Search instead for 
Did you mean: 

Peripheral use before FreeRTOS Kernel Init makes the MCU to infinite loop

SOgal.1
Associate II

Hi, I am using an STM32F401. I have on board peripherals (not in the MCU) connected with USART, SPI and I2C. I am using FreeRTOS. I am using Systick, external crystal HSE, external crystal LSE, RTC, but no Timers. I am generating my code with STM32Cubeide.

The program enters an infinite loop when initializing my SPI or USART peripherals:

 

 

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER COuDE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_RTC_Init();
  MX_SPI1_Init();
  MX_SPI3_Init();
  MX_USART1_UART_Init();
  MX_USART6_UART_Init();
  MX_I2C3_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
  I2C_ONBOARD_SENSOR1_Init();

  SPI_ONBOARD_SENSOR2_Init();
// EXECUTION DOES NOT ADVANCE FURTHER THAN THIS!
// AND IF COMMENT OUT THE SPI SENSOR, EXECUTION
// ENTERS A LOOK INSIDE USART SENSOR INIT
  USART_ONBOARD_SENSOR3_Init();




  /* USER CODE END 2 */

  /* Call init function for freertos objects (in freertos.c) */
  MX_FREERTOS_Init();

  /* Start scheduler */
  osKernelStart();
  /* We should never get here as control is now taken by the scheduler */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  { ...

 

 

  During debugging, I see that the execution halts on the function HAL_Delay inside the libraries of my SPI sensor, so I can imagine it is the GetTick that is giving me a constant value so I can't get out from the HAL_Delay.

If I comment out the SPI sensor initialization, I see during debug that the looping function is UART_WaitOnFlagUntilTimeout(), which uses HAL_GetTick too. 

 

 

static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
                                                     uint32_t Tickstart, uint32_t Timeout)
{
  /* Wait until flag is set */
  while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
  {
    /* Check for the Timeout */
    if (Timeout != HAL_MAX_DELAY)
    {
      if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
      {
        /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
        ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
        ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);

        huart->gState  = HAL_UART_STATE_READY;
        huart->RxState = HAL_UART_STATE_READY;

        /* Process Unlocked */
        __HAL_UNLOCK(huart);

        return HAL_TIMEOUT;
      }
    }
  }
  return HAL_OK;
}

 

 

I do not know the reason behind this. Although I have a workaround for this, I would like to understand why this is not working.

Thank you so much in advance.

S.

4 REPLIES 4
Pavel A.
Evangelist III

Insert HAL_Delay(2) after SystemClock_Config()  and after  MX_GPIO_Init ().

Will it stuck there?

FBL
ST Employee

Hello @SOgal.1,

 

Are you using a customized board?  It is possible that the problem is with the external crystal. I suggest running a minimum piece of code to reproduce the behavior so that we can help you. 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

BillyBob
Associate II

Somewhere, can't remember where, I read when running FreeRTOS SysTick can not be used for the time base. Select a timer. Note: This may have been for my target, STM32U5.

BillyBob_0-1688659071503.png

You can use SysTick in FreeRTOS. You can't use it when you want to use Tickless Idle functionality of the FreeRTOS to save Power.
If you use Systick in tickless idle mode then tickless idle functionality does not make sense as systick ISR( which is generated every 1ms) will wakeup the system every 1ms.