Search code examples
cembeddedmappingextern

Declaring mapped address as an extern


I'm trying to map some locations, and here is a sample of my code. The point I want to declare porta and ddra as an extern variables so I can share them between files.

typedef union _porta
{
  byte REGISTER;
  struct 
  {
     unsigned PA0:1;
     unsigned PA1:1;
     unsigned PA2:1;
     unsigned PA3:1;
     unsigned PA4:1;
     unsigned PA5:1;
     unsigned PA6:1;
     unsigned PA7:1;

  };
}PORTA;


typedef union _da
{
  byte REGISTER;
  struct 
  {
     unsigned  DA0:1;
     unsigned  DA1:1;
     unsigned  DA2:1;
     unsigned  DA3:1;
     unsigned  DA4:1;
     unsigned  DA5:1;
     unsigned  DA6:1;
     unsigned  DA7:1;

  };
}DDRA;


#define porta      (*(( volatile PORTA *)0x22))
#define  ddra        ( *(( volatile DDRA *)0x21) ) 
// Here in the same header want to declare porta and ddra as an extern variables I can use outside 

Solution

  • Simple put the defines and the typedefs in a header file and name it "xxx_registers.h" or some such (where xxx is your MCU). That's how this is usually done.

    However, you should name the typedef DDRA_t and then #define DDRA ... volatile DDRA_t*. It is custom to always use capital letters for register names.

    IMPORTANT: Make sure that strict aliasing is disabled in your compiler! Otherwise code like this may break in horrible ways. This is mostly a problem with the gcc compiler, but other compilers might handle strict aliasing in similar dysfunctional ways. For gcc, always compile with -fno-strict-aliasing when coding embedded systems, or otherwise that compiler can't be used.

    Please note that bit-fields are non-portable and dangerous, so there is no guarantee that this code will work on other compilers. It is better and safer to use bitwise operators for accessing individual bits, rather than bit-fields.