[En-Nut-Discussion] Hardware Register Access Using Volatile Pointer
enut at cicely.de
Tue Apr 26 18:45:56 CEST 2011
On Tue, Apr 26, 2011 at 02:55:28PM +0200, Harald Kipp wrote:
> Hi Bernd,
> On 4/26/2011 1:00 PM, Bernd Walter wrote:
> > On Tue, Apr 26, 2011 at 09:27:50AM +0200, Harald Kipp wrote:
> >> On 4/25/2011 10:45 PM, Bernd Walter wrote:
> >>> On Mon, Apr 25, 2011 at 07:51:25PM +0200, Harald Kipp wrote:
> >>>> #define inr(_reg) (*((volatile unsigned int *)(_reg)))
> >>> typedef volatile unsigned int AT91_REG;// Hardware register definition typedef struct
> > In the end I think it's just a different style with different pros and
> > cons.
> Definitely there are no pros for using the "Atmel style", except
> personal preference:
It personally think typesafe controller pointers are pro.
> > I personally use the Atmel style in my own projects,
> > which sometimes
> > is tricky since there are name clashings with ethernut includes.
> This is even tricky within Nut/OS. Following the good old style of
> avr-libc, we try to use port and bit names from the datasheet. This
> helps to remember the names. The bad thing is that Atmel datasheets are
> not written with C programming in mind.
Yes - that's definitive a pro for the other way.
Buty I don't fight for either style.
For me the biggest pro is not to change it without good reason, so that
means to stay with inr/outr.
> > A (compiler) memory barrier isn't just writing imode - it also writes
> > other registers, which are unrelated.
> That's the other side of the coin.
> > It's only the programmer who knows wether a barrier or volatile variable
> > is the better option.
> My view differs. If the programmer knows better, than he better use
> memory barriers instead of volatiles. Simple reason: There are cases,
> where the order of I/O register reading and writing is not important at
> all. Why not let the compiler decide and only use memory barriers where
True, but do you think that the programmers order is usually that bad?
If you read/write 10 registers without specific order requirement.
How likely do you think that the compiler can gain a win by reordering
Masking registers can be a different thing.
If you mask a register multiple times then doing it with a volatile
register requires them to be done individually while a compiler can
optimize it into one read/modify/write, but then again - it's easy
for the programmer to write it into a single line if it matters.
> >> That's the point. I assume too, that the suggested approach will remove
> >> inr(). Further, I'm not sure, that an access to volatile memory will be
> >> kept, if the result is not used in the code. I wasn't able to find any
> >> document on this either.
> > Yes - but with defining it volatile the compiler can't know that reading
> > won't change anything - as it surely does for reading hardware registers.
> > It is free to remove the dummy variable itself, which I think is a good
> > thing.
> That's your opinion. You may call me an awkward doubter, but again my
> question: Is this documented anywhere? Are you sure that the compiler is
> aware, that a read may effect the source?
Well - that's the reason for volatile.
Fortunately someone already came up with a definitive documentation.
This is GCC documentation and not C, so you still might have doubts about
> What I understood is, that volatile means for reading, that the compiler
> must reload the value each time before using it. I can't find any
> document that states, that the read is done in any case, even if the
> result is not needed.
Other viewing point:
We all know that it _does_ influence hardware - that's the reason why
we want to see the read actually happen.
What else do we have in C language?
> A few tests with GCC 4.6 showed, that the read is conserved. But is that
> a proof?
It's just an evidence - the documentation is a proof, but just for GCC.
B.Walter <bernd at bwct.de> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.
More information about the En-Nut-Discussion