I'm using 80c390 in 24-bit mode (a TINI board). If I define the following: struct rtc { unsigned char seconds; unsigned char minutes; unsigned char hours; } struct rtc *p_time; I have a pointer (p_time), which is located somewhere in XDATA ( > 0x100080) and it points to address I:0x00 and there messes up with register bank0. If I declare the pointer as struct rtc * xdata p_time; it points to X:0x000000. What am I doing wrong? Val
I'm not familiar with C51, but it seems to me that this is a C question. Nothing is wrong. You declared a global variable which is a pointer to a structure. It was initialized with zero, as all global variables without initializers are. You got a NULL pointer. If you want it to point to a variable of the type struct rtc, declare a variable of that type and assign its address to your pointer:
struct rtc rtc_time; struct rtc *p_time = &rtc_time;
Thanks Mike. It is exactly what I need.
You also might want to read the section on the manual where it talks about "generic" pointers and memory-specific pointers. Since the 8051 has so many different memory spaces with different access instructions, Keil C tags generic pointers with an extra byte so it can tell what memory area is pointed to. "0" means idata/data, so an uninitialized pointer (all zeroes) will point there. If you declare a pointer to a specific memory type (e.g., "mystruct * xdata p"), then the memory area is part of the type information, and the compiler does not generate the extra type byte.
"'0' means idata/data, so an uninitialized pointer (all zeroes) will point there." Thus uninitialised pointers in C51 can very easily trash your Stack! :-0
Even worse: that all-zeros pointer will trash your registers. In hindsight, I'd wish for a different mapping for that tag byte. (Say 0-7fh is xdata, without having to subtract one to get the bank; high values can map to code and idata/data.) But changing now would introduce a fairly major incompatibility with existing code, and annoy everyone that wrote assembler routines that have an interface with a C pointer involved.