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

__attribute__((bitband)) address miscalculation?

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))