cancel
Showing results for 
Search instead for 
Did you mean: 

Is this a bug in the app or the HAL, support framework?

Korporal
Senior

I'm seeing something very odd. I have a crude test app that exercises an EPS8266 plugged into my STM32F769 Discovery board.

The app runs and loops and does simple checks during execution, it runs fine every time I run it.

But if I simply comment out an unused local struct declaration and run it, it fails! It behaves differently.

I wondered if there is a bug in my code in which I was inadvertently writing to memory in that unused struct and removing it meant it was writing to some other part of the stack and so behaved differently.

However if I zeroize the struct and run, at no point do I see anything changing in the struct so I see no evidence the app is writing to this area, besides the app is simple and I see no code that looks suspect.

I'm using Visual Studio 2017 with Visual GDB, shall I post the source? is anyone interested in trying to repro? (it's a single source file, quite small).

Thx

 ...a short time later....

OK forget it, this is fixed!

The cause is that the second declared struct is a UART handle and although the code inits the UART it was not initializing all fields. Therefore the content of that struct (though some fields were initialized) was different when I removed the preceding unused struct declaration.

 I now zeroize the UART struct before setting its various fields and initializing the UART and I get consistent soldi behavior no matter what I do with that unused struct.

All good (But the example code I copied this from is flawed)

4 REPLIES 4

Memory alignment and appropriate use of volatile, and behaviour of compiler/optimizer to those things.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

By default auto/local variable are not cleared and contain random stack junk.

Many HAL examples don't explicitly clear the variable, nor set all the fields, random hilarity can then ensure.

I have a tendency to do this now, and use static if I think there is any potential for the structure to be reused beyond the scope of the function. ie referenced to via some other structure HAL is holding.

{
  static UART_HandleTypeDef UartHandle = {0}; // usually don't do this statically
  GPIO_InitTypeDef GPIO_InitStruct = {0}; // clear because the stack normally isn't

I also do this because I don't like a lot of globals, and localizing the scope allows me to catch other usage.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Korporal
Senior

@Community member​ - Hmm I never saw that {0} initialization, I'm new to C++ and of course C has no such thing. I also just read that = {}; defaults to the same as = {0}; Very helpful feature!

Thanks

Pretty sure it's a C thing, I've been using it for decades. Traceable to K&R

"If there are fewer initializers in the list than members of the structure, the trailing members are initialized with 0"

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..