prasad
prasad

Reputation:

How can I reuse physical memory by mapping two variables at the same location?

I am writing code for a serial communication gateway using MSP430F2619 with Code Composer Studio 6.1.

The gateway has two different modes of operation:

The program will be either in master or slave mode as same RS-485 bus is shared between PC application and other slave boards.

Rather than using 2 different memory buffers for each mode, I am trying to figure out whether same physical memory can be used by both buffers.

I tried to search on memory overlay feature of Code Composer Studio without success.


Essentially, I have this:

char Slaverxbuffer[2048];
char Masterrxbuffer[2048];

I want both of these buffers to share the same memory so that I will use 2KB memory instead of 4KB.

So I need a way for Slaverxbuffer and Masterrxbuffer to use the same memory area, something like:

char Sharedbuffer[2048];

Upvotes: 5

Views: 359

Answers (2)

Andrew
Andrew

Reputation:

If, as you say, you don't want a union, you could just have a single buffer, and a separate variable to log which mode you are in?

char rxBuffer[2048];
bool rxMode;  // false = master, true = slave

This way you can have the buffer in a fixed memory location (defined by the linker) and link to the buffer

Upvotes: 4

Niall C.
Niall C.

Reputation: 10918

Could you just have a single buffer and share it between the two modes of operation? That would probably be the simplest solution.

Otherwise, in C and C++, you can accomplish this by having the two buffers be fields in a union type. Each of the members in the union has the same base address in memory, and the overall size of the union is the size of the largest member.

The code would look something like this:

union OverlaidBuffer
{
    char Slaverxbuffer[2048];
    char Masterrxbuffer[2048];
};

union OverLaidBuffer  overlay;

/* Code to use the slave buffer */
for(unsigned int index = 0; index < 2048; ++index)
{
     overlay.Slaverxbuffer[index] = some_slave_value();
}

/* Code to use the master buffer */
for(unsigned int index = 0; index < 2048; ++index)
{
     overlay.Masterrxbuffer[index] = some_master_value();
}

Note that you if you use a union, you should always read from the member that you most recently wrote to. Writing to one member, then reading from another is undefined behavior, and is likely to result in buggy code. For example, the code:

overlay.Slaverxbuffer[i] = 1; 
overlay.Masterrxbuffer[i] = 2; 
x = overlay.Slaverxbuffer[i];

may well set x to 1 since that's “obviously” the last value stored in overlay.Slaverxbuffer[i], even though that memory address now contains the value 2.

Another way to accomplish this is to use compiler and linker directives to place the two buffers at specific locations in memory. Most embedded toolchains will allow you to do this via a #pragma directive in the source code. The exact format of the directive will depend on the particular toolchain; a couple of examples are below.

Then in the linker file, add directives to place the symbol at a specific location:

Upvotes: 10

Related Questions