[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