ARM Technical Support Knowledge Articles


Applies to: C51 C Compiler


Information in this article applies to:


I am working on a project that has 32K of RAM and 32K of NV (non-volatile) RAM. How should I design my target to use both types of RAM?


There are many ways to do this effectively. The end results are typically the same: SRAM is used for run-time variables and NVRAM is used for configuration or calibration or historical data.

One way to implement your target is to design the hardware so that the SRAM is located from 0x0000-0x7FFF in the XDATA space and the NVRAM is located from 0x8000 to 0xFFFF in the XDATA space.

Configuring and Using the SRAM...

In the startup code (STARTUP.A51) you should change the XDATA length to 0x8000. This clears only the first 32K of XDATA (which is the SRAM). For example:

;  User-defined Power-On Initialization of Memory
;  With the following EQU statements the initialization of memory
;  at processor reset can be defined:
;               ; the absolute start-address of IDATA memory is always 0
IDATALEN        EQU     80H     ; the length of IDATA memory in bytes.
XDATASTART      EQU     0H      ; the absolute start-address of XDATA memory
XDATALEN        EQU     08000H  ; the length of XDATA memory in bytes.
PDATASTART      EQU     0H      ; the absolute start-address of PDATA memory
PDATALEN        EQU     0H      ; the length of PDATA memory in bytes.

If you use the linker from the command line, you should specify that the XDATA space is limited to 0x0000-0x8000. For example:

BL51 ... XDATA(0x0000-0x7FFF)

In the uVision2 IDE, you may simply specify that the RAM starts at 0x0000 and is 0x8000 bytes in length.

Any variables you locate in XDATA will be placed in the SRAM.

Configuring the NVRAM...

The NVRAM will reside in the XDATA space from 0x8000-0xFFFF. Depending on your use for the NVRAM, there are several ways you can allocate variables there.

One way is to use the XBYTE macro from the ABSACC.H header file to explicitly access this area as an array. For example,

XBYTE[0x8000] = 'A';   // Write an 'A' into NVRAM
var = XBYTE[0x8000];   // Read the 'A' from NVRAM

Another way to access the NVRAM is to create a file that holds all of your NVRAM variables. Declare these as XDATA variables. Then, locate the ?XD?filename segment starting at 0x8000 (using the linker). Whenever you access these variables, the NVRAM will be used.

A final way to access this memory is to declare XDATA variables AT and address. For example:

unsigned char xdata variable _at_ 0x8000;

All of these methods work similarly well.

There is one more thing to consider if you use the NVRAM as storage for configuration/calibration data and historical data. You should create a structure for your calibration data and /or a structure for your historical data. For example:

struct cal_data_st
  int cal_a;
  int cal_b;
  int cal_c;
  unsigned char checksum;

Then, locate a copy of the struct (or an array of the struct for historical data) in the NVRAM. For example:

struct cal_data_st xdata cal_data _at_ 0x8000;

// or

struct hist_data_st xdata hist_data [100] _at_ 0x8100;

Then, when your program starts, verify the checksum of the calibration data to be sure it is valid.


Article last edited on: 2007-01-19 08:37:03

Rate this article

Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential