We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Should I be using the "volatile" declaration with the Keil C compiler? It hasn't made a difference so far - as far as I can tell (which may or may not mean anyting). The manuals make no reference to it one way or the other.
"The manuals make no reference to it one way or the other." That's because there is nothing special about it in Keil C51 - it has the standard ANSI 'C' meaning & behaviour. The manuals do not attempt to teach you the 'C' language - they assume that you know the language, and focus only on the issues & extensions specific to the implementation. Therefore you need to consult a standard 'C' textbook for this.
Well, actually the question is - does it matter, or does the Keil compiler automatically know what is a register and what's not, in the same way that it knows how to handle RTX51Tiny tasks. I'm thinking particularly of sbit and sfr declarations.
"Well, actually the question is..." Always helps if you ask the question that you actually want answered...! ;-) "does the Keil compiler automatically know what is a register and what's not" The Compiler knows nothing - you have to tell it by making suitable definitions. I do believe that 'volatile' is implied by the sfr and sbit extended keywords
What about a variable that is used for declaration between 2 RTX51Tiny processes (with os_switch_task or os_wait moderating between the two)? From one tasks point of view, the variable magically changes from one reference to the next.
Any variable which can be changed by something outside of a very narrow "local" view of the immediate code should be declared volatile. This includes variables shared with other tasks and variables shared with interrupt handlers, as well as addresses that overlay hardware addresses and might be updated by the hardware. Imagine yourself as the code generator producing instructions for a particular line of C, and ask yourself if you would know that a task switch occurred, or if an interrupt occurred, and so on. Volatile is the hint from the programmer to the code generator that it can't be sure the value hasn't changed by some means outside of its scope, and thus must reload the variable, avoid optimizing out apparently redundant writes, and so on. (This is in general true of all compilers, not just Keil. It's the standard meaning of volatile, and why the keyword exists.)
"Any variable which can be changed by something outside of a very narrow "local" view of the immediate code should be declared volatile. This includes variables shared with other tasks and variables shared with interrupt handlers, as well as addresses that overlay hardware addresses and might be updated by the hardware." There are additional considerations when preemptible task switching and interrupts are used. In these situations volatile will not help (but won't necessarily hurt). When manipulating variables of more than one byte in size, you (the coder) have to guaranty mutually exclusive access, since the MCU can't modify multi-byte data objects atomically. Even with 1-byte data objects, you've got to know whether the manipulation is atomic by examining the compiler output.
Well, of course. Under RTX51Tiny, if the pre-emptive task-switching is turned off then it can't change tasks unless allowed to by an os_switch_task or os_wait call.
"Well, of course. Sorry to have offended you by stating the obvious.