avr-gcc-list
[Top][All Lists]
Advanced

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

Re: [avr-gcc-list] Serial Communication


From: Dave Hansen
Subject: Re: [avr-gcc-list] Serial Communication
Date: Thu, 29 Jan 2004 09:10:59 -0500

From: Neil Johnson <address@hidden>
[...]
> > #define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )

> The mask is used to maintain a ring buffer.

**CAUTION**

The masking trick works if the size of the buffer is a power of 2,
e.g. 2, 4, 8, 16, 32, 64, 128, 256, 512, etc

That way you can use bitwise AND to do the wraparound, e.g.

        index = (index + 1) & USART_TX_BUFFER_MASK;

For any other buffer size you need to use the more expensive modulo
operator "%":

        index = (index + 1) % USART_TX_BUFFER_MASK;

A couple nits to pick...

The second case should actually be

        index = (index + 1) % (USART_TX_BUFFER_MASK+1);

or

        index = (index + 1) % USART_TX_BUFFER_SIZE;

There is another option as well, that some might find clearer:

     if (++index >= USART_TX_BUFFER_SIZE)
        index = 0;

which should be more efficient than "%" if USART_TX_BUFFER_SIZE isn't a power of 2.

[...]
Discussion: one *could* stick with the BUFFER_SIZE value and hope the
compiler optimizes unsigned-modulo-with-(2^n) into bitwise AND-with-(2^n - 1).

Yes, it would be interesting to compare the code generated in each case when "USART_TX_BUFFER_SIZE" is a power of 2. A good compiler should be able to recognize the optimization and use the AND operation in both cases. I assume gcc is a good compiler, but I haven't examined this case yet...

Regards,
  -=Dave

_________________________________________________________________
High-speed users—be more efficient online with the new MSN Premium Internet Software. http://join.msn.com/?pgmarket=en-us&page=byoa/prem&ST=1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]