VME board problem

Artem Kazakov kazakov at gmail.com
Mon Jan 22 05:50:28 UTC 2007


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
> >   
> 



More information about the users mailing list