CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

was “Number of bits out of range” problem fixed?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

was “Number of bits out of range” problem fixed?
PostPosted: Mon Jul 01, 2013 6:15 pm     Reply with quote

Colleagues,

This compiler error (or lack of feature) has come up in the past. For example in this thread and this one.

The problem is that the CCS compiler doesn't (or didn't) work with bit fields in a struct bigger than 8 bits.

Code:
typedef union              // AD7794 status register (read only) bit fields.  See Table 16 in [1]
{
   unsigned int8 i8;       // content as a byte
   struct
   {
      unsigned int8  Channel  : 3;
      unsigned int8           : 2;  // don't care
      unsigned int8  NoExtRef : 1;  // no external reference
      unsigned int8  Error    : 1;
      unsigned int8  Ready_n  : 1;
   }
   BitFields;
}
structAD7794StatusRegBits;

In the above code, the total length is 8 bits. It compiles and runs correctly.

Code:

typedef union     // AD7794 configuration register bits.  See Table 20 in [1]
{
   unsigned int16 i16;
   struct
   {
      unsigned int16 ChannelSelection  : 3;  // channel selection bits
      unsigned int16 Buffered          : 1;  // buffered or unbuffered
      unsigned int16 RefDetect         : 1;  // reference detect
      unsigned int16 RefSelection      : 2;  // reference selection
      unsigned int16 GainSelection     : 3;  // gain selection             // (!) compile-time error generated  here
      unsigned int16 Boost             : 1;  // bias current
      unsigned int16 Unipolar          : 1;  // U/B#
      unsigned int16 BurnoutCurrentEn  : 1;  // burnout current enable
      unsigned int16 VBiasSelection    : 2;  // used in conjunction with Boost bit
   }
   BitFields;
}
strucrtAD7794ConfigRegBits;

In the above code, the total length is 16 bits. CCS generates an error “Number of bits out of range”.

I'm still using the old version 4.081. (Primarily because of "don't change it, if it ain't broke" agreement with regulatory people involved.)
Was “Number of bits out of range” problem fixed in the newer version of the compiler Question

Any suggestion, insight or reference is really appreciated!

Cheers,
- Nick
_________________
Read the label, before opening a can of worms.
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

PostPosted: Mon Jul 01, 2013 7:32 pm     Reply with quote

Try swapping these two lines:
Code:
 
     unsigned int16 RefSelection      : 2;  // reference selection
     unsigned int16 GainSelection     : 3;  // gain selection   
 


Quote from TTelmah in one of the posts you listed:
Quote:
In CCS, the default int size, is 8bits, and bit fields in structures have to fit inside this.

_________________
Google and Forum Search are some of your best tools!!!!
kender



Joined: 09 Aug 2004
Posts: 768
Location: Silicon Valley

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Mon Jul 01, 2013 9:56 pm     Reply with quote

It had compiled with the change, which you've proposed.

At first, I thought that this change would undermine this use case. The order of the bit fields should corresponds to that in a register of particular external peripheral**. If the order is changed, this would scramble*** the contents from AD7794’s standpoint. The idea behind this union struct is to be able to assign the bit fields using dot notation (convenient), then send them “in bulk” as bytes (convenient).

Code:
strucrtAD7794ConfigRegBits sConfigReg;
sConfigReg.RefSelection = 0b00;
sConfigReg.GainSelection = 0b111;
// … assign more bit fields

spi_xfer( make8(sConfigReg.i16, 1) );        // spi communication code simplified for brevity
spi_xfer( make8(sConfigReg.i16, 0) );


At first, I thought that one of the bit fields straddles the boundary between the 2 bytes. But then I've noticed that ChannelSelection bit field is 4 bits instead of 3. After that change, there is not bit field, which straddles.

Other 16-bit registers in AD7794 also don’t have a straddling bit field. Is this luck? Did the designers of AD7794 deliberately (and with foresight) avoid having a bit field, which straddles across the bytes boundary? What if designers of some other hypothetical IC with 16-bit registers didn’t have such foresight?

** AD7794, which is an A/D converter with SPI interface. The register is described in the Table 20 in the datasheet.
*** ever so slightly ;)
_________________
Read the label, before opening a can of worms.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Jul 02, 2013 1:05 am     Reply with quote

I think, it's quite obvious that bitfields over larger entities than a byte are useful in some situations. Bit structures
defined by external hardware are one of several cases where it's not appropriate to reorder the fields.

CCS decided not to supported it with 8-bit compilers, and there's no change in recent V5.
So you need to assemble and decode byte crossing bit fields in your code manually.

The more anoying thing in my view is that altough nominally supported with 16-Bit PCD compiler, they never
worked without some bugs, even up to new V5 versions.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Jul 02, 2013 1:07 am     Reply with quote

In the example you give there are fifteen bits NOT 16. Depending on endianness and left v right alignment, one field, GainSelection, may straddle the byte boundary. On machines with 16 or more bits this is not a problem, but on 8 bit machines byte straddling is likely to cause trouble.

In the general case, using bit fields to access bits and parts of data is not foolproof not risk free. It may work in C, and if it does that's clearly a good thing, but there is no guarantee.

Instead its generally better to do bit field extraction and manipulation explicitly in code rather than relying on the compiler - any compiler - to always generate correct code for you. These problems most commonly arise when a processor is called on to deal with data streams/structures/packets from other devices. Sometimes the trick of constructing a compatible data structure to cover the data works, sometimes it doesn't. That is was never the intended purpose of bit fields in C - it was to make more efficient use of limited memory at the expense of increased processing speed. When it doesn't you just have to do it by other ways, such as bit masking and shifting.

In this case you are trying to overlay a bit field defined structure over data from/to an ADC. You are dealing with just 15 bits. I'd almost certainly not have even bothered to use bit fields, and simply gone for bit manipulations right from the start. Sure the bit field version looks nice, and gives compact and easy to understand source code which is a clear plus, but its so implementation dependant that there's bound to be trouble at some time or another.

Looking at this, I personally have doubts that there is any actual "problem" to be fixed in the compiler. Rather its an unrealistic expectation on the part of the user: i.e. that all machines and compilers will implement bit fields in the manner the user expects. You don't just have to take my word for it; here is a quote from "The C Book", publications.gbdirect.co.uk/c_book/chapter6/bitfields.html :

"The main use of bitfields is either to allow tight packing of data or to be able to specify the fields within some externally produced data files. C gives no guarantee of the ordering of fields within machine words, so if you do use them for the latter reason, you program will not only be non-portable, it will be compiler-dependent too. The Standard says that fields are packed into ‘storage units’, which are typically machine words. The packing order, and whether or not a bitfield may cross a storage unit boundary, are implementation defined. To force alignment to a storage unit boundary, a zero width field is used before the one that you want to have aligned."

RF Developer
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Jul 02, 2013 2:02 am     Reply with quote

Bitfields are a standard C element and working flawlessly in most embedded C compilers. Restrictions
are however admitted by the C standard, e.g. not to allow crossing of specific implementation dependent
storage element boundary. K&R, 2. edition states:

Quote:
A bit−field, or field for short, is a set of adjacent bits within a single implementation−defined storage unit that we will call a ``word.''
(...)
Almost everything about fields is implementation−dependent. Whether a field may overlap a word boundary is implementation−defined. Fields need not be names; unnamed fields (a colon and width only) are used for padding. The special width 0 may be used to force alignment at the next word boundary.

Fields are assigned left to right on some machines and right to left on others. This means that although fields are useful for maintaining internally−defined data structures, the question of which end comes first has to be carefully considered when picking apart externally−defined data; programs that depend on such things are not portable. Fields may be declared only as ints; for portability, specify signed or unsigned explicitly. They are not arrays and they do not have addresses, so the & operator cannot be applied on them.


On a machine with a 16-bit machine word size, e.g. PIC24, correct operation over this size can be
however expected. Needless to say that Microchip C30 or C32 have no problems of this kind.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group