Skip to main content
ADSB
Associate II
November 5, 2019
Question

Global variables losing their contents, using Keil and STM32l031k6

  • November 5, 2019
  • 6 replies
  • 6223 views

Dear Community,

I am encountering a strange behavior, where some of my global variables in main.c file are losing their contents (even when I declare them as static). They show the initial values which are 0. I am using Keil with optimization level O3, I used also level O1 , the problem is still occurring. My MCU is STM32l031k6. I want to know if this is related to optimization issues, has somebody encountered the same problem before? your help will be really appreciated.

Thank you very much

This topic has been closed for replies.

6 replies

Tesla DeLorean
Guru
November 5, 2019

Issues with optimization on/off tend to highlight latent issues in the code itself. Compiler likely to adjust register vs stack utilization.

Watch for stack utilization and size. Keil parks the stack above the statics, locale, and heap so if your call tree causes excessive stack usage (auto/local variables and arrays) it will trash your globals.

Understand your code and the expectations on the stack. Set the stack size in startup.s to something that is appropriate to handle your worst case usage and interrupt/callback loading factored in.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
ADSB
ADSBAuthor
Associate II
November 6, 2019

Thank you for your help.

I am guessing that is what happening for my case. However, this is the first time I encounter such an issue. According to my understanding, once you declare the variable as static the stack size should be adjusted accordingly. However, I will try to debug in this direction and update you.

Piranha
Principal III
November 5, 2019

Or you could be missing "volatile" on variables which are being used in main code and interrupts or multiple threads in RTOS.

And what happens with optimization level -O0 ?

ADSB
ADSBAuthor
Associate II
November 6, 2019

Thank you for your help. I did make them volatile as some of my variables are accessed through the main function and interrupt, but the problem still occurs.

I couldn't build the code with optimization level -O0, it creates a lot of errors, I guess my code is too large for the memory of the MCU. it is around 27 to 29 kb in other optimization levels

alister
Senior III
November 6, 2019

>my global variables are losing their contents <snip> even when I declare them static

From "global" we understand they're static storage duration and you're declaring them in file scope. Declaring them static only affects linkage.

> Initial values are 0.

They're in bss and you're expecting this, or are you expecting they'd not be initialised? If you're expecting they'd be random at power-up and retain their values across warm-boots you'd need to put them in a section to prevent their initialising. I don't Keil. Refer the manual and/or Google.

Otherwise,

  1. Possibilities include over/under-running an array, bad cast of a pointer, uninitialised pointer, corrupt pointer perhaps caused by something else over/under-running an array or a task stack has underflowed another task stack, memory's wrapping because you're using unconnected address bits...
  2. You might first confirm you are writing the variable.
  3. If you've a jlink, you might watchpoint said variable so it breaks on the code that writes it.

Post some simple example code to improve the guessing.

ADSB
ADSBAuthor
Associate II
November 6, 2019

Thank you for your reply.

> I know they should be initialized as zero once I declare them static, what I meant, that they go back to the initialized value even after it was changed by the program. I confirmed that the variable was changed, but then it goes back.

The code is too large but I will try to share a routine that help you :

main.c:

static volatile flag = 0;
 
int main(void){
 
 while(1){
 // I am sending the flag value with UART here for checking
 if(flag == 1){
 toggleREDLED();
 }
 if(flag == 2){
 toggleGREENLED();
 }
 }
}
 
//this is just an example
timerInterrupt(){
 if(flag ==0){
 flag = 1;
 }else if(flag ==1){
 flag =2;
 }else if(flag==2){
 flag =1;
 } 
}

ok for example if the timer interrupt trigger every 10 sec, the RED LED will trigger only once, and the value of flag goes back to zero, once the while loop in the next iteration. and so on, basically the flag loses the value which was set to it by the interrupt, after one iteration, sometimes two iterations of the while loop.

I really hope I make my problem clear

Ozone
Principal
November 6, 2019

You could try a different approach.

Using a data breakpoint/watchpoint, and detect when a 0 is written to your flag variable.

Sebastian1
Associate II
June 21, 2020

I had the same problem, I made the changes suggested here and my problem continued until I found that the error was in my code, when I returned from an interrupt and re-evaluated the variable without first deactivating this interrupt, I would reset it again, perhaps this can be what is happening to you

edogr.1
Visitor II
February 22, 2023

I have an similar problem when I create a global array in main c like

GPIO_TypeDef* x[NO] ={A,B,..} after HAL_Init and RCC_Init command executes the first member content become zero.. I changed optimization settings and this situation solved. but I don't want to change optimization due to other issues what can be the cause of problem.

alister
Senior III
February 23, 2023

>GPIO_TypeDef* x[NO] ={A,B,..}

The definition places x in a data section.

> I changed optimization settings and this situation solved.

What can changing the optimization change? A quick Google finds https://scienceprog.com/function-calls-and-stacking-of-in-embedded-systems/, which explains it pretty well. Increasing optimization may reduce function stack frames and their sizes. As mentioned in an earlier comment, if the stack is too small and above the data section, then it will overflow as functions execute, culminating in the stack trashing variables in the data section.