何时使用xdata?

10

我是嵌入式系统编程的新手。我正在开发一个使用8051芯片组的设备。在示例程序中,我注意到有时在定义变量时会使用关键字xdata。像这样...

static unsigned char xdata PatternSize;

而其他时候则省略了xdata关键字。

我的理解是,xdata关键字指示编译器将该变量存储在外部闪存内存中。

在什么情况下应该使用xdata将变量存储在外部?访问这些变量需要更长的时间,对吗?使用xdata存储的值在设备硬重置后还会存在吗?

同时,我知道static关键字表示变量将在每次调用它所定义的函数时保持不变。static和xdata必须一起使用吗?

5个回答

9
8051架构有三个独立的地址空间,核心RAM使用8位地址,因此最大可达256字节,XDATA是一个16位地址空间(64K字节),具有读/写功能,程序空间是一个16位地址空间,具有执行和只读数据功能。由于其小的地址范围和与核心的紧密耦合,所以在代码空间和访问周期方面,寻址核心RAM更加高效。
最初的8051核心具有微小的芯片内RAM(256字节的地址空间,但某些变体实际上只有一半的内存),而XDATA指的是芯片外部的数据存储器(与程序存储器相对)。然而,现代的大多数8051架构设备都有芯片内部的XDATA和程序存储器。
因此,在性能至关重要时,您可能会使用核心内存,并使用XDATA来处理更大的内存对象。但是,在大多数情况下,编译器应该为您做出这个决定(请查看您的编译器手册,它将详细描述内存分配方式)。该指令集使得在核心内存中实现栈非常有效,而静态和动态分配的数据通常应该分配给XDATA。如果编译器有XDATA关键字,则它将覆盖编译器的策略,并且只应在编译器的策略出现问题时使用,因为它将降低代码的可移植性。
[编辑]还要注意,核心内存包括一个32字节的位寻址区域,位寻址指令使用8位地址进入该区域直接访问单个位。该区域存在于256字节的可寻址核心内存中,因此既支持比特又支持字节寻址[/编辑]

6

xdata告诉编译器数据存储在外部RAM中,因此必须使用不同的指令来读写该内存,而不是内部RAM。

访问外部数据需要更长的时间。我通常将中断变量放在内部RAM中,将大多数大型数组放在外部RAM中。

关于硬复位(而非电源循环)后外部RAM的状态:这取决于硬件设置。复位线是否连接到外部芯片?此外,一些芯片带有8051 CPU以及一定数量的XDATA。再读一遍。某些芯片具有8051 CPU和一定数量的IC内部XDATA。

静态和xdata不重叠。静态告诉编译器如何分配变量(在堆栈或内存位置)。Xdata告诉编译器如何访问该变量。静态还可以将该变量的命名空间限制为仅该文件。您可以拥有一个局部函数的xdata静态变量,并拥有一个局部函数的静态变量,但使用内部RAM。


3
重要的一点尚未提及,因为不同的指令用于访问不同的内存区域,硬件没有统一的“指针”概念。在已知位于DATA/IDATA空间的任何地址可以使用一个字节的指针唯一标识;同样,在已知位于PDATA空间的任何地址也可以使用一个字节的指针唯一标识。在已知位于CODE空间的任何地址可以使用两个字节的指针标识;同样,在已知位于XDATA空间的任何地址也可以使用两个字节的指针标识。然而,在许多情况下,像memcpy这样的程序事先不知道应该使用传入的指针访问哪个内存空间。为了适应这种情况,8x51编译器通常使用三个字节的指针类型,可以用来访问任何内存空间(一个字节选择应该与指针一起使用的指令类型,其他字节保存值)。例如指针声明:
char *ptr;

这将定义一个可以指向任何内存空间的三字节指针。将声明更改为:

char xdata *data ptr;

将定义一个存储在DATA空间中的两字节指针,但它只能指向XDATA空间中的内容。同样地,

char data * data ptr;

将定义一个存储在数据空间中的两字节指针,但该指针只能指向数据和IDATA空间中的内容。使用指向已知数据空间的指针的代码将比使用“通用”三字节指针的代码快得多(可能快十倍)。


1

如何以及何时使用xData存储区取决于系统架构。一些系统可能在此地址处拥有RAM,而其他系统可能具有ROM或Flash。在任何情况下,访问速度都比访问内部RAM、ROM或Flash慢。

一般来说,大型项目、常量项目和较少使用的项目应该放入xData中。没有标准规则可以确定什么应该放入xData,因为这取决于架构。


严格来说,xdata仅改变了代码生成,以发出命中16位数据空间的指令。编译器并不关心它是RAM、ROM还是(NOR)闪存;显然,不同的设备可以具有混合地址空间,但它们都是“xdata”内存。 - Andy Ross

1

8051拥有128字节的临时存储区域,被称为“伪寄存器”,大多数编译器会将其用作声明变量的默认位置。但显然,这个区域非常小,您还需要能够将变量放入16位内存地址空间中。这就是xdata(即“外部数据”)说明符的作用。当然,要放置哪些数据取决于数据本身以及您计划如何使用它。

基本上,我认为这是错误的问题。在学习如何使用C编译器的8051特定功能之前,您需要先了解您的CPU架构。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接