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
As long as you have volatile-declared your variables, you should be able to have a pointer to the "raw" address of the register, allowing you to do direct 16-bit or 32-bit updates. This will not affect the linkers ability to place variables at absolute addresses.
Another alternative is to manuall set an unsigned variable "at" the register address, and a struct/array of 32-bit unsigned integers "at" the alias address for bit-addressing. Remember that the bit-banding does its magic by having the bitbanded variables aliased to two different addresses. The bitband attribute is a bit of black magic added by the compiler to try and automagically hide this aliasing.