cancel
Showing results for 
Search instead for 
Did you mean: 

Optimization crazyness (H733, STM32CubeIDE 1.10.1)

LCE
Principal II

Heyho,

I had some really strange error, which went away when turning optimization from "fast" to "off".

The function EthPhyInit() always returned 166 = 0xA6 - it should return "HAL_StatusTypeDef", something between 0 .. 3.

So I changed all the return values to some integer between 1..8 to find out where things go wrong, then added the last line:

uart_printf("EthPhyInit() good ->return 0\n\r");

before returning 0 when all went well.
Still, always got 166 back, even when I got "EthPhyInit() good ->return 0\n\r" on the terminal.

Until I turned optimization OFF, now all is good.

WTF is happening there? Can optimization be that bad?

 

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
 /**
  * @brief  all PHY, ETH MAC & DMA reset and init:
  *			1) EthBaseInit()	GPIO, clocks, basic stuff
  *			2) EthPhyInit()		PHY
  *			3) EthMacInit()		MAC registers
  *			4) EthDmaInit()		DMA registers
  * @PAram  -
  * @retval HAL status
  */
uint8_t EthAllInit(uint8_t u8SkipBase)
{
	static uint32_t u32CallCount = 0;
	uint8_t u8RetInit = 0xFF;

	u32CallCount++;

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* base init */
	if( 0 == u8SkipBase )
	{
		u8RetInit = EthBaseInit();
		if( u8RetInit != HAL_OK )
		{
			#if( 1 )	// DEBUG_ETHNETIF
				uart_printf(SZC_TEXT_ERR "EthBaseInit() = %u\n\r", u8RetInit);
			#endif 	/* DEBUG_ETHNETIF */

			return u8RetInit;
		}
	}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* PHY initialization and configuration */
	u8RetInit = EthPhyInit();
	if( u8RetInit != HAL_OK )
	{
		#if( 1 )	// DEBUG_ETHNETIF
			uart_printf(SZC_TEXT_ERR "EthPhyInit() = %u\n\r", u8RetInit);	// ##### <- always 166 = 0xA6
			uart_printf("u32CallCount = %lu\n\r", u32CallCount);
		#endif 	/* DEBUG_ETHNETIF */

		/* do NOT return error
		 *	-> to NOT block other inits
		 */
		//return u8RetInit;
	}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* MACCR: more MAC registers */
	u8RetInit = EthMacInit();

...

	return u8RetInit;
}


/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 /**
  * @brief  ETH PHY initialization and configuration
  * @PAram 	none
  * @retval HAL status
  */
uint8_t EthPhyInit(void)
{
	/* KSZ8863RLL dual port PHY */

	/* wait after reset */
	HAL_Delay(50);

/* ++++++++++++++++++++++++++++++++++++++++++++++++ */
	if( EthPhyKszAlive() != HAL_OK )
	{
uart_printf(SZC_TEXT_ERR "EthPhyInit() 1\n\r");
		return 1U;	//HAL_ERROR;
	}

	/* ++++++++++++++++++++++++++++++++++++++++++++++++ */
	#if DEBUG_ETHNETIF
		uart_printf("PHY KSZ set RMII clock to internal...\n\r");
	#endif 	/* DEBUG_ETHNETIF */

	if( EthPhyKszClockSource(1) != HAL_OK )
	{
uart_printf(SZC_TEXT_ERR "EthPhyInit() 2\n\r");
		return 2U;	//HAL_ERROR;
	}

	/* PHY needs a little time after clock change */
	HAL_Delay(50);

	/* ++++++++++++++++++++++++++++++++++++++++++++++++ */
	/* check LINK status of BOTH PHY ports */
	#if DEBUG_ETHNETIF
		uart_printf("PHY link check...\n\r");
	#endif 	/* DEBUG_ETHNETIF */

	u8PhyPortActive = PHY_PORT_NONE;

	/* ETH */
	if( EthPhyLinkStatus((uint8_t)PHY_PORT_ETH, ETH_LINK_CHECK_LONG) == HAL_OK )
	{
		u8PhyPortActive = PHY_PORT_ETH;
	}

	/* USB if ETH not LINKed */
	if( PHY_PORT_NONE == u8PhyPortActive )
	{
		if( EthPhyLinkStatus((uint8_t)PHY_PORT_USB, ETH_LINK_CHECK_LONG) == HAL_OK )
		{
			u8PhyPortActive = PHY_PORT_USB;
		}
	}

	#if( 1 )	// DEBUG_ETHNETIF
		uart_printf("u8PhyPortActive = %u\n\r", u8PhyPortActive);
	#endif 	/* DEBUG_ETHNETIF */


	/* ++++++++++++++++++++++++++++++++++++++++++++++++ */
	/* power down unused port */
	if( PHY_PORT_NONE != u8PhyPortActive )
	{
		uint32_t u32PhyRegVal = 0;
		volatile uint8_t u8PhyPortUnused = PHY_PORT_NONE;
		uint8_t u8RetVal = 0;
		UNUSED(u8RetVal);

		if( PHY_PORT_ETH == u8PhyPortActive ) u8PhyPortUnused = PHY_PORT_USB;
		else u8PhyPortUnused = PHY_PORT_ETH;

		u8RetVal = EthPhyPowerDown(u8PhyPortUnused);
		#if DEBUG_ETHNETIF
			if( u8RetVal != HAL_OK ) uart_printf(SZC_TEXT_ERR "EthPhyPowerDown()\n\r");
			else uart_printf("PWRDWN unused port set\n\r");
		#endif 	/* DEBUG_ETHNETIF */

		/* check */
		HAL_Delay(10);
		u8RetVal = EthPhyReadReg(PHY_REG_PWR_DOWN, &u32PhyRegVal, u8PhyPortUnused);
		#if DEBUG_ETHNETIF
			if( u8RetVal != HAL_OK ) uart_printf(SZC_TEXT_ERR "EthPhyReadReg(PHY_REG_PWR_DOWN)\n\r");
			else
			{
				uart_printf("PHY_REG_PWR_DOWN = %04lX of unused port\n\r", u32PhyRegVal);
				if( (u32PhyRegVal & (uint32_t)PHY_REG_BIT_PWR_DOWN) == 0 ) uart_printf(SZC_TEXT_ERR "EthPhyPowerDown() failed\n\r");
			}
		#endif 	/* DEBUG_ETHNETIF */
	}

	/* ++++++++++++++++++++++++++++++++++++++++++++++++ */
	/* wait for auto-negotiation complete */
	if( PHY_PORT_NONE != u8PhyPortActive )
	{
		if( EthPhyAutoNegStatus(u8PhyPortActive) == HAL_OK )
		{
			#if DEBUG_ETHNETIF
				uart_printf("AUTO-NEGOTIATION 0 complete\n\r");
			#endif 	/* DEBUG_ETHNETIF */
		}
		else
		{
			/* re-start Auto-Negotiation */
			if( EthPhyAutoNegRestart(u8PhyPortActive) != HAL_OK )
			{
				#if( 1 )	// DEBUG_ETHNETIF
					uart_printf(SZC_TEXT_ERR "EthPhyAutoNegRestart()\n\r");
				#endif 	/* DEBUG_ETHNETIF */

				return 6U;	//HAL_ERROR;
			}

		/* wait for auto-negotiation complete */
			if( EthPhyAutoNegStatus(u8PhyPortActive) == HAL_OK )
			{
				#if DEBUG_ETHNETIF
					uart_printf("AUTO-NEGOTIATION 1 complete\n\r");
				#endif 	/* DEBUG_ETHNETIF */
			}
			else
			{
				#if( 1 )	// DEBUG_ETHNETIF
					uart_printf(SZC_TEXT_ERR "EthPhyAutoNegStatus() TIMEOUT\n\r");
				#endif 	/* DEBUG_ETHNETIF */

				return 7U;	//HAL_TIMEOUT;
			}
		}
	}
	else
	{
		#if( 1 )	// DEBUG_ETHNETIF
			uart_printf(SZC_TEXT_ERR "u8PhyPortActive = PHY_PORT_NONE\n\r");
		#endif 	/* DEBUG_ETHNETIF */

		return 8U;	//HAL_ERROR;
	}

uart_printf("EthPhyInit() good ->return 0\n\r");

	return 0U;	//HAL_OK;
}

 

PS:

- STM32H733 on a custom board

- working with that for > 1 year now, with lots of printf for debugging (UART DMA), never had something like this

- same on other boards

- still using STM32CubeIDE 1.10.1

10 REPLIES 10
TDK
Super User

Ticks should definitely have a volatile qualifier on it, as it's modified within an interrupt. The code for ticks is dirt simple, no bugs there. If your ticks are going backwards, there has to be a bug somewhere in there. Perhaps an out of bounds write. I suspect an issue with something else messing with the stack variable rather than the underlying tick variable.

Careful of making random changes to get it to "work". You may be sweeping larger issues under the rug, which will come up later.

> When stepping through (on C level) I see "return 0;", then the return value in the above function gets some other seemingly random value.

Also suggests stack corruption.

If you feel a post has answered your question, please click "Accept as Solution".