>If you plan on changing the value of a
>global variable from within an interrupt handler and then also use it
>outside of an interrupt handler, you should add the volatile keyword
Erik is correct, but even if you add volatile, there are other potential
problems lurking that may eventually show up.
The code Shahzad posted calls sec_wait() from within both interrupt
routines and also from the main program, and at first glance it appears
that the two interrupts have different priority levels so it's possible
that 3 instances of sec_wait() could be executing concurrently. Any
function that could be executed concurrently must be reentrant (not
share its local variables with other instances). As written, sec_wait()
appears to only use registers even though it is not declared as
reentrant, so it is ok. But if the code is modified later to have a
second parameter or some local variables, by default SDCC will use
statically allocated memory and the code will fail in strange
difficult-to-reproduce ways when multiple instances unintentionally
share the same static data.
Another common problem, which doesn't appear to exist yet in this very
simple code, is needing atomic access to variables when accessing them
in the main program or lower priority interrupts. When you access a
variable that is also used within an interrupt routine (which should be
declared volatile), you must be careful of the case where an interrupt
routine accesses the variable at the same time. With 16 and 32 bit
variables this is a larger problem because the interrupt routine might
execute between the main program's (or lower priority interrupt's)
access to the individual bytes. The usual approach is to disable the
interrupt, access the shared data and then reenable the interrupt. This
also applies to groups of related variables, such as a buffer and "head"
and "tail" pointers into its contents.
Unlike most simple software bugs, these interrupt data sharing issues
are very difficult to troubleshoot because they only occur when the
interrupt executes at some exact moment relative to the main program (or
lower priority interrupt). Often times they go unnoticed during testing
and then some later code change "triggers" them. Or they go unnoticed
during product development but "in the field" the code fails very
mysteriously in ways that don't seem reproducable.