Taking advantage of cotiguous bytes in struct = portable?

From: Kobu (kobu.selva_at_gmail.com)
Date: 02/16/05


Date: 16 Feb 2005 13:08:28 -0800

In embedded systems (programmed in C), often times structure
declarations are used to group together several status/control/data
registers of external hardware (or even internal registers). The
example below (from GBD's THE C BOOK) uses this. Is this a portable
method? [Note, there is no issue with structure "padding" because no
structure object is defined, only a declaration is used to access
existing hardware].

/*
* Declare the device registers
* Whether to use int or short
* is implementation dependent
*/

struct devregs{
        unsigned short volatile csr;
        unsigned short const volatile data;
};

/* bit patterns in the csr */
#define ERROR 0x1
#define READY 0x2
#define RESET 0x4

/* absolute address of the device */
#define DEVADDR ((struct devregs *)0xffff0004)

/* number of such devices in system */
#define NDEVS 4

/*
* Busy-wait function to read a byte from device n.
* check range of device number.
* Wait until READY or ERROR
* if no error, read byte, return it
* otherwise reset error, return 0xffff
*/
unsigned int read_dev(unsigned devno){

        struct devregs * const dvp = DEVADDR + devno;

        if(devno >= NDEVS)
                return(0xffff);

        while((dvp->csr & (READY | ERROR)) == 0)
                ; /* NULL - wait till done */

        if(dvp->csr & ERROR){
                dvp->csr = RESET;
                return(0xffff);
        }

        return((dvp->data) & 0xff);
}

Any portability issues? At first sight this looks like an awesome
technique!