Jump to content
csym

Watch Window, Variables Showing "error" Value

Recommended Posts

Hello all.

 

I hope this is not an RTFM issue, but can not quite figure this out...

 

I'm debugging my code, and for reason unknown the watch window

shows "error" value for some variables. What makes this even more

confusing is that the variables I'd like to watch are all be in scope as

they are declared in beginning of the function, like this:

 

 

static void Timer1_Event_Handler(void)

{ unsigned char i,

button_port,

button_bit,

isr_ctrl_button_pushed_bit,

isr_ctrl_button_released_bit,

isr_ctrl_button_msg_sent_bit,

isr_ctrl_button_filter_running ,

msg_button_pushed_bit;

 

 

I set a breakpoint in Timer1_Event_Handler function, and some of

the variables show up fine, some with value "error". How come?

My project has originally been started as wizard generated for PIC

16F877A. After a while I had to add linker option "-swcs 6 2" as size

of the code grew up. Could software stack have anything to do with this?

 

Help is really appreciated!

 

TIA

Share this post


Link to post
Share on other sites

Ok, now this is getting even more weird.

Changed variable declaration to global scope

from function scope and now the values seem

to update fine in watch window. What the...?

 

However, I'd like to keep my code tidy and

have declarations where they ought to be, so

any ideas, what am I missing? No variable

declarations in interrupt service routine allowed?

 

Thanks...

Share this post


Link to post
Share on other sites

It may be due that the local variables have no assignment within the function and therefore unused so have been optimized out.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites
I'm debugging my code, and for reason unknown the watch window

shows "error" value for some variables. What makes this even more

confusing is that the variables I'd like to watch are all be in scope as

they are declared in beginning of the function, like this:

 

 

static void Timer1_Event_Handler(void)

{ unsigned char i,

button_port,

button_bit,

isr_ctrl_button_pushed_bit,

isr_ctrl_button_released_bit,

isr_ctrl_button_msg_sent_bit,

isr_ctrl_button_filter_running ,

msg_button_pushed_bit;

If you don't refer to the variables in the code, then they will be optimised away. Then there is nothing to watch. Try assigning values to them so they are used, and then try to watch them.

 

Regards

Dave

Share this post


Link to post
Share on other sites

I have found that variables in an interrupt routine should be declared as "volatile" otherwise they are very likely to get optimised away.

Share this post


Link to post
Share on other sites

Hello again, and thank you for your answers. I didn't mention in my earlier posts that I also tried to assigning values to variables, but that was also no help. Viewing assembly code bar also showed that variables are allocated and not optimized out.

 

I have found that variables in an interrupt routine should be declared as "volatile" otherwise they are very likely to get optimised away.

 

Turns out that what you Alex suggested helped in my problem. Declaring the variables as volatile shows them in watch window, no matter if they have initial value assignment or not.

 

So now that my problem is gone, I'm still curious to know what causes this kind of behaviour?

 

Thanks!

Share this post


Link to post
Share on other sites

I'm no expert on optimisation and its all a bit of a black art as far as I'm concerned but from what I gather when the compiler does it's thing it goes through the variables and any variable that it can't see being used in the program gets deleted. Then any variable that is not changed in the program gets converted to literal constant.

 

Since the ISR is not logically connected to the main program any variable in the ISR is seen as either unused or unchanging so gets either deleted or converted to a literal constant. Making them volatile tells the compiler to leave them alone.

 

The first time I came across this it took me days to figure out what was going on. I was setting a global flag in the ISR and reading in in the main function, I could see the program jump to the ISR but the flag would not change no matter what I did. The compiler in its wisdom had optimised the flag to a literal constant! Marking the flag as volatile solved the problem.

Edited by AlexR

Share this post


Link to post
Share on other sites
I have found that variables in an interrupt routine should be declared as "volatile" otherwise they are very likely to get optimised away.
Not true. Variables declare in an interrupt routine just as you normally would. Volatile indicates that the variable can be changed by something external (like it is a register that maps to an input port), the compiler then knows it cannot cache this value and must always read from and write to that actual register when it is referenced in the code.

 

Since the ISR is not logically connected to the main program any variable in the ISR is seen as either unused or unchanging so gets either deleted or converted to a literal constant. Making them volatile tells the compiler to leave them alone.
Not true.

 

The first time I came across this it took me days to figure out what was going on. I was setting a global flag in the ISR and reading in in the main function, I could see the program jump to the ISR but the flag would not change no matter what I did. The compiler in its wisdom had optimised the flag to a literal constant! Marking the flag as volatile solved the problem.
Possible, it is correct to mark any variable used in both the main routine and and ISR as volatile. If you don't do this, the main code may take a copy of the variable, so when it is changed in the ISR the change is not seen. Using the volatile keyword causes the compiler to always read the original source of the data every time it is referenced.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Alex, Dave,

 

The first time I came across this it took me days to figure out what was going on. I was setting a global flag in the ISR and reading in in the main function, I could see the program jump to the ISR but the flag would not change no matter what I did. The compiler in its wisdom had optimised the flag to a literal constant! Marking the flag as volatile solved the problem.
Possible, it is correct to mark any variable used in both the main routine and and ISR as volatile. If you don't do this, the main code may take a copy of the variable, so when it is changed in the ISR the change is not seen. Using the volatile keyword causes the compiler to always read the original source of the data every time it is referenced.

 

Hum? In my case variables in question are declared and used only in ISR, so main routine does not have access to them (as far as my understanding goes in compiling and allocating memory locations in generated assembler code. Also, I planned my code in a way that there's only one flag bit playing a role of a mutex that gives access to shared memory locations between ISR and main routine. I've used this piece of code for couple of years now for various PICs and I don't think this has anything to do with my original question.

 

What I am thinking now is that this may have something to do assigning constants to these variables. Sounds so Fox Mulder that it makes me wish I had never ever seen a computer at first place. Wouldn't be the first time to see that my code is a piece of junk. :)

 

I'll let you know if I have figured out anything new. So far, guys, thank you very much for you help!

Share this post


Link to post
Share on other sites
Hum? In my case variables in question are declared and used only in ISR, so main routine does not have access to them (as far as my understanding goes in compiling and allocating memory locations in generated assembler code. Also, I planned my code in a way that there's only one flag bit playing a role of a mutex that gives access to shared memory locations between ISR and main routine.
Use of volatile is not required in this case except for the shared flag.

 

Regards

Dave

Share this post


Link to post
Share on other sites
Hello again, and thank you for your answers. I didn't mention in my earlier posts that I also tried to assigning values to variables, but that was also no help. Viewing assembly code bar also showed that variables are allocated and not optimized out.

 

I have found that variables in an interrupt routine should be declared as "volatile" otherwise they are very likely to get optimised away.

 

Turns out that what you Alex suggested helped in my problem. Declaring the variables as volatile shows them in watch window, no matter if they have initial value assignment or not.

 

So now that my problem is gone, I'm still curious to know what causes this kind of behaviour?

 

Thanks!

I think you have to do more than just init the variable. If the variable is only initialized and then not used again, then it can either go out of scope or become literal. You may not see this in the assembly code.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...