Hello,
I'm using Keil MDK 3.80a on STM32 and trying to use the bitband attribute to access individual bits in a 32bit register.
typedef struct { uint32_t a0: 1; uint32_t b0: 1; uint32_t c0: 1; uint32_t d0: 1; uint32_t e0: 1; uint32_t f0: 1; uint32_t g0: 1; uint32_t h0: 1; //8bit uint32_t a1: 1; uint32_t b1: 1; uint32_t c1: 1; uint32_t d1: 1; uint32_t e1: 1; uint32_t f1: 1; uint32_t g1: 1; uint32_t h1: 1; //8bit uint32_t a2: 1; uint32_t b2: 1; uint32_t c2: 1; uint32_t d2: 1; uint32_t e2: 1; uint32_t f2: 1; uint32_t g2: 1; uint32_t h2: 1; //8bit uint32_t a3: 1; uint32_t b3: 1; uint32_t c3: 1; uint32_t d3: 1; uint32_t e3: 1; uint32_t f3: 1; uint32_t g3: 1; uint32_t h3: 1; //8bit } BB __attribute__((bitband)); BB bb __attribute__((at(0x40010800)));
(0x40010800 is the STM32 GPIOA.CRL register)
When in main I set
bb.a0=1;
which should be bit 0, it compiles to
0x080001BE 4B23 LDR r3,[pc,#140] ; @0x0800024C 0x080001C0 F8C30800 STR r0,[r3,#0x800]
which is off by 0x1C from the correct bitbanding address (which should be 0x42210000) , so instead of setting bit0, it sets bit 7 in GPIOA.CRL
Is my definition of the bitfield wrong or where is the error?
Thank You!
B. Schmidt
But this Keil document shows this exact use togehter with the bitband attribute, I didn't even change the name of the structure ;)
As far as I can see that example doesn't rely on any assumption about how the bits in the bitfield structure map to the bits in the underlying 32 bit value, whereas your code does.
Unless you have a good reason to use bitfields it is usually better, and portable, to stick with shifting and masking.
I guess a "good reason" would be to take advantage of the underlying hardware's ability to directly access individual bits?
That feature can be used without using bitfields too, as long as all bitfields are exactly one bit large.
Then you just create a struct with 32 32-bit large fields and map to the correct address.
The attribute was added to let the compiler mix and/or for multi-bit fields with 32-bit reads/writes for 1-bit fields.