如何通过在同一位置映射两个变量来重用物理内存?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过在同一位置映射两个变量来重用物理内存?相关的知识,希望对你有一定的参考价值。
我正在使用MSP430F2619和Code Composer Studio 6.1为串行通信网关编写代码。
网关有两种不同的操作模式:
- 掌握这是默认模式。它将数据轮询为RS485总线上的总线主控器,然后将其发送到具有不同协议的另一个板。
- 从站响应串口上的PC应用程序的从站。
程序将处于主模式或从模式,因为PC应用程序和其他从属板之间共享相同的RS-485总线。
我试图弄清楚两个缓冲区是否可以使用相同的物理内存,而不是为每种模式使用2个不同的内存缓冲区。
我试图搜索Code Composer Studio的内存覆盖功能但没有成功。
基本上,我有这个:
char Slaverxbuffer[2048];
char Masterrxbuffer[2048];
我希望这两个缓冲区共享相同的内存,以便使用2KB内存而不是4KB内存。
所以我需要一种方法让Slaverxbuffer
和Masterrxbuffer
使用相同的内存区域,例如:
char Sharedbuffer[2048];
您可以只使用一个缓冲区并在两种操作模式之间共享吗?这可能是最简单的解决方案。
否则,在C和C ++中,您可以通过将两个缓冲区设置为union类型的字段来实现此目的。联合中的每个成员在内存中具有相同的基址,并且联合的总大小是最大成员的大小。
代码看起来像这样:
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();
}
请注意,如果您使用联合,则应始终从最近写入的成员中读取。写一个成员,然后从另一个成员读取是undefined behavior,并可能导致错误的代码。例如,代码:
overlay.Slaverxbuffer[i] = 1;
overlay.Masterrxbuffer[i] = 2;
x = overlay.Slaverxbuffer[i];
可能会将x
设置为1,因为它“显然”是存储在overlay.Slaverxbuffer[i]
中的最后一个值,即使该内存地址现在包含值2。
另一种实现此目的的方法是使用编译器和链接器指令将两个缓冲区放在内存中的特定位置。大多数嵌入式工具链允许您通过源代码中的#pragma
指令执行此操作。指令的确切格式取决于特定的工具链;下面是几个例子。
- TI Code Composer Studio(参考MSP430 Optimizing C/C++ Compiler User's Guide)
#pragma DATA_SECTION(Slaverxbuffer, "some_section") char Slaverxbuffer[2048];
- IAR Embedded Workbench(参考IAR C/C++ Development Guide)
#pragma section = "some_section" char Slaverxbuffer[2048];
然后在链接器文件中添加指令以将符号放在特定位置:
- TI Code Composer Studio(参考MSP430 Assembly Language Tools User's Guide)
SECTIONS { .some_section : load = 0x12345678 }
- IAR Embedded Workbench(参考IAR C/C++ Development Guide)
place at address mem:0x12345678 { readwrite section some_section };
如果,如你所说,你不想要一个联合,你可以只有一个缓冲区和一个单独的变量来记录你所处的模式?
char rxBuffer[2048];
bool rxMode; // false = master, true = slave
这样,您可以将缓冲区放在固定的内存位置(由链接器定义)并链接到缓冲区
以上是关于如何通过在同一位置映射两个变量来重用物理内存?的主要内容,如果未能解决你的问题,请参考以下文章