Search code examples
cembeddedvolatile

EMBEDDED C - Volatile qualifier does not matter in my interrupt routine


I am new to embedded C, and I recently watched some videos about volatile qualifier. They all mention about the same things. The scenarios for the use of a volatile qualifier :

  1. when reading or writing a variable in ISR (interrupt service routine)
  2. RTOS application or multi thread (which is not my case)
  3. memory mapped IO (which is also not my case)

My question is that my code does not stuck in the whiletest();function below when my UART receives data and then triggers the void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) interrupt function

int test;

int main(void)
{
  test = 0;
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  HAL_UART_Receive_IT(&huart1, (uint8_t *)&ch, 1);

  while (1)
   {
        Delay(500);     
        printf("the main is runing\r\n");
        whiletest();
   }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        test = 1;
        HAL_UART_Receive_IT(&huart1, (uint8_t *)&ch, 1);
    }
}

void whiletest(void)
{
int count =0;
while(!test){
 count++;
 printf("%d\r\n",count);
 Delay(2000);
 }
}

I use keil IDE and stm32cubeIDE. I learned that the compiler would optimize some instructions away if you choose the o2 or o3 optimization level. Therefore, I chose the o2 level for build option, but it seems no effect on my code. The compiler does not optimize the load instruction away in the while loop and cache the test value 0 in the main function as the videos teach on youtube. It is confusing. In what situation I am supposed to use volatile qualifier while keep my code optimized (o2 or o3 level).

note: I am using stm32h743zi (M7)


Solution

  • The compiler may only optimize (change) code if the optimized code behaves as if it the optimizer did nothing.

    In your case you are calling two functions (Delay and printf) in your while loop. The compiler has no visibility of what these functions do since they appear in a separate compiler unit. The compiler therefore must assume they may change the value of the global variable test and therefore cannot optimize out the check for the value in test. Remove the function calls and the compiler may well optimize out the check for value of test.