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

mapping SFR space

How would I locate a structure to coincide with the beginning of SFR space for the 8051? address 0x80 of directly assessible data memory.

We are using a core8051 (inside an FPGA), and the core8051 lets us map external events to SFR space. So it would be very convienent to define a structure which allows us to more easily access all of SFR space. (we take care not to "stomp" on already defined SFR registers.

How can I do that?

Thanks

Parents Reply Children
  • Why do you want to overlay SFR space with a structure?

    The usual reason for declaring a structure to overlap registers is to access multiple instances of a piece of hardware via a base pointer. That is, the code looks something like:

       instance1->intMask |= myInt;
       instance2->intMask |= MyInt;
    

    The 8051 architecture isn't well suited to pointers, so this coding style wouldn't be very efficient.

    Even if you locate a single copy of the structure at a fixed memory location

       struct { ... } SFR _at_ 0x80;
    
       SFR.P0 |= 1;
    

    you're going to run into the 8051 quirk that the addressing mode interacts with the address to determine what address space you actually wind up seeing.

    There are two of each address 80H through 0FFH. Direct addressing reaches an SFR. Indirect addressing reaches a byte of RAM (for variants with 256 bytes of RAM intead of 128). If you try to make SFR space look like a variable in data space, you're going to run the risk of confusing the code generator and having it generate an indirect access to a location, which won't do what you want.

    The sfr keyword is in C51 for a reason. SFRs are not like just another byte of data space. The 8051 is a peculiar architecture with concepts that C, with its CPUs-have-exactly-one-address-space assumption, doesn't quite match.

    You might want to consider sticking with the definitions in the REG.h files and the coding style that just treats SFRs as independent variables.

        EA = 0;
        P0 &= 0x0f;
    

  • Hopefully

    That's exactly the problem, in a single word. You're relying on hope to resolve a technical problem. That cannot ever, possibly, be a good idea.

    That link you dug up doesn't actually define the struct in C --- it declares it in C, then defines the address (but not the size) in assembly. The C compiler doesn't even know this structure is in SFR space. That opens a can of worms like you wouldn't believe. E.g. if you were to use struct assignment on such a struct, the compiler would almost certainly use its internal equivalent of memcpy() to do that --- but that uses pointers, and there is no such thing as a pointer to an SFR. Madness will ensue.

    Basically none of the things for which a struct offers any actual advantage over individual variables can really work if the struct is in SFR space. The net gain between

    sfr foo_a;
    sfr foo_b;
    sfr foo_c;
    


    and what you want to do:

    sfr struct {
       u8 a;
       u8 b;
       u8 c;
    } foo;
    


    is, for practical purposes, zero.