DPRG
DPRG List  



[DPRG] I didn't want this to work: C structure confusion

Subject: [DPRG] I didn't want this to work: C structure confusion
From: Dale Wheat dale at dalewheat.com
Date: Fri Sep 8 12:27:50 CDT 2006

C structure adepts:

I am attempting to encapsulate/structure some bit-twiddling that I'm 
doing for low-level hardware control on some ARM7 processors.  I guess 
this technique could be applied to any embedded programming.

I want to eliminate all the magic hexadecimal numbers from my register 
initializations, and replace them with (semi) recognizable constants.

For example, the "Pin Connect Block" registers contain a series of 
two-bit fields for each of the I/O pins.  This is where you tell the 
chip which pins are general-purpose input & output lines (GPIO) or if 
they are to be used by some other on-chip peripheral, such as a UART or 
a timer.  There are up to 4 different functions for each pin, so two 
bits are enough to encode this information.

On the Philips LPC2103, pin 13 can have any one of the following functions:

00) GPIO P0.0 (general purpose IO, Port 0, pin 0)
01) UART0 TXD0 (UART #0 transmit data)
10) MAT3.1 (Timer 3 match output #1)
11) reserved - not used

I figured the way to do this was to define a bunch of constant values 
for the actual bit patterns:

enum { GPIO0_0, TXD0, MAT3_1 };

This assigns the constant value '0' to the symbol GPIO0_0, '1' to TXD0, 
etc.  The enum feature in C starts numbering at zero, and continues up 
incrementally for each new symbol, but these values can be overridden, 
if necessary.  These newly defined symbols can be used instead of typing 
in the actual numeric values.  One step closer to my goal!  This part works.

Next I want to be able to limit where these values can be used.  I don't 
want to be able to tell pin 13 to be the UART RXD (receive) pin, for 
example (it is the transmit pin, TXD0).  I thought I could create a new 
data type for each different bitfield using the typedef declaration, 
like this:

typedef enum { GPIO0_0, TXD0, MAT3_1 } PCB0_0;
typedef enum { GPIO0_1, RXD0, MAT3_2 } PCB0_1;

This also works.  I repeat this process many times and define all the 
possible combinations of pin select options for the available port pins, 
or should I say I will do this once I get it all working, but this 
should be enough to test it for now.

Now I want to gather all these bit patterns together in the same order 
that they are present in the actual hardware register.  I use the C 
aggregate data typing feature, struct, and limit the size of each 
bitfield to two, like this:

volatile struct PINSEL0_T {
	PCB0_0 p0_0 : 2;
	PCB0_1 P0_1 : 2;
} *PINSEL0 = (struct PINSEL0_T *) 0xE002C000;

This creates and initializes a pointer to the register (0xE002C000 
happens to be the address of the pin select 0 register).  Now I should 
be able to twiddle bits by talking to the individual members of the 
structure, and since each one is typedef'd to a limited set of possible 
choices, I shouldn't be able to write the wrong kind of value to a bit:

PINSEL0->p0_0 = TXD0;
PINSEL0->p0_1 = RXD0;

But I can! Waaaa!

GCC doesn't seem to mind mixing my metaphors at all:

PINSEL0->p0_0 = GPIO0_0;
PINSEL0->p0_1 = GPIO0_0; // <-- not supposed to be legal!

...compiles with no errors or warnings, even with the '-Wall' option. 
Changing to '-pedantic' only adds a warning that the bitfield types are 
a GCC-extension.

Can anyone educate me as to why the compiler is not restricting the 
assignment of wrong-type values to my bitfields?  I thought that was 
what typedef'ing was for.

Any insight would be appreciated.  The entire (short) program listing 
follows at the end.

Thanks,

Dale


Program listing:

/* main.c */

typedef enum {
	GPIO0_0,
	TXD0,
	MAT3_1
} PCB0_0;

typedef enum {
	GPIO0_1,
	RXD0,
	MAT3_2
} PCB0_1;
	
volatile struct PINSEL0_T {
	PCB0_0 p0_0 : 2;
	PCB0_1 p0_1 : 2;
} *PINSEL0 = (struct PINSEL0_T*)0xE002C000;

int main(void) {

	PINSEL0->p0_0 = GPIO0_0;
	PINSEL0->p0_1 = GPIO0_0;

	return 0;
}

/* [end-of-file] */

More information about the DPRG mailing list

Copyright © 1984 - 2006 Dallas Personal Robotics Group. All rights reserved.
Website Design by NCC

For the latest robot news visit robots.net