Peripheral use before FreeRTOS Kernel Init makes the MCU to infinite loop
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.
