Global variables losing their contents, using Keil and STM32l031k6
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-05 8:14 AM
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
- Labels:
-
Keil
-
STM32L0 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-05 8:22 AM
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.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-05 10:23 AM
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 ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-05 4:58 PM
>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,
- 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...
- You might first confirm you are writing the variable.
- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-06 1:57 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-06 2:01 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-06 2:21 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-06 3:21 AM
You could try a different approach.
Using a data breakpoint/watchpoint, and detect when a 0 is written to your flag variable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-06 7:31 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-21 11:00 AM
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
