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
>> However, the exact bit field layout is defined by the ARM ABI. > > And you're sure that covers even bit-banded ones? I'm certainly no ARM > expert, but this sounds to me like this might be a feature that, > originating in a second-party implementation of the ARM core, might > not be covered by the ARM ABI document.
Bit-banding, although not architecturally defined, is a feature of the Cortex-M3 macrocell and certainly not a second-party implementation.
Ensuring proper (ABI compliant) mapping of bit-fields to bit-banding access is the task of the compiler, if it wants to provide syntactic sugar like this attribute.
> Not even to mention it was added a good deal later than the ABI was > first written.
Normally there is a better chance for something to be implemented properly after the specification has been written.
Best regards Marcus http://www.doulos.com/arm
I've have had success using the macros in the link below for bit band access. Probably not as "clean" as bit fields in a structure, but it is portable and saves you from having to calculate out that address by hand.
infocenter.arm.com/.../index.jsp
I just ran across some Macros from Luminary for bit-band access that are slightly different from the ARM ones.
//***************************************************************************** // // Macros for hardware access, both direct and via the bit-band region. // //***************************************************************************** #define HWREG(x) \ (*((volatile unsigned long *)(x))) #define HWREGH(x) \ (*((volatile unsigned short *)(x))) #define HWREGB(x) \ (*((volatile unsigned char *)(x))) #define HWREGBITW(x, b) \ HWREG(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \ (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2)) #define HWREGBITH(x, b) \ HWREGH(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \ (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2)) #define HWREGBITB(x, b) \ HWREGB(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \ (((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2))