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

struct pointing to RTC in far memory location.

I have a Real Time Clock (RTC) located at address 0x180000

I would like to create a struct of the RTC registers and map it to 0x180000 where the RTC registers start, located in far xdata memory or (HDATA).

I want to access the RTC such as

 RTC.Month = 8; 

Would I use the FVAR or far * in some way to accomplish this?

Thanks for your help..

Parents
  • I think that would be a reasonable thing to do, yes. Something like:

    #define RtcAddr  0x180000
    
    typedef struct
        {
        U16 year;
        U8 month;
        U8 day;
        } RtcReg;
    
    #define Rtc  FVAR (RtcReg, RtcAddr)
    
    ...
    
    Rtc.month = 8;
    
    

    If you peek at the definition of FVAR, you'll see that it's a macro that really just adjusts an address for the Keil tag byte coding scheme, casts it to a pointer to the type given, and dereferences that pointer. So it's a way to claim that a variable of a particular type lives at a particular address, without actually declaring a variable.


    The way I read the manual, you should also be able to use the _at_ extension to declare a variable at the right location:

    RtcReg far Rtc _at_ 0x180000UL;
    
    Rtc.month = 8;
    

    But I've never done it that way myself.

    A variation would be to put the variable in a source file by itself, so that it will wind up in a data segment by itself, and then use the linker to specify the location of that data segment. A bit more trouble, but it avoids the use of one non-standard extension if portability is a concern.

    (The first method is, IMO, the most portable; people tend to forget about the linker configuration files, and there's no commonality at all between linker control file / directive syntax from one linker to another. Most projects I've worked on use the cast-an-address route to physically locate a variable.)

Reply
  • I think that would be a reasonable thing to do, yes. Something like:

    #define RtcAddr  0x180000
    
    typedef struct
        {
        U16 year;
        U8 month;
        U8 day;
        } RtcReg;
    
    #define Rtc  FVAR (RtcReg, RtcAddr)
    
    ...
    
    Rtc.month = 8;
    
    

    If you peek at the definition of FVAR, you'll see that it's a macro that really just adjusts an address for the Keil tag byte coding scheme, casts it to a pointer to the type given, and dereferences that pointer. So it's a way to claim that a variable of a particular type lives at a particular address, without actually declaring a variable.


    The way I read the manual, you should also be able to use the _at_ extension to declare a variable at the right location:

    RtcReg far Rtc _at_ 0x180000UL;
    
    Rtc.month = 8;
    

    But I've never done it that way myself.

    A variation would be to put the variable in a source file by itself, so that it will wind up in a data segment by itself, and then use the linker to specify the location of that data segment. A bit more trouble, but it avoids the use of one non-standard extension if portability is a concern.

    (The first method is, IMO, the most portable; people tend to forget about the linker configuration files, and there's no commonality at all between linker control file / directive syntax from one linker to another. Most projects I've worked on use the cast-an-address route to physically locate a variable.)

Children
No data