Question

CPU: 8051 based

The following lines of code will set 0xaa value at 0x0aaa address in external flash memory.

mov     a,#0aah
mov     dptr,#X0aaa
movx    @dptr,a

The following is mov

The MOV instruction allows data to be transferred between any internal I-RAM spaces or SFR locations and between accumulator to internal I-RAM spaces or SFR locations.

and and movx instruction descriptions from CPU datasheet

MOVX instruction is used to access the internal X-RAM and e-FLASH area. Only indirect addressing can be used. The choice whether to use a one-byte address, @Ri, where Ri can be either R0 or R1 of the selected register bank, or a two-byte address, @DPTR.

CPU datasheet

Some code that I've seen in examples:

xdata UCHAR * data ecFlashaaa  = (xdata UCHAR *)(0xaaa); 
*ecFlashaaa  = 0xaa;

the code doesn't compile because it doesn't know what is xdata and also confused on data. So somehow I need to explain linker that ecFlashaaa is pointing to e-Flash...

Was it helpful?

Solution 2

The difference between your sample code:

xdata UCHAR * data ecFlashaaa  = (xdata UCHAR *)(0xaaa); 
*ecFlashaaa  = 0xaa;

And the accepted answer is that with xdata the compiler will generate code very similar to your assembly snipet. The literal value 0xaa will be written to location 0xaaa in external RAM (or, in your case, what appears to be a memory mapped EEPROM in the external RAM space) in a few instructions.

The accepted answer with a generic pointer declared unsigned char *flashptr will use a 3-byte type for flashptr where the upper byte will indicate which memory space the address is in. So instead of being declared as a pointer to xdata it is declared as a generic pointer and then assigned a value like {XDATA, 0x0AAA}. Access to generic pointers is by calling a library routine which uses the correct instruction (mov, movc, or movx) to access the memory.

The cost isn't too bad if you use a utility function (e.g. memcpy) which is smart enough to determine the memory type once and then use an optimized copy loop. If you write your own copy loop the performance will be significantly worse if you use a generic pointer unnecessarily.

(The sample code you found that I quoted was probably written for Keil's C51 compiler)

OTHER TIPS

Data and xdata are probably either compiler extensions or macros (defined in a header file) that qualify the data type.

Writing the code in C is pretty simple. But whether or not it generates the assembler you want is going to depend on how smart your compiler is. Does it know about the different kinds of memory in your system?

What you want to do is declare a pointer to a byte, and then set the value of the pointer (not what it points to) to the address you wish to access. Then you can dereference the pointer and set it to the value you want.

unsigned char *flashptr = (unsigned char *)0xaaa;
*flashptr = 0xaa;

Which is pretty much what you have in the example, without the extra data/xdata in there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top