2

i want to execute a while loop until a condition is reached, the condition is given by an interrupt fired with a user button, but when i press the button the while loop does not ends, the strange is that if i put a delay inside the loop then it works

//does not works:
while( 1 )
{
 PRINTF("hello\n\r");

 while (button_state==0)
  {
   //do something
   if(button_state==1)
   break;
  }

button_state=0;
}
//works:
while( 1 )
{
 PRINTF("hello\n\r");

 while (button_state==0)
  {
   HAL_Delay(500);//i don't know why needs this to work
   //do something
  }

button_state=0;
}
//does not works:
while( 1 )
{
 PRINTF("hello\n\r");

 while (button_state==0)
  {
   //do something
  }

button_state=0;
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  button_state = 1;
}

the program starts with a "hello", then goes into the while loop, i press the button and in this point the interrupt puts button_state to 1 and i expect that the while loops ends, reach the line where i reset the condition "button_state=0;" and see "hello" again but nothing of this happens. If i insert the delay inside the loop all the expected is fulfilled

  • 2
    Hello Jairo, in which platform is this code running?? Can you explain a bit more about the kind of button you are using?? – Alejandro Montilla Aug 12 '19 at 10:33
  • Have you ensured it's not a problem with flushing the output stream? Add a `fflush(stdout)` after every print statement. – klutt Aug 12 '19 at 10:48
  • If you use stm32 you may want to add stm32 tag. What is `PRINTF`? – KamilCuk Aug 12 '19 at 10:48
  • Hi, i am using system workbench for stm32 - eclipse, the board is a st bl072z LoRa, the button is integrated in the board, is a push button. – jg_spitfire Aug 12 '19 at 10:49
  • All switches need "de-bouncing" unless you have RC filters in the hardware (which is rare). Due to the electromechanical signal bounce in all switches. This should be addressed by any half-decent embedded systems beginner tutorial. – Lundin Aug 12 '19 at 10:51
  • 2
    There's not enough information here to confidently answer the question, and we prefer not to guess. Please present a [mre] that exhibits the problem. – John Bollinger Aug 12 '19 at 10:51
  • @klutt i am using "hello" just to simplify the problem, instead that "hello" i had a function where i reset the button_state to 0, and also did not work, always works with the delay inside the loop – jg_spitfire Aug 12 '19 at 10:53
  • @JairoGallardoGonzalez As John said, you need to give us a [mre] to stop guessing. – klutt Aug 12 '19 at 10:56
  • 1
    What kind of variable is button_state? Is it declared as volatile? If it isn't declared volatile, the compiler might try to optimize away accesses to button_state within while (button_state==0) {} causing unexpected behaviour. Try declaring it as volatile if that is not the case already. – th33lf Aug 12 '19 at 12:28
  • 1
    @th33lf thanks, it works!, but still have a dude, i have been reading about volatile variables and i learned that are useful when your are working with interrupts (as this case), with RTOS and multiple tasks and with inputs from a GPIO, but i was making some tests and inside the while loop put "test=1;" and when i see the state of that variable is 0, only changes if is declared as volatile too, why? – jg_spitfire Aug 12 '19 at 15:42
  • @JairoGallardoGonzalez The compiler may have noticed that you don't do anything with `test` other than set it to 1. In very simplistic terms, volatile is an instruction to the compiler to **not** perform any optimization on the reads & writes to that variable, even though it may think that the operation does not have any effect. For eg: if I write `a = 5; a = 6;`, the compiler normally only generates code for `a = 6;` because the value 5 is not used for any computation and is immediately replaced by 6. However, if you declare `a` as volatile, such optimization will not be performed. – th33lf Aug 13 '19 at 07:42
  • @JairoGallardoGonzalez If you agree with my answer, please accept it so that it stays on for future reference. – th33lf Aug 13 '19 at 07:55

1 Answers1

0

If it your variable button_state isn't declared volatile, the compiler might try to optimize away accesses to button_state within while (button_state==0) {} causing unexpected behaviour. Try declaring it as volatile.

EDIT: Posting deleted answer back, for reference, since the OP has accepted in comments that this was the solution to his problem.

th33lf
  • 2,177
  • 11
  • 15