[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

VME board problem



Hi, Till! 

Thank you very much for your advice. After making all register pointer
volatile the program started to work. 

Cheers, 
Tyoma.

On Fri, 19 Jan 2007 00:23:51 -0800
Till Straumann <strauman at slac.stanford.edu> wrote:

> A quick look at your
> 
> void done(int addr)
> {
>     unsigned char x;
> 
>     do {
>         x = *(unsigned char *)(addr+CR10);
>     } while(x & 0x8);
> }
> 
> routine reveals a typical, excuse me, novice error.
> Device register pointers must be declared 'volatile'
> [here: (volatile unsigned char*)].
> Otherwise, the compiler (RTEMS' gcc is probably more
> recent than vxworks' and hence optimizes more aggressively)
> optimizes your code into
> 
> if ( (*(unsigned char*)(addr + CR10)) & 0x8 )
>     while (1);
> 
> (because it doesn't know that the register contents
> can change due to 'external' causes).
> 
> IMHO this way of accessing device registers is
> generally bad practice:
>   - device access is not explicit but implicit
>   - not portable (endian issues in case of wider registers,
>     execution ordering issues)
> 
> In particular, be aware that the powerpc (and other
> modern CPUs probably, too) don't necessarily execute
> instructions in the order you code them. The powerpc
> may reorder instructions if this wouldn't change program
> behavior under the assumption that all accesses are
> to 'ordinary memory' w/o side effects.
> 
> Consider, e.g., a device with two registers: a 'trigger'
> register and a 'result' register. Writing something to 'trigger'
> causes the device to do something and the result of the operation
> can be read from the 'result' register.
> 
> int
> read_device() {
>  *trigger_reg_p = 1;
>  return *result_reg_p;
> }
> 
> Even if the compiler generated instructions exactly in the
> specified order, the powerpc may still execute them as
> 
>  x = *result_reg_p;
>  *trigger_reg_p = 1;
>  return x;
> 
> (because if '*result_reg_p' and '*trigger_reg_p' were ordinary
> variables in memory this reordering wouldn't matter but may
> allow for more efficient use of CPU resources.)
> 
> A special instruction ('eieio') is required to enforce ordering of
> the load with respect to the store operation.
> 
> For these reasons, it is strongly recommended to use the
> I/O operations defined in libcpu/io.h
> 
> HTH
> -- Till
> 
> Artem Kazakov wrote:
> > Hello everybody.
> >
> > I'm using RTEMS-4.6.99 on MVME-5500 board.
> > Recently I tried to use an ADC board PVME-303 and I failed. I have a
> > simple test program which successfully runs under VxWorks, but under
> > RTEMS it just loops forever.
> > In short the program does the following: it makes several writes to
> > configuration registers of ADC board. And then it reads DATA register
> > for data.
> > After configuring the ADC board and before reading data, the program
> > is supposed to check "DONE" bit. When it turns 0 we can proceed to
> > reading data. But for some unknown reason "DONE" bit never turns 0
> > when I use RTEMS.
> > The only difference between those two programs is that under RTEM
> > environment VME A24 window is locate on 0x9f000000 and under VxWorks
> > it is located on 0xeff00000.
> > And of course necessery headers are added in RTEMS case.
> > Any suggestions what might be the cause of that behaviour?
> > What to check?
> > Please help me.
> > I attach two versions of the program for VxWork and for RTEMS.
> >
> > Best regards,
> > Artem Kazakov
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > rtems-users mailing list
> > rtems-users at rtems.com
> > http://rtems.rtems.org/mailman/listinfo/rtems-users
> >   
>