0

Is there a way of allowing the ARM RealView/Keil linker to select from more than one but not all regions?

I can use the .ANY specifier to allow the linker free reign, and I can use a *(section_name) specifier to locate specific objects to a single region, but I would like to be able to have the linker select from several suitable regions.

To make it clear why this is desirable, I am using an STM32F4xx microcontroller with three distinct but contiguous SRAM regions on separate busses, and a further core-coupled memory region which is not bit-bandable or accessible by DMA. I want to use the smaller SRAM region for DMA to avoid bus contention and improve performance and deterministic behaviour. This region is inconveniently located between two larger regions and I want to be able to use either of the larger regions for bit banding while allowing the CCM memory be used freely for any purpose other than DMA or bit-banding. The regions are currently specified as follows:

  RW_IRAM0 CCM_START CCM_SIZE  
  {
   .ANY (+RW +ZI)
   *(core_coupled_ram)
  }

  ; SRAM1 112Kbytes (Buses: I, D, S, DMA)
  RW_IRAM1 SRAM1_START SRAM1_SIZE  
  {
   .ANY (+RW +ZI)
  }

  ; SRAM2 16Kbytes (Buses: S, DMA)
  RW_IRAM2  SRAM2_START SRAM2_SIZE  
  {
   *(dma_ram)
  }

  ; SRAM3 64Kbytes (Buses: S, DMA)
  RW_IRAM3 SRAM3_START SRAM3_SIZE  
  {
   .ANY (+RW +ZI)
  }

Adding *(bitbandable_ram) to SRAM1 and SRAM3 is rejected by the linker with:

Error: L6223E: Ambiguous selectors found for ctransmissionschedulertask.o(bitbandable_ram) from Exec regions RW_IRAM1 and RW_IRAM3.

Similarly creating an overlapping region does not work:

 ; SRAM 192Kbytes 

  RW_IRAM_ALL SRAM_START (SRAM1_SIZE + SRAM2_SIZE + SRAM3_SIZE)
  {
   .ANY (+RW +ZI)
    *(bitbandable_ram)  
  }

reporting:

Error: L6221E: Execution region RW_IRAM1 with Execution range [0x20000000,0x200045e0) overlaps with Execution region RW_IRAM_ALL with Execution range [0x20000000,0x20018608).

Currently my less-than-ideal solutions are:

  1. to nominate only one region for bit-banding,
  2. to make all the contiguous SRAM a single region (allowing DMA operations may occur in any memory making it less deterministic) thus:

     ; SRAM 192Kbytes 
    
      RW_IRAM_ALL SRAM_START (SRAM1_SIZE + SRAM2_SIZE + SRAM3_SIZE)
      {
       .ANY (+RW +ZI)
        *(bitbandable_ram)  
        *(dma_ram)  
      }
    
  3. Removing the .ANY selector from the CCM region requiring object to be explicitly located there using the core_coupled_ram named section.
Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Agreed, the STM RAM layout is a bit "special". But do you really expect a serious problem with bus contention? Just place stack and static variables in CCM and use the system SRAM as one continous region. – too honest for this site Oct 16 '16 at 22:44
  • @Olaf : I's probably second-guess the requirement too, but the question is valid even if there were no strict need; I have other options of course. It is a signal processing application; two signals from are read at 48ksps each from the ADC using DMA, DMA is also used for SPI and USB. Experience with several STM32 targets has shown that this arrangement is advantageous. There are other hard real-time deadlines requiring determinism of the order of a few tens of microseconds. The CCM space alone is insufficient and there is no one stack - it is an RTOS with 15 or so threads running. – Clifford Oct 17 '16 at 09:58
  • I did not want to imply it is not valid. And without knowing the details, I will not say it is not. Just that: I use these devices with >> than 15 threads, all stacks in CCM, that is not a problem. (there is another advantage with this: the DMA cannot corrupt this space.) Not quite clear, what the problem is though. Typically, due to the restrictions, one wants to manually specify the region. In gcc/gnu-ld one uses custom sections in the source with `_attribute__`. I'm not sure what good it is leaving this to the linker. – too honest for this site Oct 17 '16 at 10:31
  • @Olaf : `__attribute__` (armcc used the GNU syntax) is exactly what I am using - the section names must still be defined in the linker, and it is still the linker that does the locating - `__attribute__(section))` is a linker directive. What I really need is an attribute that says *"locate this object in any region with the specified label"*, and then in the scatter file assign labels to specific regions. A section name can be applied to only one region. – Clifford Oct 17 '16 at 17:22
  • Hmm, I might be wrong, but I have a faint memory GNU-ld at least (I don't know the Keil Tools) has an option to mention an input-section in multiple output-section. The linker will place it then into the first it fits into. As said, I'm not sure I remember correctly, but maybe it's worth a try. An alternative could be to generate the control file from a small program, e.g. Python. – too honest for this site Oct 17 '16 at 17:29

0 Answers0