This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

What's wrong with my struct *

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;
    
    If this is not what you meant and I missed something C51-specific, I apologize.

    Regards,
    - mike

  • 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.