2019-02-28 10:04 AM
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)
2019-02-28 10:07 AM
Memory alignment and appropriate use of volatile, and behaviour of compiler/optimizer to those things.
2019-02-28 10:23 AM
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.
2019-02-28 12:35 PM
@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
2019-02-28 12:42 PM
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"