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

xdata access by #define

I have to read a flash written by another program and am provided a file looking like this

// data locations
#define data1 0
#define data2 data1+0x100
...

I would like to use the file 'as is" but all my typecasting efforts have resulted in errors or wrong code.

In advance, thanks

Erik

  • Without knowing what errors or wrong code you were getting, I can only guess that the typecasting failures are due data2's expression definition lacking parentheses to avoid side effects. To use the include file unchanged, I would suggest you provide the parentheses explicitly or by xdata access macros as in:

    #define XDATA_BYTE_ACCESS(addr) (*(unsigned char xdata *)(addr))
    #define XDATA_WORD_ACCESS(addr) (*(unsigned int  xdata *)(addr))
    
    unsigned char b;
    unsigned int  w;
    
    void main(void)
    {
        b = XDATA_BYTE_ACCESS(data2);
        w = XDATA_WORD_ACCESS(data2);
    }
    

  • Have you checked out the C51 predefined macros for this - XBYTE, XWORD, etc?

    They're in the manual under "Absolute Memory Access Macros"

  • Thanks Andy,
    Things are so simple to use when you know what they are called.

    Erik

  • Have you checked out the C51 predefined macros for this - XBYTE, XWORD, etc?

    Side note for other readers...

    Be sure to understand what this really means in your context and "read the fine print" in the manual before using the 'WORD versions of the macros in absacc.h. They are not directly address-compatible like the 'BYTE versions are. For example XBYTE[data2] and XWORD[data2] (using data2 from Eric's example) will not access the same address.

  • "For example XBYTE[data2] and XWORD[data2] (using data2 from Eric's example) will not access the same address."

    Yes.
    I think this is also well illustrated in these threads:
    http://www.keil.com/forum/docs/thread2575.asp
    http://www.keil.com/forum/docs/thread2574.asp

  • "I think this is also well illustrated in these threads:"

    Topically, I'm a bit confused by those references, since the threads did not relate to this one on a strictly technical basis. Are you implying anything beyond "Please read the manual" as you justifiably recommended there and as it applies here?

  • I was thinking that the caution noted by Dan and the "problems" experienced in the cited threads both relate to a proper understanding of the Compiler's internal data representation - or lack thereof!

    Yes - in the end, it all comes down to Please read the manual!! ;-)

  • "the "problems" experienced in the cited threads both relate to a proper understanding of the Compiler's internal data representation - or lack thereof!

    Thanks for clarifying. I figured my point didn't come across. Yes those threads do relate to internal representation. However, yy cautions are independent of the implementation -- strictly a "C thing". The context in which XBYTE and XWORD are used expect "array-ness", if you will, and this is a particular problem with XWORD, regardless of the target system. XBYTE[data2] accesses a byte at address 0x0100, whereas XWORD[data2] accesses a word at address 0x0200.

    I personally find the dichotomy awkward and a source of errors. When I'm thinking in terms of addresses, I want my macros to implement them as addresses/pointers, not arrays where one macro coincidentally works with addresses and the other does not. I prefer something a bit more generic, allowing me to always use addresses pointing to anything. A contrived example:

    // data locations
    #define data1 0
    #define data2 data1+0x100
    
    #define XDAT(type, addr)    (*(type xdata *)(addr))
    
    struct FOO
    {
        long l[3];
        char c;
    };
    
    unsigned char b;
    unsigned int  w;
    unsigned long l;
    
    void main(void)
    {
        b = XDAT(unsigned char, data2);
        w = XDAT(unsigned int,  data2);
        l = XDAT(unsigned long, data2);
    
        b = XDAT(struct FOO, data2).c;
    }