This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Bitfield Array

Hello to everyone,
I want to my ARM7 to access a (const)bitfield array, but as i'am absolute beginner not sure about C-syntax. My textbook don't includes Bitfield-Array.
Hope someone takes a look at this:

struct
{
unsigned char red[32]                   :1;
unsigned char orange[32]                :1;
unsigned char yellow[32]                :1;
unsigned char green[32]                 :1;
unsigned char blue[32]                  :1;
unsigned char violett[32]               :1;
} my_color;
const my_color.red[]    ={1,0,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,0,1,1,1,1,0,1,1};
const my_color.orange[] ={0,1,0,1,1,1,0,0,1,1,1,1,0,1,0,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,1};
const my_color.yellow[] ={1,0,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,0,1,1,1,1,0,1,1};
const my_color.green[]  ={0,1,0,1,1,1,0,0,1,1,1,1,0,1,0,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,1};
const my_color.blue[]   ={1,0,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,0,1,1,1,1,0,1,1};
const my_color.violett[]={0,1,0,1,1,1,0,0,1,1,1,1,0,1,0,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,1};
int main (void)
{
        int i;

        for(i=0;i<32;i++)
        {
                printf("%u ",my_color.red[i]);
                printf("%u ",my_color.orange[i]);
                printf("%u ",my_color.yellow[i]);
                printf("%u ",my_color.green[i]);
                printf("%u ",my_color.blue[i]);
                printf("%u ",my_color.violett[i]);
                printf("%u\n",i);
        }
        while(1){}


first as i tried some syntax-variations i just got normal errormessages or programms didn't what i expected to do. But suddenly after some time my programm makes CA stop with a WINDOWS errormessage
:ca.exe hat Fehler verursacht und wird geschlossen. Starten Sie das Programm neu. Ein Fehlerprotokoll wird erstellt. OK
How can i bring my little blinky-toy to the water?
:-)

  • C does not have bit arrays. A small change gets you closer (the formatting renders in the preview, but might not after posting):

    #define HEX__(n) 0x##n##LU
    #define B8__(x) (((x&0x0000000FLU)?1:0) + \ 
                     ((x&0x000000F0LU)?2:0) + \ 
                     ((x&0x00000F00LU)?4:0) + \ 
                     ((x&0x0000F000LU)?8:0) + \ 
                     ((x&0x000F0000LU)?16:0)+ \ 
                     ((x&0x00F00000LU)?32:0)+ \ 
                     ((x&0x0F000000LU)?64:0)+ \ 
                     ((x&0xF0000000LU)?128:0))
    #define B8(d) ((unsigned char)B8__(HEX__(d)))
    #define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24)+ \ 
                                    ((unsigned long)B8( db2)<<16)+ \ 
                                    ((unsigned long)B8( db3)<<8) + \ 
                                                    B8(dlsb))
    struct
    {
        unsigned long red;
        unsigned long orange;
        unsigned long yellow;
        unsigned long green;
        unsigned long blue;
        unsigned long violett;
    } my_color;
    const my_color.red    = B32(10111100,11110111,11111010,01111011);
    const my_color.orange = B32(01011100,11110100,11011111,10111001);
    const my_color.yellow = B32(10111100,11110111,11111010,01111011);
    const my_color.green  = B32(01011100,11110100,11011111,10111001);
    const my_color.blue   = B32(10111100,11110111,11111010,01111011);
    const my_color.violett= B32(01011100,11110100,11011111,10111001);
    int main (void)
    {
        int i;
        unsigned long mask = 0x80000000;
    
        for(i=0;i<32;i++)
        {
            printf("%c ",(my_color.red     & mask) ? '1' : '0');
            printf("%c ",(my_color.orange  & mask) ? '1' : '0');
            printf("%c ",(my_color.yellow  & mask) ? '1' : '0');
            printf("%c ",(my_color.green   & mask) ? '1' : '0');
            printf("%c ",(my_color.blue    & mask) ? '1' : '0');
            printf("%c ",(my_color.violett & mask) ? '1' : '0');
            printf("%c\n",i);
        }
        while(1){}
    }
    

  • Sorry, I didn't catch the nuance of your last printf() and I forgot to shift the mask.

            :
            :
            printf("%u\n",i);
            mask >>= 1;
        }
        while(1){}
    }
    

  • Dear Dan,
    thank for your prompt reply.
    After finding my own solution i'been proud.
    This last's only for about five minutes.
    After i've seen growing the ARM's Data when i enlarged the array-size it brings my feets back to the ground.
    C can make you feel as if there are bitfield-array's.
    But internaly C uses more than a bit for each bit.
    You only have the comfort to handle with bit's.
    The price is waste of memory.
    Now my (weird) solution:

    //try "const struct" to see ARM7 in Abort-Mode :-)
    struct
    {
    unsigned char red                       :1;
    unsigned char orange            :1;
    unsigned char yellow            :1;
    unsigned char green                     :1;
    unsigned char blue                      :1;
    unsigned char violett           :1;
    }color[8]={
    1,0,1,0,1,0,
    0,1,0,1,0,1,
    0,0,0,0,0,0,
    0,0,0,0,0,0,
    1,1,1,1,1,1,
    1,1,1,1,1,1,
    };
    //***************************************************************************
    int main (void)
    {
    //***************************************************************************
            unsigned int i;
            PLL_init();
            RS232_init(115200);
            printf("Bitfield array in C\n");
            for(i=0;i<8;i++)
            {
                    color[i].orange = ~color[i].red;//"~" or "!" which i correct?
                    color[i].yellow = !color[i].red;
            }
            for(i=0;i<8;i++)
            {
                    printf("%u ",color[i].red);
                    printf("%u ",color[i].orange);
                    printf("%u ",color[i].yellow);
                    printf("%u ",color[i].green);
                    printf("%u ",color[i].blue);
                    printf("%u ",color[i].violett);
                    printf("\n");
            }
            while(1){}
    }
    
    


    Another side effect:
    Defining struct as const and altering it afterwards, brings ARM7 into Abort-Mode. There's no compiler warning.

    Question which is right:
    My_bit_a = ~My_bit_b;
    My_bit_a = !My_bit_b;

    Which operator? ~ or !

  • "Question which is right:
    My_bit_a = ~My_bit_b;
    My_bit_a = !My_bit_b;

    Which operator? ~ or !"

    For single bits the result is the same. For bitfields wider than one bit, use '~'.

  • But internaly C uses more than a bit for each bit.
    You only have the comfort to handle with bit's.
    The price is waste of memory.

    That's quite universally wrong. Almost all existing C implementations use exactly one bit for a one-bit bitfield. But that doesn't change that the smallest actaully adressable unit of memory is still one byte. Which means that no, you can't have a pointer to a single bit, nor an array of bits, and yes, there will be padding between bitfields and non-bitfield parts of a struct. There may even be padding inside bitfields.

    Bitfields are for giving names to parts of a byte (or bigger integer type). As long as controllers arr 8-bit, 16-bit or wider, C can't point to a single bit in any portable fashion.

  • And one byte is not guaranteed to be 8 bits large. Only to be _at least_ 8 bits. If the machine have 36-bit word size (some older IBM mainframes), it may have 9-bit bytes.

    There are no required standard for the placement of bit or byte paddings (except that specific operating systems defines byte padding standards for access to OS system calls) and bit-fields may be stored left-aligned, right-aligned or in the middle of an integer.

    The bit-fields where not invented for mapping of physical bits in microcontrollers, but for creating small (signed or unsigned) integers for better packing of data when the full numeric range of the native integer sizes wasn't needed.

    When using bit fields, it is very important to remembered that two-complement storage means that a 1-bit signed bit field can only store the values -1 and 0. Testing the bit field for the value ==1 is one of the most common errors.

    As long as the software doesn't performs binary writes of the bitfields to processor registers, to files or over communication channels, there are no compatibility problems with them.

    When fiddling with bits in a microcontroller, the bit operations (& | ~ << >> ^) are normally used instead, since they are portable between compilers.