Issue with variables used in interrupts that are NOT assigned volatile.

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

I have a very short main.c that assigns a SysTick interrupt with a non-volatile assigned variable (uint32 systick = 0;) named systick that gets incremented every time the interrupt occurs.

Simple.  Note:  Using Creator 4.2

In main(), I compare the systick value for different values to make decisions.  The code 'hangs' looking for systick to get to 100.  (In debug mode, the code hangs yet the systick exceeds the value be checked)

If I assign the systick as volatile (volatile uint32 systick =  0;), the code DOES NOT hang!

I think the compiler is assuming the systick variable can be register assigned (nonvolatile) in main().  Yet when I hover over the systick var, it can far exceed the value being compared.

Attached is a very small archive of the program that exhibits this issue.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
1 Solution
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi,

The compiler might have optimized out your statements based on the non-volatile value. Once you define the volatile keyword, the portion of the code might not have been optimized out. Every global variable that is changed in an interrupt handler must be declared as volatile.

Best Regards,
VSRS

View solution in original post

0 Likes
7 Replies
lock attach
Attachments are accessible only for community members.
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Here's the attachment:

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi,

The compiler might have optimized out your statements based on the non-volatile value. Once you define the volatile keyword, the portion of the code might not have been optimized out. Every global variable that is changed in an interrupt handler must be declared as volatile.

Best Regards,
VSRS

0 Likes

Bob,

Thanks for the link.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
Anonymous
Not applicable

Hi Len,

For understanding what's happening, you can take a look at the assembly code diff below. .L9+4 holds the address of the systick variable. You can see a missing part in while(systick<100u) in non-volatile case. systick value is not continuously read. That is why, it gets stuck there.

AssemblyCodeDiff.png

-Rajiv 

Rajiv,

Again many thanks for the help here.  My bad!  I assumed variables declared outside of functions can't be optimized into registers.

I've been corrected.

You'd  think that if the compiler found a variable declared outside a function and used in two different functions (especially if one of the functions was called in an interrupt service routine), it would default to volatile.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
Anonymous
Not applicable

You're welcome Len.

0 Likes