avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] port access with avr-gdb


From: Ned Konz
Subject: Re: [avr-gcc-list] port access with avr-gdb
Date: Fri, 18 Jun 2004 12:40:38 -0700
User-agent: KMail/1.6.2

On Sunday 13 June 2004 7:23 am, Dave Hylands wrote:
> One way to get the registers to show up symbolically, is to create a
> structure which has the same layout as the registers. Then you can access
> through a null pointer. This would allow you to see the registers in GDB.
> They still wouldn't show up I nthe linker map though.
>
> There are ways of making them show up in the linker map too. Just create an
> asm file which has each of the registers named. On the C side you'd have
> appropriate externs decalred.

I rather like the way that Microchip's C18 compiler does it...

extern volatile near unsigned char       PORTA;

extern volatile near union {
  struct {
    unsigned RA0:1;
    unsigned RA1:1;
    unsigned RA2:1;
    unsigned RA3:1;
    unsigned RA4:1;
    unsigned RA5:1;
    unsigned RA6:1;
  };
  struct {
    unsigned AN0:1;
    unsigned AN1:1;
    unsigned AN2:1;
    unsigned AN3:1;
    unsigned :1;
    unsigned AN4:1;
    unsigned OSC2:1;
  };
  struct {
    unsigned :2;
    unsigned VREFM:1;
    unsigned VREFP:1;
    unsigned T0CKI:1;
    unsigned SS:1;
    unsigned CLK0:1;
  };
  struct {
    unsigned :5;
    unsigned LVDIN:1;
  };
} PORTAbits;


So you can just write stuff like:

        PORTAbits.RA0 = 1;

or if you want:

        PORTA |= 1;

The registers themselves are defined in the processor library, which is 
compiled from the .asm sources.

In this case, the corresponding part of the p18f452.h file looks like:

SFR_UNBANKED0       UDATA_ACS H'F80'    ; segment reference with absolute 
address
PORTA               
PORTAbits           RES 1     ; 0xF80

This has the added advantage of catching mismatches between bit names and 
registers.

It does not tell the compiler that PORTAbits and PORTA are aliases of each 
other, though since these are all declared as volatile I don't know if that 
matters much (I suppose it could save a pointer load).

To avoid that problem you could do this:

extern volatile near union {
  struct {
    unsigned RA0:1;
    unsigned RA1:1;
    unsigned RA2:1;
    unsigned RA3:1;
    unsigned RA4:1;
    unsigned RA5:1;
    unsigned RA6:1;
  };
  struct {
    unsigned AN0:1;
    unsigned AN1:1;
    unsigned AN2:1;
    unsigned AN3:1;
    unsigned :1;
    unsigned AN4:1;
    unsigned OSC2:1;
  };
  unsigned char bits;
} PORTAbits;

#define PORTA PORTAbits.bits

This also allows re-use between processor families if you're clever; each 
family of functions (say PORTA and its usual pin definitions) could be in a 
separate header file, with only the things like the pin overloading (here, 
for instance, RA0 and AN0 are on the same pin) being processor-specific.

I wasn't able to see Larry's suggestion, as it got stripped.

-- 
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE


reply via email to

[Prev in Thread] Current Thread [Next in Thread]