cancel
Showing results for 
Search instead for 
Did you mean: 

Global variables losing their contents, using Keil and STM32l031k6

ADSB
Associate III

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

11 REPLIES 11

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
Piranha
Chief II

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 ?

alister
Lead

>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.

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

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.

ADSB
Associate III

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

You could try a different approach.

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

Per your example...

> they should be initialized as zero once I declare them static

No, "flag" is initialised zero because its definition gives it static duration. The "static" specifier only gives it local linkage.

> they go back to the initialized value

Does the "example" execute and manifest the bug? Can't see all the code so still guessing. Perhaps you're app's resetting and rebooting and you don't realise? An unexpected break on main would indicate it. If this is the case, there's some info about identifying reset causes at https://stackoverflow.com/questions/34196663/stm32-how-to-get-last-reset-status.

> static volatile flag = 0;

> timerInterrupt(){

Don't like implicit ints. C99 and later disallow. Perhaps warnings are turned off? If they're off, turn them on. Warnings indicate ambiguities in the code that might be mistakes. One might be the cause of the bug. Good code compiles without warnings with all warnings enabled.

Sebastian1
Associate II

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