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

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

Re: [avr-libc-dev] new, delete support


From: Ned Konz
Subject: Re: [avr-libc-dev] new, delete support
Date: Thu, 01 Jun 2006 07:17:20 -0700
User-agent: Thunderbird 1.5.0.2 (Macintosh/20060308)

kashey wrote:
kashey пишет:
Ned Konz пишет:
kashey wrote:
Hi all.
When be included support new and delete functions support in avr-libc?


What do you need? Assuming you don't need the whole libstdc++ library, this will probably do what you need for typical C++ programs.


extern "C" {
#include <stddef.h>
#include <stdlib.h>
}

void *operator
new(size_t sz) throw()
{
  return malloc(sz);
}

void operator
delete(void *p)
{
    free(p);
}

extern "C" __cxa_pure_virtual();

void __cxa_pure_virtual()
{
   abort();
}


And what about calling Constructor/Destructor ?

What do you mean? That's not the job of avr-libc.

Is there some code that you want to write that won't call the constructor and destructor, given the above?

I am using a recent version of avr-gcc (4.2.0, almost) and am using templates, constructors, destructors, and so on using more or less just the above and avr-libc.

Most of my objects are static, and so the constructors get called before main() (and the destructors never do), but if there were actually an exit from my code (nowhere to go, in ROM) the destructors would also get called.

Code like this works just fine (and calls the constructor and destructor):

// --------

// compile with
// avr-gcc -x c++ -Os -g -mmcu=atmega128 pulsetest.cpp -o pulsetest.elf
// avr-objdump -C -S pulsetest.elf > pulsetest.lss
//

#ifndef F_CPU
#define F_CPU 16e6
#endif

extern "C" {
#include <stddef.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
}

#define INLINE inline __attribute__((always_inline))

class Pulser
{
    volatile uint8_t &port_;
    const uint8_t bit_;
public:
    INLINE Pulser(volatile uint8_t &port, uint8_t bitNumber)
        : port_(port), bit_(1 << bitNumber)
    { port_ |= bit_; }

    INLINE ~Pulser() { port_ &= ~bit_; }
};

int main()
{
    {
        Pulser pulseMe(PORTC, PC0);
        _delay_ms(1.0);
    }
    abort();
}

// --------

producing code like this:

int main()
  ca:   cf ef           ldi     r28, 0xFF       ; 255
  cc:   d0 e1           ldi     r29, 0x10       ; 16
  ce:   de bf           out     0x3e, r29       ; 62
  d0:   cd bf           out     0x3d, r28       ; 61
  d2:   a8 9a           sbi     0x15, 0 ; 21
  d4:   80 ea           ldi     r24, 0xA0       ; 160
  d6:   9f e0           ldi     r25, 0x0F       ; 15
  d8:   01 97           sbiw    r24, 0x01       ; 1
  da:   f1 f7           brne    .-4             ; 0xd8 <main+0xe>
  dc:   a8 98           cbi     0x15, 0 ; 21
  de:   ff cf           rjmp    .-2             ; 0xde <main+0x14>


I use the above definition of INLINE to force inlining instead of macros.

I've also found that using templates can help the code generation quite a bit.

In this case, it doesn't, for some reason (the destructor ends up doing an in/and/out instead of a cbi), but it does work:

//-----

// compile with
// avr-gcc -x c++ -Os -g -mmcu=atmega128 pulsetest2.cpp -o pulsetest2.elf
// avr-objdump -C -S pulsetest2.elf > pulsetest2.lss
//

#ifndef F_CPU
#define F_CPU 16e6
#endif

extern "C" {
#include <stddef.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
}

#define INLINE inline __attribute__((always_inline))

template <uint16_t portAddr, uint8_t bitNumber>
struct Pulser
{
    INLINE static volatile uint8_t &port()
    { return *(volatile uint8_t *)(void *)portAddr; }
    static const uint8_t bitMask = 1 << bitNumber;
    INLINE Pulser() { port() |= bitMask; }
    INLINE ~Pulser() { port() &= bitMask; }
};

const uint16_t portCAddress = 0x35;

int main()
{
    {
        Pulser<portCAddress,PC0> pulseMe;
        _delay_ms(1.0);
    }
    abort();
}

//-----

produces this:

int main()
  ca:   cf ef           ldi     r28, 0xFF       ; 255
  cc:   d0 e1           ldi     r29, 0x10       ; 16
  ce:   de bf           out     0x3e, r29       ; 62
  d0:   cd bf           out     0x3d, r28       ; 61
  d2:   a8 9a           sbi     0x15, 0 ; 21
  d4:   80 ea           ldi     r24, 0xA0       ; 160
  d6:   9f e0           ldi     r25, 0x0F       ; 15
  d8:   01 97           sbiw    r24, 0x01       ; 1
  da:   f1 f7           brne    .-4             ; 0xd8 <main+0xe>
  dc:   85 b3           in      r24, 0x15       ; 21
  de:   81 70           andi    r24, 0x01       ; 1
  e0:   85 bb           out     0x15, r24       ; 21
  e2:   ff cf           rjmp    .-2             ; 0xe2 <main+0x18>


Thanks,
--
Ned Konz
address@hidden
http://bike-nomad.com




reply via email to

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