Electronic – Microchip XC8: How to Overlap Specific Variables without Union

clinkerpicxc8

I have effectively three sets of variables to put in two locations. Sets 1 and 2 are never used together, so they can occupy the same space. Set 3 needs to be unique.

I know I can use a union of structs to get what I want, but that's a lot of data to force into the same area, and it makes the names unnecessarily complex in my opinion:

union
{
    struct
    {
        ...
    } set_1;
    struct
    {
        ...
    } set_2;
} shared_variables;

I can also assign a specific address to each variable, but that doesn't allow any freedom for the linker to optimize them:

unsigned char foo_1 @ 0x1A0;
unsigned int  bar_1 @ 0x1A1;

unsigned long foo_2 @ 0x1A0;    //same address as foo_1

I can assign a section name to each variable and tell the linker what to do with the sections, but I still think it's too restrictive:

unsigned char __section("set_1") foo_1;    //set_1 is 1 byte
unsigned int  __section("set_1") bar_1;    //set_1 is now 3 bytes

unsigned long __section("set_2") foo_2;    //set_2 is 4 bytes

//linker: -L-Ashared_class=<address_range> -L-Pset_1=shared_class -L-Pset_2=shared_class
//actually concatenates them somewhere in the specified range (total 7 bytes), not sure how to overlay them (total 4 bytes)

Is there a way to tell it, "I don't care if this set of variables overlaps that set of variables, but this other set of variables must be unique," and just leave it at that?

Edit in response to comments:

  • Set 1 + Set 2 + Set 3 represent all the variables that are used in the entire project.
  • The code that uses them is currently spread across 4 source modules.
  • Like most if not all chips in this range made by Microchip, the memory is fragmented in hardware into 80-byte chunks separated by hardware configuration registers. There is another addressing mode that requires a pointer to access all the fragments as if they were contiguous, but that would thrash the pointer registers a lot. (and there seems to be a bug in the debugger that corrupts data that's used that way in certain cases; normal running is okay though)

Best Answer

I find unions perfectly fine for "sharing" variables. Let me expand on this with code:

typedef struct
{
  union
  {
     struct
     {
     } set_1;
     struct
     {
     } set_2;
  } set_union;
  struct
  {
  } set_3;
} data_set;

... Of course, this could be made much more readable using typedefs on set_1 and set_2.