This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

bit-banding

Hi all,

I'm rather new to Tiva and am now learning bit-banding.  I've read the other posts about it on this site and find it a bit confusing.  Instead I've written the following code that I modified from Josehp Yiu's book.  The only modification is the addressing from the peripheral alias bank to the SRAM alias bank.

#define DEVICE_REG0_BIT0    *((volatile unsigned long*) (0x22000000))   //Alias to bit 0 of SRAM byte 0x20000000

#define DEVICE_REG0_BIT1    *((volatile unsigned long*) (0x22000004))   //Alias to bit 1 of SRAM byte 0x20000000

... and so on ...

Then in our code...

DEVICE_REG0_BIT1 = 0x1;  //Setting bit 1 in SRAM location 0x20000000

What I don't understand is how do I allocate memory in SRAM so the compiler does not allocated 0x20000000 for something else.  Also, just wondering what the exports think about this method in general.

Thanks George

  • Hello George,

    From the compiler perspective, the SRAM will exist at location 0x20000000 and that is what should be used in the linker command file.

    On the second question of bit-banding (if that is what you meant), it is an effective method of modifying a bit without doing a read modify write operation, saving CPU code cycles.

    Regards

    Amit

  • Hi Amit,

    Thanks for taking the time to help me.  I think my problem is that I'm not up on linking and memory allocation yet.  I want to use a word of SRAM for my programs needs, like ISR flags (the ISR got some data that needs to be processed by the main routine.)  My question is how do I allocate a 32bit word in SRAM to use for bit-banding?  I need to know where that word is because I need to know what alias to use to flip the bits in that word.  I don't want to step on the linker, because it allocates SRAM for ISR vectors etc.  And I want the linker to know not to use the word I intend to use for bit-banding.

    Thanks George

  • Hello George,

    The simplest way is in the linker command file to reduce the size of the SRAM (towards the end or start) and use the region for bit banded SRAM. The ISR vectors can be kept in Flash and there is no need to reduce precious SRAM for the same. To do so, mention the IST functions in the startup file.

    Regards

    Amit

  • Amit Ashara said:

    On the second question of bit-banding (if that is what you meant), it is an effective method of modifying a bit without doing a read modify write operation, saving CPU code cycles.

    More importantly it's an atomic operation.

    Robert

  • @George,

    It very important to keep the startup file as provided - this is because otherwise you will never know if and when your microcontroller goes into FaultISR and you will not be ever able to inspect by yourself some nasty bugs unintentionally produced.

    As for your variables - can you explain more? seems to me that you want to move a GPIO register to RAM, make there modifications, bit-banded, and move back to register. If this is the case, then is unusual, bad practice, since not always you can do bit-banding, but only read-modify-write which is automatically managed by the compiler if you write your program in C.

    It is good you read Yiu, but , at this stage, it is useful also to read the compiler and assembler manual with a focus on "sections".

    Petrei

  • You might not be seeing the forest for the trees...

    Need to know where a variable is in memory? Take a pointer to it.

    uint32_t myWord;
    uint32_t* myWordLocation = &myWord;

    Then just use myWordLocation for the bit-band address calculations.

  • Hello all,

    Thanks to all of you for taking the time to help me!

     

    I've read all replies and have done additional reading on my own (and will continue to do so), and I think I'm starting to understand this better.  Here is how I see it for clarification and for the benefit of other readers.

     

    Bit-banding is a good thing because you can set or clear a bit in memory “atomically”.  That is, it can not be interrupted by and interrupt.  There could be unexpected results if this process was interrupted by an ISR.

     

    As I see it there are two ways to do bit-banding.  One is from the Yiu book, which I mentioned in my first post.  The other is by using the macro HWREGBITW.

     

    If I’m not mistaken, they work like this…

    The coding for the method from the Yiu book seems easer to me, but requires that the RAM word to be modified is fixed and know at compile time.  This is fine is you want to access peripheral control words, but if you want to access SRAM, you have to do some tricky things to tell the linker to not use the SRAM words you are using for bit-banding.

     

    Looks to me that HWREGBITW uses more and ‘clever’ code, but it takes the address of the word to be modified as an argument, so you can declare that word just like any other variable.  So the compiler decides where that word is…not you.  But that means you don’t need to mess with link/setup files.  This method is better for application usage.  You can set up a word in SRAM for your application’s flags.  You can have 32 flags to indicate if an interrupt has just been completed, the denounced status of a switch, etc. 

     

    Did I miss something?  Is this the consensus from the other posters?

     

    Thanks George

     

  • Maybe I'm the one missing something, but I still think you're taking an overly complicated approach to this.

    I don't understand why *you* would need to decide/know where the word to be used for bit-banding is located. The compiler knows that, as it is the one that decides that. The HWREGBITW macro might look complicated, but the compiler does  all the calculations at compile time if your parameters are constant, as is the case with a statically allocated variable.

    And really, the only place where you 'reserve' one word for bit-banding is in your head :-)  The whole SRAM address space is available for bit-banding. You can flip the sign bit of a signed integer or float using bit-banding, for example.

  • As I mentioned, I'm new to ARM and Cortex M3/4 and am well into the learning cycle.  This atomic bit-banding thing is new to me and it took me some time to get my head wrapped around it.  I was confused why there are two completely different ways to do the same thing, but now I get it.  I can only assume that there are others who are also trying to understand this, and I wanted to write a post to describe the two methods in a clear way. 

  • Okay, makes sense now! Nice to hear you're "getting it".

    While you're at it, take a look at the GPIOPinWrite & co. internals as well, there's another bit-banding scheme used there. Instead of providing unique word addresses for every GPIO pin, there are actually unique addresses for each possible pin *combination* - 256 addresses for each 8-bit port, that is!

    You can still use regular bit-banding with GPIO ports too, you just should use the "full access" address of the GPIO port to base your bit-band calculations on.

  • Depending on compiler you will have some options . I know the KEIL superficially and could do what you asked as follows :
    
    unsigned char flags __attribute __ ( (at ( 0x20000000 ) ) );
    
     This sets the variable flag at address 0x20000000 , use the address you want
    Other compilers should have similar directives.

    After that you could use your own code

    "
    #define DEVICE_REG0_BIT0    *((volatile unsigned long*) (0x22000000))   //Alias to bit 0 of SRAM byte 0x20000000

    #define DEVICE_REG0_BIT1    *((volatile unsigned long*) (0x22000004))   //Alias to bit 1 of SRAM byte 0x20000000...

    ... and so on ...
    "

    Simão