Re: Function prefix comments in C files



Peter Bushell wrote:
"Peter Bushell" <NOpeter.bushell@xxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:4346b20e_4@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

"Bo" <bo@xxxxxxxxxx> wrote in message news:51db6$434669a6$18d6ec55$16918@xxxxxxxxxxxxxx

"Peter Bushell" <NOpeter.bushell@xxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:43464d78_4@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx



I strongly agree with David over this. However, I do not believe he has gone far enough. Global variables are **bad news**! I've seen so many problems with their use over a long career, that I eventually decided to stop using them altogether.

How would you, in C, NOT use a global in the following circumstance?

100us counter incremented by an ISR
access needed to read us counter by ALL modules?


The counter would be static. The ISR would be in the same file and would access the static variable directly. Access functions (public, global, non-static - whatever you wish to call them) would also be provided, in that file, for use by other modules. Each of these access functions would disable interrupts around the access. The associated header file would publish these functions. It would probably be necessary to publish the ISR, also, so that its vector could be set up.


I hope that helps!


-- Peter Bushell http://www.software-integrity.com/



Important postscript...

Disabling interrupts around individual reads and writes is OK as far as it goes. Some people don't even do that, arguing that accesses to integers, say, are atomic. Well I'm more paranoid than that. Can we be sure that the compiler will generate a single instruction? Even if the structure containing the integer is packed? Even when someone decides to make the integer a long (or a long long)?


This will be dependant on your compiler-target combination. For example, on an 8-bit micro you can be sure that access to an int will *not* be atomic (since an int is at least 16 bit). Thus you need to do something like disabling interrupts, or doing multiple reads, if reading the volatile data - if the read is not atomic. So for accessing multi-byte volatile data in a safe way, access functions can sometimes be a good solution (though not necessarily the best or most appropriate solution).


Anyway, none of this helps if you're doing non-trivial read-modify-write operations. Then you have to do the protection round the whole operation. That's what I meant when I said that access functions can provide "at least some" of the required protection. Many applications, though, do simple reads and writes of buffers, which are shared between an ISR and a task (or main program). The r-m-w operations tend to be limited to things like incrementing a counter or bumping a pointer, and such operations can themselves be fully contained within their own access functions.


Of course you should use functions to ensure safe access to structures like buffers shared between ISRs and other parts of the program. I would not think of such data as "global" in the first place - it is private to the ISR's module. But supposing this module (say, a UART handler) also has a flag variable called "transmitting" that is declared as a volatile global variable. Only the UART module will ever change this flag, but other modules may want to read it. Where is the harm in exporting this as a global variable for all to read?
.