什么时候使用 xdata?
我是嵌入式系统编程的新手。我正在开发使用 8051 芯片组的设备。我在示例程序中注意到,在定义变量时,有时会使用关键字 xdata。像这样...
static unsigned char xdata PatternSize;
而其他时候 xdata 关键字被省略。
我的理解是 xdata 关键字指示编译器将该变量存储在外部闪存中。
在什么情况下我应该使用 xdata 在外部存储变量?访问这些变量需要更长的时间,对吗?使用 xdata 存储的值在设备硬重置后不会保留,不是吗?
另外,我知道 static 关键字意味着该变量将在每次调用它所定义的函数时持续存在。static 和 xdata 是否必须一起使用?
I am new at embedded system programming. I am working on a device that uses an 8051 chipset. I have noticed in the sample programs that when defining variables, sometimes they use the keyword xdata. like this...
static unsigned char xdata PatternSize;
while other times the xdata keyword is omitted.
My understanding is that the xdata keyword instructs the compiler that that variable is to be stored in external, flash, memory.
In what cases should I store variables externally with xdata? Accessing those variables takes longer, right? Values stored using xdata do not remain after a hard reset of the device do they?
Also, I understand that the static keyword means that the variable will persist through every call to the function it is defined in. Do static and xdata have to be used together?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
8051架构具有三个独立的地址空间,核心RAM使用8位地址,因此最大可达256字节,XDATA是具有读/写能力的16位地址空间(64Kbytes),程序空间是16位地址空间具有执行和只读数据能力。由于其较小的地址范围和与内核的紧密耦合,对内核 RAM 的寻址在代码空间和访问周期方面更加高效。
最初的 8051 内核具有微型片上 RAM(地址空间为 256 字节,但某些变体具有实际存储器中的一半),XDATA 指的是片外数据存储器(与程序存储器相对)。然而,大多数现代 8051 架构器件都具有片上 XDATA 和程序存储器。
因此,当性能至关重要时,您可能会使用核心内存,而对于较大的内存对象,您可能会使用 XDATA。然而,在大多数情况下,编译器应该为您做出这个决定(检查您的编译器手册,它将详细描述如何分配内存)。指令集使得在核心内存中实现堆栈变得高效,而静态和动态分配的数据通常在 XDATA 中分配更合理。如果编译器有 XDATA 关键字,那么它将覆盖编译器的策略,并且仅应在编译器的策略因某种原因失败时使用,因为它会降低代码的可移植性。
[编辑] 另请注意,核心存储器包括一个 32 字节位可寻址区域,位寻址指令使用该区域中的 8 位地址来直接访问各个位。该区域存在于 256 字节可寻址核心内存中,因此位和字节均可寻址[/编辑]
The 8051 architecture has three separate address spaces, the core RAM uses an 8 bit address, so can be up to 256 bytes, XDATA is a 16bit address space (64Kbytes) with read/write capability, and the program space is a 16bit address space with execution and read-only data capability. Because of its small address range and close coupling to the core, addressing the core RAM is more efficient in terms of code space and access cycles
The original 8051 core had tiny-on-chip RAM (an address space of 256 bytes but some variants had half that in actual memory), and XDATA referred to off-chip data memory (as opposed to program memory). However most modern 8051 architecture devices have on-chip XDATA and program memory.
So you might use the core memory when performance is critical and XDATA for larger memory objects. However the compiler should in most cases make this decision for you (check your compilr's manual, it will describe in detail how memory is allocated). The instruction set makes it efficient to implement the stack in core memory, whereas static and dynamically allocated data would usually be more sensibly allocated in XDATA. If the compiler has an XDATA keyword, then it will override the compiler's strategy, and should only be used when the compiler's strategy somehow fails since it will reduce the portability of the code.
[edit] Note also that the core memory includes a 32byte bit-addressable region, the bit-addressing instructions use an 8bit address into this region to access individual bits directly. The region exists within the 256byte byte addressable core memory, so is both bit and byte addressable[/edit]
xdata 告诉编译器数据存储在外部 RAM 中,因此它必须使用不同的指令来读取和写入该内存,而不是内部 RAM。
访问外部数据确实需要更长的时间。我通常将中断变量放在内部 RAM 中,将大多数大型数组放在外部 RAM 中。
至于硬重置(不是电源周期)后外部 RAM 的状态:这取决于硬件设置。复位线是否连接到外部芯片?另外,有些芯片的 CPU 芯片内带有 XDATA。再读一遍。有些芯片有一个 8051 CPU 以及 IC 内的一些 XDATA。
static 和 xdata 不重叠。静态告诉编译器如何分配变量(在堆栈上或在内存位置)。 Xdata 告诉编译器如何获取该变量。静态还可以将该变量的名称空间限制为仅该文件。您可以有一个仅在函数本地的 xdata 静态变量,也可以有一个在函数本地但使用内部 RAM 的静态变量。
xdata tells the compiler that the data is stored in external RAM so it has to use a different instruction to read and write that memory instead of internal RAM.
Accessing external data does take longer. I usually put interrupt variables in internal RAM and most large arrays in external RAM.
As to the state of the external RAM after a hard reset (not power cycle): That would depend on the hardware setup. Does a reset line go to the external chip? Also some chips come with XDATA within the CPU chip. Read that again. Some chips have an 8051 CPU plus some amount of XDATA within the IC.
static and xdata do not overlap. Static tells the compiler how to allocate a variable (on a stack or at a memory location). Xdata tells the compiler how to get to that variable. Static can also restrict the name space of that variable to just that file. You can have an xdata static variable that is local to just a function, and have a static variable that is local to a function but uses internal RAM.
尚未提及的重要一点是,由于使用不同的指令来访问不同的内存区域,因此硬件没有统一的“指针”概念。已知在 DATA/IDATA 空间中的任何地址都可以用一字节指针唯一地标识;同样,已知位于 PDATA 空间中的任何地址。已知在代码空间中的任何地址都可以用两字节指针来标识;同样,已知位于 XDATA 空间中的任何地址。但在许多情况下,像 memcpy 这样的例程不会提前知道哪个内存空间应该与传入的指针一起使用。为了适应这一点,8x51 编译器通常使用三字节指针类型,可用于访问任何内存空间中的内容(一个字节选择应与指针一起使用的指令类型,其他字节保存值)。像这样的指针声明
将定义一个可以指向任何内存空间的三字节指针。将声明更改为
将定义一个存储在 DATA 空间中的两字节指针,但它只能指向 XDATA 空间中的内容。同样,
将定义一个存储在DATA空间中的两字节指针,但它只能指向DATA和IDATA空间中的内容。使用指向已知数据空间的指针的代码将比使用“通用”三字节指针的代码快得多(可能快十倍)。
An important point not yet mentioned is that because different instructions are used to access different memory areas, the hardware has no unified concept of a "pointer". Any address which is known to be in DATA/IDATA space may be uniquely identified with a one-byte pointer; likewise any address which is known to be in PDATA space. Any address which is known to be in CODE space may be identified with a two-byte pointer; likewise any address which is known to be in XDATA space. In many cases, though, a routine like
memcpy
won't know in advance which memory space should be used with the passed-in pointers. To accommodate that, 8x51 compilers generally use a three-byte pointer type which may be used to access things in any memory space (one byte selects which type of instructions should be used with the pointer, and the other bytes hold the value). A pointer declaration like:will define a three-byte pointer which can point to any memory space. Changing the declaration to
will define a two-byte pointer which is stored in DATA space, but which can only point to things in the XDATA space. Likewise
will define a two-byte pointer which is stored in DATA space, but which can only point to things in the DATA and IDATA spaces. Code which uses pointers that point to a known data space will be much faster (possibly by a factor of ten) than code which uses the "general-purpose" three-byte pointers.
如何以及何时使用 xData 内存区域取决于系统架构。某些系统可能在此地址具有 RAM,而其他系统可能具有 ROM 或闪存。无论哪种情况,访问都会比访问内部 RAM、ROM 或闪存慢。
一般来说,大型项目、常量项目和较少使用的项目应该放入 xData。对于 xData 中的内容没有标准规则,因为它取决于架构。
How and when to use xData memory area depends on the system architecture. Some systems may have RAM at this address while others could have ROM or Flash. In either case, access will be slower than accessing internal RAM, ROM or Flash.
Generally speaking, large items, constant items and lesser used items should go into xData. There are no standard rules as to what goes in xData, as it depends on the architecture.
8051 有一个 128 字节范围的暂存器“伪寄存器”,(大多数)编译器将其用作声明变量的默认值。但显然这个区域非常小,并且您也希望能够将变量放入 16 位内存地址空间中。这就是 xdata(即“外部数据”)说明符的用途。显然,将什么放在哪里取决于数据是什么以及您计划如何使用它。
基本上,我认为这是一个错误的问题。在学习如何使用 C 编译器的 8051 特定功能之前,您需要首先了解 CPU 架构。
The 8051 has a 128 byte range of scratch pad "pseudo-registers" that (most) compilers use as the default for declared variables. But obviously this area is very small, and you want to be able to put variables in the 16 bit memory address space too. That's what the xdata (i.e. "external data") specifier is for. What to put where depends, obviously, on what the data is and how you plan on using it.
Basically, I think this is the wrong question. You need to understand your CPU architecture first before learning how to use the C compiler's 8051-specific features.