SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Mapping External RAM Correctly with Scatter Load Files on ARM Cortex-M
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

Mapping External RAM Correctly with Scatter Load Files on ARM Cortex-M

Javier Massey
Last updated: September 21, 2023 1:41 pm
Javier Massey 7 Min Read
Share
SHARE

When working with external RAM on an ARM Cortex-M chip, it is crucial to map the external memory regions correctly using scatter load files. Scatter files provide a flexible and convenient way to define the memory layout for your Cortex-M application, allowing you to specify where code and data sections should be placed in physical memory. Using scatter files improperly can result in hard-to-debug memory issues, so understanding the syntax and usage is important.

Contents
Overview of External RAM on Cortex-MUsing Scatter Files to Define External RAM LayoutPlacing Code and Data in External RAMAvoiding Memory Overlaps and FragmentationAdding External RAM Access Rules with MPUAdding Wait States for Reliable OperationVerifying Successful External RAM AccessKey Takeaways

Overview of External RAM on Cortex-M

The Cortex-Mfamily of ARM processors are designed for embedded applications with tight memory constraints. However, many advanced applications require more RAM capacity than available on-chip. External RAM integrated circuits can be added to provide this extra memory, communicating with the Cortex-M chip via an external bus interface like AHB or AXI.

To utilize external RAM, the memory must be configured correctly via the Memory Protection Unit (MPU). The MPU allows setting access permissions for memory regions, splitting external RAM into multiple blocks if needed. Special care must be taken with timing, bus waits states, and bus arbitration to ensure reliable operation.

Using Scatter Files to Define External RAM Layout

Scatter files provide a flexible method for defining how code and data sections should be arranged in physical memory. The linker will allocate sections into memory regions according to the scatter file when generating the final executable binary.

For external RAM, the scatter file must define one or more regions that cover the full external address space provided. As an example: LR_IROM1 0x00000000 0x00080000 { ; load region size_region ER_IROM1 0x00000000 0x00080000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } ; External RAM region LR_ExtRAM 0x20000000 0x00200000 { ER_ExtRAM 0x20000000 0x00200000 { .ANY (+RW +ZI) } } }

This defines a 512KB external RAM region from 0x20000000 to 0x20020000. The .ANY directive will place all RW and ZI sections within this memory.

Placing Code and Data in External RAM

By default, the linker will try to place all code and data into internal memory first. To move specific sections into external RAM, you must use directives.

For example, to move the .text section to external RAM: SECTIONS { .text : { *(.text) } > ER_ExtRAM }

And to move the .bss section: SECTIONS { .bss : { *(.bss) } > ER_ExtRAM }

For placing larger data arrays, the linker also supports putting variables at specific addresses using the AT attribute: int large_array[8192] __attribute__((at(0x20020000)));

This syntax lets you manually place data within the external RAM region as needed.

Avoiding Memory Overlaps and Fragmentation

When defining your external RAM regions in the scatter file, it is critical to get the addresses and sizes correct to avoid overlaps or fragmentation.

Overlapping regions will lead to hard-to-debug memory corruption issues. The linker also requires regions to be defined sequentially with no gaps in between. Otherwise, the unused fragmented memory cannot be utilized.

Make sure your external RAM chip’s datasheet precisely matches the start address and capacity specified in the scatter file. Double check that multiple RAM regions don’t accidentally overlap.

Also beware of fragmentation. For example, defining two 256KB external RAM regions from 0x20000000-0x200FFFFF and 0x20400000-0x20500000 would lose access to the unused 128KB gap, wasting memory.

Adding External RAM Access Rules with MPU

In addition to the scatter file, the MPU configuration must allow access to external RAM address ranges. The MPU allows setting read/write/execute permissions for each defined region.

As an example, enabling read-write access to the 0x20000000-0x2002FFFF external RAM range: MPU->RBAR = 0x20000000; MPU->RASR = 0x00000003; //full access

Failing to configure the MPU properly will lead to hard faults when the Cortex-M processor tries to access external memory. Setting the correct boundaries and access permissions is vital.

Adding Wait States for Reliable Operation

External RAM chips often operate at slower speeds than the processor’s bus interface. Wait states must be inserted to avoid outrunning the external RAM access times and causing incorrect behavior.

For example, adding 2 wait states to an FMC external memory controller peripheral: FMC_Bank->BTCR[0] = 2 //insert 2 wait states

The required number of wait states depends on the RAM chip’s datasheet and the Cortex-M processor’s bus speed. Too few wait states will lead to unreliability.

Verifying Successful External RAM Access

After defining the scatter file and MPU regions, test carefully to validate correct external RAM access. Simple test code can write values and read them back to check for consistency.

Memory scope tools and debuggers that can access external memory areas are also invaluable for more robust testing. Watch memory locations to verify writes are updating properly. Check that different data arrays do not overlap or interfere.

Going through methodical external RAM validation will help identify any bugs in the memory configuration early, saving lots of debug time down the road.

Key Takeaways

Here are some key tips for correctly utilizing external RAM on an ARM Cortex-M processor:

  • Use scatter files to define external memory regions and place code/data
  • Avoid overlaps between regions to prevent memory corruption
  • Configure MPU to enable read/write access to external RAM
  • Add sufficient wait states for reliable external RAM access
  • Verify successful operation by testing reads and writes

Following these steps carefully when integrating external RAM will help avoid confusing memory errors and save much debugging effort. External memory opens up many possibilities for on-chip RAM limited Cortex-M devices. Using the right configuration approach makes utilizing large external memories simple and effective.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Scatter Load File Best Practices for ARM Cortex-M Applications
Next Article Changing Interrupt Priority on Cortex-M Microcontrollers
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

Arm Sleep Mode Entry and Exit Differences: WFE vs WFI

The ARM Cortex architecture provides two instructions for entering sleep…

6 Min Read

What is the Difference Between UART and I2C?

UART (Universal Asynchronous Receiver/Transmitter) and I2C (Inter-Integrated Circuit) are two…

7 Min Read

How many registers does ARM Cortex-M have?

The ARM Cortex-M processors are a series of 32-bit microcontroller…

7 Min Read

Arm Cortex-M DAP bus and interconnect architecture Explained

The Arm Cortex-M series of processors feature a Debug Access…

11 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account