可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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]
回答2:
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.
回答3:
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:
char *ptr;
will define a three-byte pointer which can point to any memory space. Changing the declaration to
char xdata *data ptr;
will define a two-byte pointer which is stored in DATA space, but which can only point to things in the XDATA space. Likewise
char data * data ptr;
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.
回答4:
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.
回答5:
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.