Overlaying RAM code segments in IAR products with XLINK

Technical Note 62554

Architectures:

All

Component:

linker

Updated:

5/31/2018 9:14 AM

Introduction

This text will describe how use the same RAM to run different code at different times, by copying ROM-content from several different segments to the same addresses in RAM.

See Technical Note 80460 about the basics about copying content from ROM to RAM.

Applies to

This Technical Note applies to versions that uses IAR XLINK Linker.

Basics

The following steps must be taken to overlay several code segments in RAM:

  1. Place each such "load unit" in its own segment.
  2. Use the -Q linker option on each such segment to create initializer segments.
  3. Overlay the original segments in RAM.
  4. Place the initializer segments in ROM.
  5. Copy the bytes from each initializer segment to its segment before use.
  6. Make sure that no overlaid segment refers to another overlaid segment.

1. Placing contents in segments

See Technical Note 80460.

Note that "built in" keywords (like __ramfunc) typically do not work when you want to place content in two (or more) different segments. You probably have to use the #pragma approach.

2. Create the initializer segments

See Technical Note 80460.

-QRAMCODE1=RAMCODE1_ID
-QRAMCODE2=RAMCODE2_ID

3. Overlaying segments in RAM

IAR XLINK Linker has a placement modifier for the -Z segment placement command, @, that ignores previously placed content in the placement range.

-Z@(DATA)CODE_A,CONST_A,DATA_A=RAM_OVERLAY_START-RAM_OVERLAY_END

The -Z@ command obeys all the normal rules for -Z, it just ignores any previously placed content in the range. The segments will be placed in the specified order starting on the address RAM_OVERLAY_START.

Then place the next overlay on the same address:

-Z@(DATA)CODE_B,CONST_B,DATA_B=RAM_OVERLAY_START-RAM_OVERLAY_END

This will place the specified *_B-segments on the same addresses that the *_A segments used. This creates an intentional overlap where multiple RAM-segments have the same addresses.

IAR XLINK Linker will detect the segment overlaps and generate errors for them. The overlap error can be turned off, or changed into a warning. The problem is that turning the error off will result in real overlaps being ignored as well. Changing the error into a warning will result in several warnings every time the program is linked. There is a linker option --disable_overlap_check that allows you to selectively turn the overlap error off for specified segments overlaying.

Use ...

--disable_overlap_check=CODE_A,CONST_A,DATA_A,CODE_B,CONST_B,DATA_B

... to turn off the segment overlap error for the involved segments. This turns the overlap error off for the involved segments, but only if it overlaps another of the involved segments. Overlaps between CODE_A and some other segment (that might, or might not, be listed in another --disable_overlap_check option) will still be reported.

4. Place the initializer segments in ROM.

See Technical Note 80460.

-Z(CONST)CODE_A_ID,CONST_A_ID=ROMSTART-ROMEND
-Z(CONST)CODE_B_ID,CONST_B_ID=ROMSTART-ROMEND

5. Copy the bytes from the initializer segment to the segment

See Technical Note 80460.

6. Check overlaid segment references

The case with overlaid RAMCODE segments is quite a bit more complex than the case of a single RAMCODE segment. These are the most important aspects:

  • The overlaid segments can never be used at the same time and references to each segment can only be made when the segment is "active". This is entirely up to the user to enforce. There is no support for detecting these in the compiler or the linker. References to the segment when it is not active results in undefined behavior.
  • One overlaid segment can never refer to content in another segment with which it is overlaid as they are never active at the same time. Neither the compiler, nor the linker is currently able to detect such a reference. It is not impossible to create overlay situations where two RAMCODE segments can be active at the same time (e.g., one on the addresses 0x2000-0x23FF and another on 0x2400-2FFF while other segments use 0x2000-0x2FFF -- in this case the two are not overlaying each other) but all such tricks are up to the programmer to handle.
  • Debug information for the RAM-area will not be of the usual quality as the portion of RAM will be saturated with debug information (one set of debug information for every segment overlaid on the same addresses) and a debugger will probably be quite confused and might be unable to even present the correct function. The code will work as expected but it might not be easy to debug on any level except assembly.
  • If the code is organized so that each "load unit" resides in a separate file it is possible to compile the module without debug information. If only the module containing the load unit that you want to debug contains debug information the debugger should be able to do a better job.
  • If you have enough RAM space it can be an option to place the load unit you want to debug in its own memory space. It will then get the normal debug information.

 

All product names are trademarks or registered trademarks of their respective owners.

We do no longer support Internet Explorer. To get the best experience of iar.com, we recommend upgrading to a modern browser such as Chrome or Edge.