cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32L4] Bit banding

sunny
Associate II
Posted on June 15, 2016 at 10:27

Hi,

I want to use the Bit Banding region of STM32L4 but I do not know how to modify the linker script for the same.

I tried to follow the https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FC%20compilers%20and%20bit%20banding&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=459

and the ARM Infocenter mentioning the C-Code to access the Bit-Banding region starting at 0x20000000 but since I have not seperated the bit-banding region in linker script, the 0x20000000 location gets over written by the code.

Can somebody please help me out for the same ?

Also, if we use the Bit-band region e.g. 4 bytes of the SRAM bit-band region which translates to 128 (32*4) bytes of bit aliased region, then do I have to leave 128 bytes of SRAM memory in the linker file ?

Below is my linker script:

; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region

  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address

   *.o (RESET, +First)

   *(InRoot$$Sections)

   .ANY (+RO)

  }

  RW_IRAM1 0x20000000 0x00018000  {  ; RW data

  *.o (RESET_ram, +First)

   .ANY (+RW +ZI)

  }

  RW_IRAM2 0x10000000 0x00008000  {

   .ANY (+RW +ZI)

  }

}

Thanks,

Sunny

#stm32l4 #bit-band
11 REPLIES 11
mark239955_stm1
Associate II
Posted on June 15, 2016 at 11:14

How are you accessing the bit band region?

I ask because when I've used bitbanding in the past (in an F405), I just created a pointer to a uint32 and assigned a value to it that points into a bitband region.  I had no linker issues whatsoever.

sunny
Associate II
Posted on June 15, 2016 at 12:11

Hi Mark,

Thank you for the reply.

I understand how you used the bit band region.

But my query is that how will the Keil Compiler / Linker know that it should not use the particular SRAM location which I have assigned to a particular variable.

Example:

I assign uint32_t *pBitBandVar1 = (uint32_t *)0x20000000, then how will the compiler / linker know that it should not access the 0x20000000 SRAM location for any of the compiler code ?

Thanks,

Sunny

mark239955_stm1
Associate II
Posted on June 16, 2016 at 04:48

In the context of the F405/7 and using Coocox+GCC (I don't have Keil installed so I can't doublecheck with it, but it should be identical), the linker doesn't need to be aware of the bitband alias region because there is no physical RAM located there.

So, for example, if the address that I wanted to access with bitbanding is 0x20000000, the bitband alias address for the LSB of 0x20000000 is 0x22000000; LSB+1 is 0x22000004; LSB+2 is 0x22000008; etc.  The linker knows about 0x20000000 because that is physical RAM that can contain code or data, but it doesn't know about 0x22000000 because that is a bitband alias for the physical RAM.

Preventing the compiler from using a particular section of physical RAM, e.g. 0x20000000, because you have a specific non-mobile purpose for it, is a different matter.

Posted on June 16, 2016 at 05:03

The Linker is not going to be able to rationalize dual use of a variable/memory location. If you want a bit-banded section, you'll need to shrink the normal IRAM size, and create the bit band region that describes the area you've freed up

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
sunny
Associate II
Posted on June 16, 2016 at 06:03

Hi Clive,

Thank you for the reply.

Now I understand that we need to create a bit-band region in the Linker Script so that the other code/data will not be used from the bit-band region.

But can you please help me out to create a sample section for bit-band in the Linker Script, as I am not aware of how to do that.

From the above linker script, if I want to use the SRAM bit-band region starting from 0x20000000 and upto total of 4 bytes i.e. upto 0x20000003, then if can is the below Linker Script correct for STM32L4 having 1MB of Flash ?

Below is my linker script:

; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region

  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address

   *.o (RESET, +First)

   *(InRoot$$Sections)

   .ANY (+RO)

  }

  RW_SRAM_BB 0x20000000 0x04  {  ; RW data

   ._srambb 

  }

  RW_IRAM1 0x20000004 0x00018000  {  ; RW data

  *.o (RESET_ram, +First)

   .ANY (+RW +ZI)

  }

  RW_IRAM2 0x10000000 0x00008000  {

   .ANY (+RW +ZI)

  }

}

And to place a variable in this section, I can do the below:

unsigned volatile long __attribute__ ((section(''.srambb''))) bitBandVar1;

Awaiting your reply.

Thanks,

Sunny

mark239955_stm1
Associate II
Posted on June 16, 2016 at 06:57

I'm no expert with linker scripting, but I would have thought that

 RW_IRAM1 0x20000004 0x00018000  {  ; RW data

  *.o (RESET_ram, +First)

   .ANY (+RW +ZI)

  }

should be

 RW_IRAM1 0x20000004 0x00017ffc  {  ; RW data

  *.o (RESET_ram, +First)

   .ANY (+RW +ZI)

  }

Otherwise, sure, it looks reasonable.

I'd even argue that you can not modify the original linker script and just force the location of your variable using

__attribute__((section(''RW_IRAM1'')))

because in practice it doesn't matter where in the IRAM1 space the linker places the variable that you want to access with bitbanding, you just need to be sure that it places it somewhere that you can access with bitbanding.

sunny
Associate II
Posted on June 16, 2016 at 07:11

Hi Mark,

Thank you for the reply.

I tried with your change as well. But with your change and with my posted linker script, I am getting the below error:

.\bitband.sct(8): error: L6236E: No section matches selector - no section to be FIRST/LAST.

which is pointing to the 

  *.o (RESET_ram, +First)

line of the RW_IRAM1 section.

It would be great if I can get pointers to resolve this.

Thanks,

Sunny

Posted on June 16, 2016 at 11:10

Surely you're trying to describe the *alternate* memory space at 0x22000000 where each 32-bit word describes a single bit in *normal* memory. ie 0x22000004 describes bit 1 at 0x20000000

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00100000 { ; load region size_region
ER_IROM1 0x08000000 0x00100000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_SRAM_BB 0x22000000 0x80 { ; RW data 4 * 4 * 8, each byte as 8x 32-bit words

._srambb 
}
RW_IRAM1 0x20000004 0x00017FFC { ; RW data advance and shrink
*.o (RESET_ram, +First)
.ANY (+RW +ZI)
}
RW_IRAM2 0x10000000 0x00008000 {
.ANY (+RW +ZI)
}
}

unsigned volatile long __attribute__ ((section(''.srambb''))) bitBandVar1; // Holds 0x00000000 or 0xFFFFFFFF ONLY

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
sunny
Associate II
Posted on June 16, 2016 at 12:38

Hi Clive,

Thanks for the reply.

I am able to compile to code.

But as you suggested to use the 

unsigned volatile long __attribute__ ((section(''._srambb''))) bitBandVar1;

I am seeing the address of bitBandVar1 as below in the .map file:

    bitBandVar1                              0x20000004   Data           4  main.o(._srambb)

I thought that the address assigned to this variable would be 0x20000000 or 0x22000000.

Is it correct ?

Also during linking, the linker is giving the below warning:

.\bitband.sct(12): warning: L6314W: No section matches pattern ._srambb(RW).

Thanks,

Sunny