From: Fabio G. <fab...@au...> - 2007-04-23 15:31:56
|
Thanks; I agree 100% but I had couriosity to know more about this argument. Thanks a gain and rest regards. Alle 22:31, venerd=EC 20 aprile 2007, Stuart MENEFY ha scritto: > Fabio Giovagnini wrote: > > Hi all, > > I have found the following problem. > > I'm using gcc 3.2.3 hms for sh target; in particular I'm using the c > > compiler (gcc without g++) and Icompiled 3.2.3 - hms version without any > > patch. > > > > On sh2 7145 and 7044 I had no problem; now I'm porting a software on sh2 > > 7085 (7080 family; > > http://eu.renesas.com/fmwk.jsp?cnt=3Dsh7080_series_landing.jsp&fp=3D/pr= oducts > >/mpumcu/superh_family/sh7080_series/) and I discovered such a problem: I > > have this struct describing the AD converter registers: > > struct st_ad0 { /* struct A/D0= =20 > > */ > > ... struct contents cut ... > > > }; /* = =20 > > */ > > > > > > Reading the hw manual you can see ADCSR is a register accessible only as > > word (16 bit) so the only assembler allowed istruction to access the > > register is MOV.W; Obviusly if I write > > AD0.ADCSR.WORD |=3D BIT14 or AD0.ADCSR.WORD &=3D ~BIT14 > > what I read in assembler is correct; > > if I write > > AD0.ADCSR.BIT.ADIE =3D 1 or AD0.ADCSR.BIT.ADIE =3D 0 > > in assembler is used a MOV.B instruction being not allowed by the > > architecture. > > > > Is this a complier bug? How could I approach the problem? > > Obviusly I can avoid the bit field manupulation in the 16 bit access > > register but I'd like to have a full featured compiler. > > In general, I'd recommend against using structs like this to manipulate > hardware registers. Compilers just don't give enough guarantees about > what they will actually do when accessing registers in this way: > > - the exact layout of the structure isn't defined, and can vary > from compiler to compiler > > - the compiler is at liberty to reorder and optimise your code as it > sees fit to try and make it more efficient. volatile helps somewhat > in this but even this different compilers can interpret in > different ways. > > - hardware memory barriers are required on some architectures to > ensure that operations are performed in the correct order > > - buffers may need flushing to ensure data has actually left the > CPU, and other operations may be required to ensure data has > reached the register. > > This is why systems such as Linux use the readl(), writel() etc macros > to access registers, and have all the various memory barrier macros. > > It also makes the intention of your code much clearer. You know that > when a writel() call appears in your code it is touching hardware, > while a struct member assignment could be easily confused with > updating a software data structure. > > And when porting your code it makes it much easier to work out what > needs changing. > > Just my twopenny worth. > > Stuart =2D-=20 =46abio Giovagnini Aurion s.r.l. via degli orti 11, 40050 Funo di Argelato (BO) Tel. +39.335.8350919 =46ax +39.051.8659009 www.aurion-tech.com account telefono VoIP skype (www.skype.com): aurion.giovagnini |