avr-libc-dev
[Top][All Lists]
Advanced

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

Re: [avr-libc-dev] Port and Memory Mapped Register Definitions


From: Bill Somerville
Subject: Re: [avr-libc-dev] Port and Memory Mapped Register Definitions
Date: Fri, 27 Sep 2002 19:51:40 +0100

"Theodore A. Roth" wrote:
> 
> Hi Bill,
> 
> On Fri, 27 Sep 2002, Bill Somerville wrote:
> 
> :) Hi
> :)
> :) I don't see any activity on the list, so I hope someone is there.
> 
> I'm here, but silently brooding over my next evil attempt at world
> domination...
> 
> :)
> :) Four points about the library:
> :)
> :) 1)
> :) Is there any reason why the above should not be defined along the
> :) following lines:
> :)
> :) #define REG_ADDR 0xnn
> :) #define REG _SFR_IO8(REG_ADDR)
> :)
> :) rather than the direct:
> :)
> :) #define REG _SFR_IO8(0xnn)
> :)
> :) The reason being to enable the REG_ADDR macro to be passed as a C++
> :) template parameter to a template class like:
> :)
> :) template< const uint8_t Port_addr, const uint8_t Ddr_addr >
> :) class IOPort
> :) {
> :)    public:
> :)       IOPort( uint8_t direction_flags )
> :)       {
> :)           *( volatile uint8_t * const )Ddr_addr = direction_flags;
> :)       }
> :)       IOPort& operator=( uint8_t value )
> :)       {
> :)          *( volatile uint8_t * const )Port_addr = value;
> :)       }
> :)       operator volatile uint8_t()
> :)       {
> :)          return *( volatile uint8_t * const )Port_addr;
> :)       }
> :) };
> :)
> :) Used like:
> :)
> :) IOPort< PORTA, DDRA > port_a( 0xff );
> :)
> :) port_a = port_a & 0xf0 | ~i & 0x0f; // put low nibble of i on port a
> :)
> :) This then allows constructs like mutex guarded ports to be easily
> :) defined.
> 
> If you are going to do that, I think you should just disable the _SFR_*
> macros complete since you're replacing their functionality (mostly). I
> think you'd still want to use them to get the mmio offsets though. Read
> this:
> 
>   
> http://savannah.nongnu.org/download/avr-libc/doc/avr-libc-user-manual/group__avr__sfr__notes.html
> 
> I'm guessing you want to define _SFR_ASM_COMPAT in all your source
> (-D_SFR_ASM_COMPAT on the gcc/g++ command line) which should disable the
> use of _MMIO_{BYTE,WORD} macros, but still give you the correct (raw) mmio
> addrs which you can cast as you do in your template.
> 
> OT: What's the code space overhead of using the templates to do this? I'm
> not a C++ guy, so I'm curious.

I think the old functionality is fine and should remain for C progs,
splitting the definitions into address and addressed object (the
register) was only needed because of a C++ quirk.

There was a mistake in my template class, I should have added 0x20 to
the register address.

pauses while RTFM...

OK, now I've read the document above I see that using the _SFR_ADDR()
macro gets the register address without defining any other macros. I
didn't look at this because of the leading underscore, but the
documentation implies it's not an implementation macro after all :-)

So with this I can use the template above and define:

IOPort< _SFR_ADDR( PORTA ), _SFR_ADDR( DDRA ) > port( 0xff );

and as a bonus the +0x20 is not required in the template definition
either.

The code overhead is zero because the template is fully expanded by the
compiler in line (at least at -O2 it is).

> 
> :)
> :) 2)
> :) It appears that outb() and inb() always use memory mapped i/o ports
> :) rather than registers if possible - is this true and if so why?
> 
> Hmmm. I don't have a clue. Marek reimplemented these using the _SFR_*
> mechanism, so that might have something to do with it.

My mistake - I should have read the comments in the header! The compiler
converts memory-mapped register access to in/out instructions where
possible in all optimization levels.

> 
> :)
> :) 3)
> :) The setjmp.h header file is not C++ compatible (no extern "C++"
> :) declaration), is this deliberate?
> 
> I don't know the history on this, but I don't see any harm in fixing it.
> I'll fix it, but I would like to know if the jmp_buf struct definition
> needs to be protected too?

Yes, just the usual

#ifdef __cplusplus
extern "C" {
#endif

...

#ifdef __cplusplus
}
#endif

stuff around everthing but the header guard.

> :)
> :) 4)
> :) Given that g++ generates avr code and gcrt1.S is now C++ compatible, it
> :) would be nice to have a very basic C++ library with the various
> :) std::new, std::delete, and std::set_new_handler fns defined, or at least
> :) the nothrow versions.
> 
> I assume you're talking about a "watered down" version of libstdc++ for
> avr? I'm not against it, but I don't have the know-how to do. I vaguely
> remember a discussion of this on avr-gcc-list a while back (Feb-2002
> archives show some discussion).
> 
> Due to the small memory available for the avrs, this would have to be very
> minimalistic. If you'd like to offer up some code, we can consider it for
> inclusion.

I've got versions of new, delete, new_handler, set_new_handler that I
use, I'll tidy them up and post them here - they are pretty short and
simple as they just delegate to malloc() and free(). I'm not sure of the
position with exceptions (which is related) with avr-g++, I havn't tried
them - I see the compiler turns them off by default. I expect the
overhead maybe too much for the smaller acrhitectures. Has anyone tried
code with exceptions?

> Ted Roth

Thanks for the prompt response.

Bill Somerville




reply via email to

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