cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeIDE 1.19.0: GCC generates wrong code

NiTr0man
Associate III

I have a simple function with loop that checks RX pin state for 10ms, and if there was high level - breaks loop and exits. it works ok with -O0, but is broken with -Os or -O1 (-O2) or -Og - it loops forever.

Here's code:

uint8_t isModemOn() {
  uint32_t expire = uwTick + 10;
  while (expire - uwTick < 11) {  // check RXD pin level, if low for 10ms - consider modem is off
    if (LL_GPIO_ReadInputPort(GPIOA) & LL_GPIO_PIN_10) {
      return 1;
    }
  }
  return 0;
}

and how it's appears in listing

080003dc <isModemOn>:
  * @PAram  GPIOx GPIO Port
  * @retval Input data register value of port
  */
__STATIC_INLINE uint32_t LL_GPIO_ReadInputPort(GPIO_TypeDef *GPIOx)
{
  return (uint32_t)(READ_REG(GPIOx->IDR));
 80003dc:	21a0      	movs	r1, #160	@ 0xa0
//#pragma GCC optimize ("O0")  // Error in -Os optimization

uint8_t isModemOn() {
  uint32_t expire = uwTick + 10;
  while (expire - uwTick < 11) {  // check RXD pin level, if low for 10ms - consider modem is off
    if (LL_GPIO_ReadInputPort(GPIOA) & LL_GPIO_PIN_10) {
 80003de:	2380      	movs	r3, #128	@ 0x80
 80003e0:	05c9      	lsls	r1, r1, #23
 80003e2:	00db      	lsls	r3, r3, #3
 80003e4:	690a      	ldr	r2, [r1, #16]
 80003e6:	421a      	tst	r2, r3
 80003e8:	d0fc      	beq.n	80003e4 <isModemOn+0x8>
      return 1;
    }
  }
  return 0;
}
 80003ea:	2001      	movs	r0, #1
 80003ec:	4770      	bx	lr
	...

 I didn't work too much with ARM assembler, but  it looks like it calculates expire variable dynamically in the loop, or even dropped it's check at all. I tried to change conditions (while..if) but it doesn't help.

I'll try to find workaround by code refactoring, but I hope it'll be fixed in future releases.

1 ACCEPTED SOLUTION

Accepted Solutions
NiTr0man
Associate III

Hm, I forgot to declare uwTick as volatile. with volatile all is OK...

View solution in original post

2 REPLIES 2
Andrew Neil
Super User

You haven't shown your definition of uwTick - is it the standard HAL one?

If not, is it volatile, and how is it updated ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
NiTr0man
Associate III

Hm, I forgot to declare uwTick as volatile. with volatile all is OK...