Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
TFrancuz
PostPosted: Feb 05, 2008 - 02:53 AM
Resident


Joined: Jan 10, 2003
Posts: 533


Hi everybody,
a couple of months ago I started with AVR and c++. It's rather painful adventure, but now most of things seems to work. So I decided to share my little experience, maybe it will be useful for you.
First thing – setup. I use AVR Studio, which is almost working with c++. Almost, because you must manually in project->Configuration options->Custom options set instead of avr-gcc avr-c++.exe to compile any of your c++ files. Just changing the extension to cpp/hpp doesn't work. Remember that if you want to debug your application you need rather to turn off code optimization (-O0). In other case debugging is extremely hard thing to do and confusing. Final compilation can be done with any optimization options.
Next thing to do is to define new and delete operators:
Code:

#include <stdlib.h>

void * operator new(size_t size);
void operator delete(void * ptr);

and implementation:
Code:

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

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

That's almost all. Almost because if you are using gcc 4.x and newer (I didn't check it with older versions) and you want to use templates, virtual inheritance and so on you must define some additional functions, which is not used now by compiler, but must be present to satisfy linker:
Code:

__extension__ typedef int __guard __attribute__((mode (__DI__)));

extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);

Please be sure to define these functions exactly as I showed, I other case gcc could crash during compilation (segmentation fault!), and for sure your program WILL BE NOT working.
Implementation is as follow (very important too):
Code:

int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
void __cxa_guard_abort (__guard *) {};

And last thing, if you use pure virtual functions you must define another function:
Code:

extern "C" void __cxa_pure_virtual(void);

and implementation:
Code:

void __cxa_pure_virtual(void) {};

This function is never called in normal operation. The only time this function may get called is if the application calls a virtual function while the object is still being created, which gives undefined behavior. So implementation is not very important for us.
With all this things defined I was able to compile my c++ programs without any problems, and I wish the same to you.
Greetings,
Tomasz.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: Feb 05, 2008 - 10:25 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Brilliant!

Attention moderators! Sticky candidate?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Feb 05, 2008 - 11:07 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

At the very least I thought Tomasz ought to repost this as a tutorial in the Tutorial Forum so it's doesn't get "lost"

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Feb 06, 2008 - 04:06 AM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13956
Location: Vancouver, BC

Also, someone put the term "CPlusPlus" in it so that it can be found by the search function. Oh look, someone just did Smile

_________________
Regards,
Steve A.

The Board helps those that help themselves.


Last edited by Koshchi on Apr 12, 2008 - 06:09 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
steve17
PostPosted: Feb 06, 2008 - 01:35 PM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

I don't have any of the cxa stuff. I never heard of it. My virtual functions aren't pure though.

The only problem I have with virtual functions is they use a huge amount of RAM and quite a bit of program memory also.

I'm currently using gcc version 4.1.2.
 
 View user's profile Send private message  
Reply with quote Back to top
cpluscon
PostPosted: Feb 17, 2008 - 01:06 AM
Raving lunatic


Joined: Jul 10, 2006
Posts: 2656
Location: Minneapolis

These array handlers may be useful too:

Code:
void * operator new[](size_t size)
{
    return malloc(size);
}

void operator delete[](void * ptr)
{
    free(ptr);
}
 
 View user's profile Send private message  
Reply with quote Back to top
kbosak
PostPosted: Jun 19, 2008 - 11:26 PM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

except the spurious semicolons that generate errors in pedantic + ansi mode,
Code:
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
void __cxa_guard_abort (__guard *) {};
,
you just made a top grade post.

I would also add '-fno-exceptions' and maybe '-ansi --pedantic -Wall' to avoid shooting ourselves in the foot. g++ AVR is uncharted minefield. Any other flags to include?

BTW in order to help newbies finding the g++ and make quicker, here is my example of Project Options/External tools that worked for me:
I:\WinAVR-20071221\bin\avr-g++.exe
I:\WinAVR-20071221\utils\bin\make.exe

The last trap is in the fact that by default printf is not supporting float numbers. However because the C++ projects can be complex, it is wise to go to Project Options/Libraries section, you might want to include
libprintf_flt
libscanf_flt
libc
libm
libobjc
but NOT libprintf_min, libscanf_min

BTW I remember the problem, when a simple code

Code:

int main()
{
   DDRC=0xFF;
   for(;;)
   {
      PORTC=0xFF;
      _delay_us(1);
      PORTC=0x00;
      _delay_us(1);
   }
}

...was not working just because I have been instancing a static class object in one of include files. It took me the whole night to find the problem, hopefully my suspicions pointed onto global objects very early. The funny part was, that everything worked when the project was big. Once I have simplified (!!!) main() function to the code above, it stopped working (freeze before main). I have hunted down the statically instantiated class in one of includes, and moved it as static object to main().
This time, however, it started complaining about lacking __cxa_guard_acquire, __cxa_guard_release.
So remember, when you make static class object in global scope, without providing these functions, the code will fail silently, depending on the actual size of the project and many other factors.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
atomicdog
PostPosted: Jun 20, 2008 - 02:10 AM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

kbosak wrote:

I would also add '-fno-exceptions' and maybe '-ansi --pedantic -Wall' to avoid shooting ourselves in the foot. g++ AVR is uncharted minefield. Any other flags to include?



These will help with the code size.
Code:

-ffunction-sections
-Wl,--gc-sections



http://www.avrfreaks.net/index.php?name ... mp;t=64513

_________________
~~John
TWI C source code
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Levenkay
PostPosted: Jun 21, 2008 - 10:28 AM
Resident


Joined: Dec 20, 2007
Posts: 946
Location: Portland, Oregon, USA

TFrancuz wrote:
Hi everybody,
a couple of months ago I started with AVR and c++. It's rather painful adventure, but now most of things seems to work. So I decided to share my little experience, maybe it will be useful for you.
First thing – setup. I use AVR Studio, which is almost working with c++. Almost, because you must manually in project->Configuration options->Custom options set instead of avr-gcc avr-c++.exe to compile any of your c++ files. Just changing the extension to cpp/hpp doesn't work. Remember that if you want to debug your application you need rather to turn off code optimization (-O0). In other case debugging is extremely hard thing to do and confusing. Final compilation can be done with any optimization options.
Next thing to do is to define new and delete operators:
Code:

#include <stdlib.h>

void * operator new(size_t size);
void operator delete(void * ptr);

and implementation:
Code:

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

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


That's almost all.
... (abridged) ...

With all this things defined I was able to compile my c++ programs without any problems, and I wish the same to you.
Greetings,
Tomasz.


This is pretty impressive (I thought I knew a thing or two about C++, but "guard"s are a new one on me).

One thing I think you have missed, though, is that delete operators are supposed to safely do nothing if they're passed a NULL pointer. So your sample implementation of delete should look like this:
Code:

void operator delete(void * ptr)
{
  if (ptr)
    free(ptr);
}
 
 View user's profile Send private message  
Reply with quote Back to top
kbosak
PostPosted: Jun 21, 2008 - 02:21 PM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

Quote:

One thing I think you have missed, though, is that delete operators are supposed to safely do nothing if they're passed a NULL pointer. So your sample implementation of delete should look like this:
Code:

void operator delete(void * ptr)
{
  if (ptr)
    free(ptr);
}

This is a surprise to me. I always believed since 1990 that free(NULL) is always OK, even if I almost never wrote code using this. http://www.winehq.org/pipermail/wine-pa ... 31544.html
says:
ANSI-C Standard:
----------------
The ANSI standard ANSI X3.159-1989 "Programming Language C." specifies
that free(NULL) is a no op.
"free deallocates the space pointed to by p: it does nothing if p is NULL."
Quoted from "The C Programming Language" second edition by Kernighan and
Ritchie with the subtitle "ANSI C".

This would indicate that your protection is superfluous.
BTW for nitpickers that like excess safety, the code should be:
Code:
if(ptr!=NULL)
{
    free(ptr);
}

because (oh there are long and useless discussions about that) NULL dont have to be 0 numerically.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Lajon
PostPosted: Jun 21, 2008 - 05:03 PM
Posting Freak


Joined: Mar 12, 2004
Posts: 1177
Location: Linköping, Sweden

Quote:
because (oh there are long and useless discussions about that) NULL dont have to be 0 numerically.
Actually NULL has to be 0 in C++ (and many C++ programmers avoid using NULL).

http://www.research.att.com/~bs/bs_faq2.html#null
/Lars
 
 View user's profile Send private message  
Reply with quote Back to top
Levenkay
PostPosted: Jun 21, 2008 - 08:34 PM
Resident


Joined: Dec 20, 2007
Posts: 946
Location: Portland, Oregon, USA

kbosak wrote:

This is a surprise to me. I always believed since 1990 that free(NULL) is always OK, even if I almost never wrote code using this. http://www.winehq.org/pipermail/wine-pa ... 31544.html
says:
ANSI-C Standard:
----------------
The ANSI standard ANSI X3.159-1989 "Programming Language C." specifies
that free(NULL) is a no op.
"free deallocates the space pointed to by p: it does nothing if p is NULL."
Quoted from "The C Programming Language" second edition by Kernighan and
Ritchie with the subtitle "ANSI C".

This would indicate that your protection is superfluous.


Wualll, I'll be darned. This is one of those superstitious "safety measure" habits that reinforce themselves; like wearing a Shriners hat to ward off flying squirrel attacks. You wear the hat, and voilla! no squirrels! After awhile, the two seem to be correlated. No particular harm done, but you DO look silly..

I'd always assumed that free()ing NULL was bad medicine, and even have dim recollection of crash dumps from our embedded code when it tried to do so (but we used an extremely old compiler). Anyway, I thought the safety of delete-ing NULL pointers was unique to C++.
 
 View user's profile Send private message  
Reply with quote Back to top
kbosak
PostPosted: Jun 21, 2008 - 10:53 PM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

Quote:
and many C++ programmers avoid using NULL

I am sorry but this is void* argument.
Most programmers are not compiler developers and most compiler developers don't care aboutev erything the Standard says, not to mention about being familiar with avr-g++.

There is more than that:
Code:
malloc(0)

in practice behaves like
Code:
new ptr[0]

The trick is that C++
Code:
new ptr[0]
is standard sanctioned: returning NONNULL, properly aligned pointer for a single element!
Code:
malloc(0)
returning nonnull may or may not be standard.
This helps implementing some dynamic data structures, I believe.
http://gcc.gnu.org/ml/libstdc++/2005-02/msg00167.html
"
The standard defines that allocators
(and operator new) may be asked for zero bytes. They must return an
address different from any other address that they have returned that
haven't since been released. (That disallows returning 0.) Most
implementations treat a call to operator new(0) identically to operator
new(1).
"


Last edited by kbosak on Jun 21, 2008 - 11:02 PM; edited 1 time in total
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
steve17
PostPosted: Jun 21, 2008 - 11:00 PM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

The use of the C++ delete operator in an AVR program is generally a waste of memory, and so is using malloc and free.

It's only when you want to dynamically "churn the heap" that it is required. To put it another way, if the equivalent C program would use malloc and free, then your C++ program would also use them, via new and delete.

Balancing each new with a delete is considered good practice in programs that run on PCs, but it serves no purpose on AVR programs where there is no shutdown except a hardware reset. Actually I question if it has any purpose in embedded programs that run on PCs, but I do it just because it's "good practice".

On an AVR, just "new" everything at startup and run with what you have until the end of time or reset/powerdown, whichever comes first.
 
 View user's profile Send private message  
Reply with quote Back to top
kbosak
PostPosted: Jun 21, 2008 - 11:06 PM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

Quote:
Balancing each new with a delete is considered good practice in programs that run on PCs, but it serves no purpose on AVR programs where there is no shutdown except a hardware reset.

Sorry, short-sighted idea. In fact many efficient linear algebra algorithms require special handling of sparse matrices for max speed. This calls for dynamic data structures. In order to keep implementation of those data structures clean, dynamic memory allocation is necessary. This is the major benefit of using C/C++ over FORTRAN in scientific programming. Using advanced linear algebra/geometry/fitting/optimization algoritms is very popular in many areas, just to mention GPS receivers. GPS receivers tend to run on ARM7, but simpler versions can easily run on AVR.

Let's put it this way: you can get rid of malloc and free completely. But one day, you will write a complex data structure, that uses fixed memory pool. Next day you will find that in runtime this structure hides 20% of innovatory code and 80% of code that immitates malloc's functionality.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
steve17
PostPosted: Jun 22, 2008 - 01:23 AM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

kbosak wrote:
Sorry, short-sighted idea.


So you are saying that any C programmer that doesn't include malloc and free in all his programs is short-sighted?

All I'm saying is C++ doesn't need malloc and free any more than C programs. If a program needs it, use it. Otherwise don't. Of course if you have excessive program memory then it doesn't matter. I rarely find myself in that situation though.
 
 View user's profile Send private message  
Reply with quote Back to top
kbosak
PostPosted: Jun 22, 2008 - 01:39 AM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

steve17 wrote:
kbosak wrote:
Sorry, short-sighted idea.


So you are saying that any C programmer that doesn't include malloc and free in all his programs is short-sighted?

All I'm saying is C++ doesn't need malloc and free any more than C programs. If a program needs it, use it. Otherwise don't. Of course if you have excessive program memory then it doesn't matter. I rarely find myself in that situation though.

I was commetning this:
Quote:
The use of the C++ delete operator in an AVR program is generally a waste of memory, and so is using malloc and free.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Broxbourne
PostPosted: Jun 22, 2008 - 06:29 AM
Hangaround


Joined: Nov 16, 2005
Posts: 341
Location: Calgary, Alberta, Canada

OT:
Quote:
GPS receivers tend to run on ARM7, but simpler versions can easily run on AVR.

That is a somewhat misleading statement. Definition of 'simpler' and 'easily' required.
 
 View user's profile Send private message  
Reply with quote Back to top
kbosak
PostPosted: Jun 22, 2008 - 10:18 PM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

Broxbourne wrote:
OT:
Quote:
GPS receivers tend to run on ARM7, but simpler versions can easily run on AVR.

That is a somewhat misleading statement. Definition of 'simpler' and 'easily' required.

You can use Student-Lockroom programming to achieve the result.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Broxbourne
PostPosted: Jun 23, 2008 - 01:37 AM
Hangaround


Joined: Nov 16, 2005
Posts: 341
Location: Calgary, Alberta, Canada

Quote:
You can use Student-Lockroom programming to achieve the result.

Thanks, I didn't know that.
 
 View user's profile Send private message  
Reply with quote Back to top
kbosak
PostPosted: Jun 23, 2008 - 05:24 PM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

Code:
###############################################################################
# Makefile for the project cpptest
###############################################################################

## General Flags
PROJECT = cpptest
MCU = atmega128
TARGET = cpptest.elf
CC = avr-g++.exe

## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)

## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall   --pedantic  -fno-exceptions  -Wl,--gc-sections  -ffunction-sections     -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ansi
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Wl,-Map=cpptest.map


## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom

HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings


## Include Directories
INCLUDES = -I"I:\ATMEGA\ATMEGA128\..\..\WinAVR-20071221\avr\include\avr"

## Libraries
LIBS = -lc -lm -lprintf_flt -lscanf_flt

## Objects that must be built in order to link
OBJECTS = cpptest.o

## Objects explicitly added by the user
LINKONLYOBJECTS =

## Build
all: $(TARGET) cpptest.hex cpptest.eep cpptest.lss size

## Compile
cpptest.o: ../../cpptest.c
   $(CC) $(INCLUDES) $(CFLAGS) -c  $<

##Link
$(TARGET): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET)
   avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@

%.eep: $(TARGET)
   -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0

%.lss: $(TARGET)
   avr-objdump -h -S $< > $@

size: ${TARGET}
   @echo
   @avr-size -C --mcu=${MCU} ${TARGET}

## Clean target
.PHONY: clean
clean:
   -rm -rf $(OBJECTS) cpptest.elf dep/* cpptest.hex cpptest.eep cpptest.lss cpptest.map


## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)



Code:
#include <avr/io.h>
#include <util/delay.h>

// C++  helpers /////////////////////
#include <stdlib.h>
void * operator new(size_t size);
void operator delete(void * ptr);
void * operator new(size_t size)
{
   return malloc(size);
}
void operator delete(void * ptr)
{
   free(ptr);
}
__extension__ typedef int __guard __attribute__((mode (__DI__)));
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
int __cxa_guard_acquire(__guard *g)
{
   return !*(char *)(g);
}
void __cxa_guard_release (__guard *g)
{
   *(char *)g = 1;
}
void __cxa_guard_abort (__guard *)
{
}
extern "C" void __cxa_pure_virtual(void);
void __cxa_pure_virtual(void)
{
}
//////////////////////////////////////

class CCCP
{
   float a;
   float b;
public:
   CCCP()
   {
   }
   CCCP(float aarg)
   {
      a=aarg;
   }
};

static CCCP * cccp=NULL;
static CCCP cccp_static(1.2);//This doesn't work

int main()
{
   //cccp=new CCCP();//This doesn't work
   DDRC=0xFF;
   for(;;)
   {
      PORTC=0xFF;
      _delay_ms(50);
      PORTC=0x00;
      _delay_ms(50);
   }
   return 0;
}


Code:
Build started 23.6.2008 at 16:25:05
avr-g++.exe -I"I:\ATMEGA\ATMEGA128\..\..\WinAVR-20071221\avr\include\avr"  -mmcu=atmega128 -Wall   --pedantic  -fno-exceptions  -Wl,--gc-sections  -ffunction-sections     -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enu
ms -ansi -MD -MP -MT cpptest.o -MF dep/cpptest.o.d  -c  ../../cpptest.c

../../cpptest.c:51: warning: 'cccp' defined but not used
avr-g++.exe: --gc-sections: linker input file unused because linking not done
avr-g++.exe -mmcu=atmega128 -Wl,-Map=cpptest.map cpptest.o    -lc -lm -lprintf_flt -lscanf_flt  -o cpptest.elf
avr-objcopy -O ihex -R .eeprom  cpptest.elf cpptest.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex cpptest.elf cpptest.eep || exit 0
avr-objdump -h -S cpptest.elf > cpptest.lss

AVR Memory Usage
----------------
Device: atmega128

Program:     900 bytes (0.7% Full)
(.text + .data + .bootloader)

Data:         18 bytes (0.4% Full)
(.data + .bss + .noinit)


Build succeeded with 1 Warnings...


Code:
Archive member included because of file (symbol)

i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_exit.o)
                              i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o (exit)
i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clear_bss.o)
                              cpptest.o (__do_clear_bss)
i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_ctors.o)
                              cpptest.o (__do_global_ctors)
i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_tablejump.o)
                              i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_ctors.o) (__tablejump__)
i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a(malloc.o)
                              cpptest.o (malloc)

Allocating common symbols
Common symbol       size              file

__brkval            0x2               i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a(malloc.o)
__flp               0x2               i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a(malloc.o)

Memory Configuration

Name             Origin             Length             Attributes
text             0x00000000         0x00020000         xr
data             0x00800060         0x0000ffa0         rw !x
eeprom           0x00810000         0x00010000         rw !x
fuse             0x00820000         0x00000400         rw !x
lock             0x00830000         0x00000400         rw !x
signature        0x00840000         0x00000400         rw !x
*default*        0x00000000         0xffffffff

Linker script and memory map

Address of section .data set to 0x800100
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
LOAD cpptest.o
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libprintf_flt.a
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libscanf_flt.a
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libm.a
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a
LOAD i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a

.hash
 *(.hash)

.dynsym
 *(.dynsym)

.dynstr
 *(.dynstr)

.gnu.version
 *(.gnu.version)

.gnu.version_d
 *(.gnu.version_d)

.gnu.version_r
 *(.gnu.version_r)

.rel.init
 *(.rel.init)

.rela.init
 *(.rela.init)

.rel.text
 *(.rel.text)
 *(.rel.text.*)
 *(.rel.gnu.linkonce.t*)

.rela.text
 *(.rela.text)
 *(.rela.text.*)
 *(.rela.gnu.linkonce.t*)

.rel.fini
 *(.rel.fini)

.rela.fini
 *(.rela.fini)

.rel.rodata
 *(.rel.rodata)
 *(.rel.rodata.*)
 *(.rel.gnu.linkonce.r*)

.rela.rodata
 *(.rela.rodata)
 *(.rela.rodata.*)
 *(.rela.gnu.linkonce.r*)

.rel.data
 *(.rel.data)
 *(.rel.data.*)
 *(.rel.gnu.linkonce.d*)

.rela.data
 *(.rela.data)
 *(.rela.data.*)
 *(.rela.gnu.linkonce.d*)

.rel.ctors
 *(.rel.ctors)

.rela.ctors
 *(.rela.ctors)

.rel.dtors
 *(.rel.dtors)

.rela.dtors
 *(.rela.dtors)

.rel.got
 *(.rel.got)

.rela.got
 *(.rela.got)

.rel.bss
 *(.rel.bss)

.rela.bss
 *(.rela.bss)

.rel.plt
 *(.rel.plt)

.rela.plt
 *(.rela.plt)

.text           0x00000000      0x37e
 *(.vectors)
 .vectors       0x00000000       0x8c i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
                0x00000000                __vectors
                0x00000000                __vector_default
 *(.vectors)
 *(.progmem.gcc*)
 *(.progmem*)
                0x0000008c                . = ALIGN (0x2)
                0x0000008c                __trampolines_start = .
 *(.trampolines)
 .trampolines   0x0000008c        0x0 linker stubs
 *(.trampolines*)
                0x0000008c                __trampolines_end = .
 *(.jumptables)
 *(.jumptables*)
 *(.lowtext)
 *(.lowtext*)
                0x0000008c                __ctors_start = .
 *(.ctors)
 .ctors         0x0000008c        0x2 cpptest.o
                0x0000008e                __ctors_end = .
                0x0000008e                __dtors_start = .
 *(.dtors)
                0x0000008e                __dtors_end = .
 SORT(*)(.ctors)
 SORT(*)(.dtors)
 *(.init0)
 .init0         0x0000008e        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
                0x0000008e                __init
 *(.init0)
 *(.init1)
 *(.init1)
 *(.init2)
 .init2         0x0000008e        0xc i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
 *(.init2)
 *(.init3)
 *(.init3)
 *(.init4)
 .init4         0x0000009a       0x1a i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
                0x0000009a                __do_copy_data
 .init4         0x000000b4       0x10 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clear_bss.o)
                0x000000b4                __do_clear_bss
 *(.init4)
 *(.init5)
 *(.init5)
 *(.init6)
 .init6         0x000000c4       0x16 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_ctors.o)
                0x000000c4                __do_global_ctors
 *(.init6)
 *(.init7)
 *(.init7)
 *(.init8)
 *(.init8)
 *(.init9)
 .init9         0x000000da        0x8 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
 *(.init9)
 *(.text)
 .text          0x000000e2        0x4 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
                0x000000e2                __vector_22
                0x000000e2                __vector_28
                0x000000e2                __vector_1
                0x000000e2                __vector_32
                0x000000e2                __vector_34
                0x000000e2                __vector_24
                0x000000e2                __vector_12
                0x000000e2                __bad_interrupt
                0x000000e2                __vector_6
                0x000000e2                __vector_31
                0x000000e2                __vector_3
                0x000000e2                __vector_23
                0x000000e2                __vector_30
                0x000000e2                __vector_25
                0x000000e2                __vector_11
                0x000000e2                __vector_13
                0x000000e2                __vector_17
                0x000000e2                __vector_19
                0x000000e2                __vector_7
                0x000000e2                __vector_27
                0x000000e2                __vector_5
                0x000000e2                __vector_33
                0x000000e2                __vector_4
                0x000000e2                __vector_9
                0x000000e2                __vector_2
                0x000000e2                __vector_21
                0x000000e2                __vector_15
                0x000000e2                __vector_29
                0x000000e2                __vector_8
                0x000000e2                __vector_26
                0x000000e2                __vector_14
                0x000000e2                __vector_10
                0x000000e2                __vector_16
                0x000000e2                __vector_18
                0x000000e2                __vector_20
 .text          0x000000e6        0x0 cpptest.o
 .text          0x000000e6        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_exit.o)
 .text          0x000000e6        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clear_bss.o)
 .text          0x000000e6        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_ctors.o)
 .text          0x000000e6        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_tablejump.o)
 .text          0x000000e6      0x1fc i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a(malloc.o)
                0x000000e6                malloc
                0x00000236                free
                0x000002e2                . = ALIGN (0x2)
 *(.text.*)
 .text.__cxa_guard_acquire
                0x000002e2       0x14 cpptest.o
                0x000002e2                __cxa_guard_acquire
 .text.__cxa_guard_release
                0x000002f6        0x8 cpptest.o
                0x000002f6                __cxa_guard_release
 .text.__cxa_guard_abort
                0x000002fe        0x2 cpptest.o
                0x000002fe                __cxa_guard_abort
 .text.__cxa_pure_virtual
                0x00000300        0x2 cpptest.o
                0x00000300                __cxa_pure_virtual
 .text._Z41__static_initialization_and_destruction_0ii
                0x00000302       0x24 cpptest.o
 .text._GLOBAL__I__Znwj
                0x00000326        0xe cpptest.o
 .text._ZdlPv   0x00000334        0x6 cpptest.o
                0x00000334                operator delete(void*)
 .text._Znwj    0x0000033a        0x6 cpptest.o
                0x0000033a                operator new(unsigned int)
 .text.main     0x00000340       0x30 cpptest.o
                0x00000340                main
 .text.libgcc   0x00000370        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_exit.o)
 .text.libgcc   0x00000370        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clear_bss.o)
 .text.libgcc   0x00000370        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_ctors.o)
 .text.libgcc   0x00000370        0xc i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_tablejump.o)
                0x00000374                __tablejump__
                0x00000370                __tablejump2__
                0x0000037c                . = ALIGN (0x2)
 *(.fini9)
 .fini9         0x0000037c        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_exit.o)
                0x0000037c                exit
                0x0000037c                _exit
 *(.fini9)
 *(.fini8)
 *(.fini8)
 *(.fini7)
 *(.fini7)
 *(.fini6)
 *(.fini6)
 *(.fini5)
 *(.fini5)
 *(.fini4)
 *(.fini4)
 *(.fini3)
 *(.fini3)
 *(.fini2)
 *(.fini2)
 *(.fini1)
 *(.fini1)
 *(.fini0)
 .fini0         0x0000037c        0x2 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_exit.o)
 *(.fini0)
                0x0000037e                _etext = .

.data           0x00800100        0x6 load address 0x0000037e
                0x00800100                PROVIDE (__data_start, .)
 *(.data)
 .data          0x00800100        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
 .data          0x00800100        0x0 cpptest.o
 .data          0x00800100        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_exit.o)
 .data          0x00800100        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clear_bss.o)
 .data          0x00800100        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_ctors.o)
 .data          0x00800100        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_tablejump.o)
 .data          0x00800100        0x6 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a(malloc.o)
                0x00800102                __malloc_heap_start
                0x00800104                __malloc_heap_end
                0x00800100                __malloc_margin
 *(.data*)
 *(.rodata)
 *(.rodata*)
 *(.gnu.linkonce.d*)
                0x00800106                . = ALIGN (0x2)
                0x00800106                _edata = .
                0x00800106                PROVIDE (__data_end, .)

.bss            0x00800106        0xc load address 0x00000384
                0x00800106                PROVIDE (__bss_start, .)
 *(.bss)
 .bss           0x00800106        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o
 .bss           0x00800106        0x8 cpptest.o
 .bss           0x0080010e        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_exit.o)
 .bss           0x0080010e        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_clear_bss.o)
 .bss           0x0080010e        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_ctors.o)
 .bss           0x0080010e        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/avr5\libgcc.a(_tablejump.o)
 .bss           0x0080010e        0x0 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a(malloc.o)
 *(.bss*)
 *(COMMON)
 COMMON         0x0080010e        0x4 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5\libc.a(malloc.o)
                0x0080010e                __brkval
                0x00800110                __flp
                0x00800112                PROVIDE (__bss_end, .)
                0x0000037e                __data_load_start = LOADADDR (.data)
                0x00000384                __data_load_end = (__data_load_start + SIZEOF (.data))

.noinit         0x00800112        0x0
                0x00800112                PROVIDE (__noinit_start, .)
 *(.noinit*)
                0x00800112                PROVIDE (__noinit_end, .)
                0x00800112                _end = .
                0x00800112                PROVIDE (__heap_start, .)

.eeprom         0x00810000        0x0
 *(.eeprom*)
                0x00810000                __eeprom_end = .

.fuse
 *(.fuse)
 *(.lfuse)
 *(.hfuse)
 *(.efuse)

.lock
 *(.lock*)

.signature
 *(.signature*)

.stab           0x00000000      0x414
 *(.stab)
 .stab          0x00000000      0x414 i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o

.stabstr        0x00000000       0x5f
 *(.stabstr)
 .stabstr       0x00000000       0x5f i:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr5/crtm128.o

.stab.excl
 *(.stab.excl)

.stab.exclstr
 *(.stab.exclstr)

.stab.index
 *(.stab.index)

.stab.indexstr
 *(.stab.indexstr)

.comment
 *(.comment)

.debug
 *(.debug)

.line
 *(.line)

.debug_srcinfo
 *(.debug_srcinfo)

.debug_sfnames
 *(.debug_sfnames)

.debug_aranges
 *(.debug_aranges)

.debug_pubnames
 *(.debug_pubnames)

.debug_info
 *(.debug_info)
 *(.gnu.linkonce.wi.*)

.debug_abbrev
 *(.debug_abbrev)

.debug_line
 *(.debug_line)

.debug_frame
 *(.debug_frame)

.debug_str
 *(.debug_str)

.debug_loc
 *(.debug_loc)

.debug_macinfo
 *(.debug_macinfo)
OUTPUT(cpptest.elf elf32-avr)
LOAD linker stubs


After noticing some problems with my larger project, moved back to make to retest simpler code. With all our modifications, the code always hangs! I am surprised. I have tested the code some half a year ago. Creating global instances of classes works only if there are lots of code... Then it works. It means the classes are instantiated in some magic memory areas, overlapping innocent global variables (?).
I have retested so many other details, optimisation options etc. What went wrong?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
kbosak
PostPosted: Jun 23, 2008 - 07:36 PM
Hangaround


Joined: Jan 30, 2008
Posts: 168
Location: Wroclaw, Poland

Proposal: alternatively, since our program in G++ for AVR is fully single-threaded by nature, we can define -fno-threadsafe-statics instead of defining __cxa_guard_acquire and friends.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
TimothyBaldwin
PostPosted: Jun 27, 2008 - 10:36 AM
Newbie


Joined: Jun 27, 2008
Posts: 14


kbosak wrote:
Proposal: alternatively, since our program in G++ for AVR is fully single-threaded by nature, we can define -fno-threadsafe-statics instead of defining __cxa_guard_acquire and friends.


That is bad assumption, one can write multi-threaded C++ AVR programs, and even without threads there is a possibility of for recursion involving ISRs. If such situations can occur in our program __cxa_guard_acquire and friends would need to protect against this.
 
 View user's profile Send private message  
Reply with quote Back to top
Lajon
PostPosted: Jun 28, 2008 - 10:02 AM
Posting Freak


Joined: Mar 12, 2004
Posts: 1177
Location: Linköping, Sweden

Quote:
That is bad assumption, one can write multi-threaded C++ AVR programs, and even without threads there is a possibility of for recursion involving ISRs. If such situations can occur in our program __cxa_guard_acquire and friends would need to protect against this.
True, but note that the __cxa_guard* implementation above is a minimum (dummy) implementation - it does not add any thread safety.
/Lars
 
 View user's profile Send private message  
Reply with quote Back to top
atomicdog
PostPosted: Jun 28, 2008 - 11:16 AM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

I think fno-threadsafe-statics is a good solution for a default setting since a lot of programs written for AVR aren't multi-threaded. The only way I see this effecting an ISR is if someone is calling a function in the ISR in which case they could compile that one function without fno-threadsafe-statics and then write their own __cxa_guard* functions. I suppose there are more cases but I think needing __cxa_guard* is more of a special case.

_________________
~~John
TWI C source code
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
atomicdog
PostPosted: Jul 06, 2008 - 09:15 AM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

Reducing C++ Code Bloat

_________________
~~John
TWI C source code
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
tomcat_1974
PostPosted: Oct 10, 2008 - 11:49 AM
Rookie


Joined: Oct 27, 2007
Posts: 34
Location: Norway

TFrancuz wrote:
I use AVR Studio, which is almost working with c++. Almost, because you must manually in project->Configuration options->Custom options set instead of avr-gcc avr-c++.exe to compile any of your c++ files. Just changing the extension to cpp/hpp doesn't work.


Correct me if I'm wrong, but it seems to me that if I create my source file with an upper case C extension instead of lower case AVR-GCC will compile as C++ without the editing mentioned above.

I'm not sure if renameing from .c to .C will work. The file must probably be created with upper case from the beginning.

_________________
JHJ
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 10, 2008 - 12:03 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

You probably need to "remove file(s) from project..", rename to .C and the "add existing source file(s)..." to be sure that Studio makes the right decision about invoking the C++ compiler but otherwise, yes, it sounds like that would be the easy answer.

Cliff

(previously there's been reports of folks having problems the other way round where they've inadvertently used a MAIN.C or something in Studio and ended up getting C++ warnings - so it should work)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
sternst
PostPosted: Oct 10, 2008 - 01:35 PM
Raving lunatic


Joined: Jul 23, 2001
Posts: 2470
Location: Osnabrueck, Germany

clawson wrote:
You probably need to "remove file(s) from project..", rename to .C and the "add existing source file(s)..." ...

Yes, because Studio refuses changing the extension.

Quote:
... to be sure that Studio makes the right decision about invoking the C++ compiler

No, Studio will still call avr-gcc.
avr-gcc itself makes the decision to use the C++-compiler due to the file name (.C) on the command line.

_________________
Stefan Ernst
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 10, 2008 - 02:17 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:
No, Studio will still call avr-gcc.
avr-gcc itself makes the decision to use the C++-compiler due to the file name (.C) on the command line.

Thanks for stating the obvious but I know that - the whole point here was to prevent the need to edit the field in Studio where it invokes avr-gcc.exe

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
steve17
PostPosted: Oct 10, 2008 - 06:09 PM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

Hmmm, I don't understand but then I don't use AVR Studio to do my builds.

For the record, I find files ending in .cpp get compiled as if they were C++ files, and files ending in .c are compiled as C files.

I never tried .C and I never heard of .hpp, just .h.

My makefile calls avr-gcc.exe
 
 View user's profile Send private message  
Reply with quote Back to top
robindegen
PostPosted: Oct 14, 2008 - 02:44 PM
Newbie


Joined: Oct 14, 2008
Posts: 1


Upon converting my code to the C++ project i came across 1 warning about my custom lcd characters:

Code:

static const PROGMEM unsigned char customCharacters[] =
{
   //Character 0
   0b00000,
   0b01110,
   0b10001,
   0b11111,
   0b10001,
   0b10001,
   0b01110,
   0b00000,

   //Character 1
   0b00000,
   0b11111,
   0b10000,
   0b10000,
   0b10000,
   0b10000,
   0b11111,
   0b00000
};


Gives: "warning: only initialized variables can be placed into program memory area"

Any thoughts?
 
 View user's profile Send private message  
Reply with quote Back to top
kmr
PostPosted: Oct 14, 2008 - 02:50 PM
Raving lunatic


Joined: Apr 01, 2004
Posts: 3812
Location: New Mexico

It's a known bug: http://www.avrfreaks.net/index.php?name ... nitialized

Also, doing a web search with the error message will give you links to other reports about that as well as a link to the bug report on the avr-gcc bug tracker.

_________________
Kevin Rosenberg
http://b9.com
http://kevin.hypershots.com
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
Trontron
PostPosted: Nov 02, 2008 - 09:14 PM
Newbie


Joined: Nov 02, 2008
Posts: 1


I think I've just found another gotcha in AVR Studio, which hopefully some people may find useful?. (It took me a few hours of Google searching and guessing before I hit on the idea of what was going wrong).

Apparently AVR Studio doesn't support .CPP files. The files need to be called ".c" and not ".cpp" (even though the code in the file is C++).

When CPP files are used, the AVR Studio (V4.14 build 589) fails to generate compile instructions in the makefile for the object file, e.g. it looked like this in the makefile...
## Compile
##Link

But when the .CPP files were renamed to .C it then generated a makefile that looked like this (and compiled ok)...
## Compile
Wire.o: ../Wire.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

ArrayDisplay.o: ../ArrayDisplay.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

LCD1.o: ../LCD1.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

lcd.o: ../lcd.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

twi.o: ../twi.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

VirtualScreen.o: ../VirtualScreen.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<

##Link

In hindsight, its very easy when you know that's what you have to do, but I've not seen it mentioned anywhere, not to call files CPP (which is what I usually use for other non-avr compilers like PC etc.).

I don't know if this is a bug or by design, but anyway, I thought this may help someone? ... (It would have helped me! Razz).
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Nov 02, 2008 - 10:38 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

I'll speculate:

AVR Studio is not case sensitive, and thus recognices both .c and .C as a file type that it thinks it can handle.

WinAVR/avr-gcc on the other hand IS case sensitive as it stems from the GNU/U*ix world, and there are three file types that I've seen used for C++ source files: .C (not to be confused with .c), .cpp and .cxx .

Thus AVR Studio thinks of your source files as C sources, but then passes them to avr-gcc which treats them as C++ source files. (The test you can make is to try to place C++ code in a .c source file, add it to Studio and see what happends. I'll bet that avr-gcc will spit it out.)

Although the approach you have taken seems to work it has the disadvantage that you can not set specific compiler flags for C++ sources different from those you set for C sources (unless you specify them for each file individually). In this sense AVR Studio does not support C++. If you will need special treatment for C++ sources then there is no other way that I know of than to write your own makefile and feed that to AVR Studio.

Here's some gcc documentation that seem to support my speculation:
Quote:
C++ source files conventionally use one of the suffixes `.C', `.cc', `.cpp', `.CPP', `.c++', `.cp', or `.cxx'[...]. GCC recognizes files with these names and compiles them as C++ programs even if you call the compiler the same way as for compiling C programs [...]


And when you are ready for it, learning make is actually not that hard. The documentation is very good: http://www.gnu.org/software/make/manual/

HTH!
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Jaques
PostPosted: Jan 30, 2009 - 02:20 PM
Rookie


Joined: Jun 06, 2008
Posts: 22


I recently faced a situation were I needed a Singleton-like (http://en.wikipedia.org/wiki/Singleton_pattern) object.

Code:

template< uint8_t BitNo >
ProtocolHandler< BitNo > &   ProtocolHandler< BitNo >::Machine( )
{
   static ProtocolHandler< BitNo >   machine;
   return   machine;
}


When compiling such code, I was taunted by this error:
Quote:
undefined reference to `atexit'


After some googling, I found this thread:
http://www.embeddedrelated.com/usenet/embedded/show/88449-1.php

Wich provides an easy solution that I want to share here to complete the "micro howto".

Code:

///   MCU would never "exit", so atexit can be dummy.
extern "C" void   atexit( void ) { }


And if I am here to collaborate, there are two other functions that can be usefull if one wants to avoid AVR-libc dynamic memory management concerns:

Code:

/// Placement new for allocating the object inside a given memory buffer.
void *   operator new( size_t, void * const buff )      {   return   buff;   }

/// Placement delete called automatically on "placement new" failure.
void   operator delete( void * p, void * const buff )   {   }


Quote:
The use of the C++ delete operator in an AVR program is generally a waste of memory, and so is using malloc and free.


I don't think so.
Dynamic memory management is just meant to avoid memory waste.
In situations were the processing is predictive enough and memory consumption is high, I can control when my data is going to use memory, instead of leaving them in RAM all the time - this data can even not fit, so the management is a must.
Of course the management system takes a little memory for itself, but it is generally a small portion of the heap (unless one plan to use the heap for allocating several single bytes, what is definitely not wise...)
 
 View user's profile Send private message  
Reply with quote Back to top
steve17
PostPosted: Jan 30, 2009 - 06:03 PM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

If the equivalent C program would benefit from using dynamic memory allocation, then the C++ program would also. But I've not encountered any embedded programs where that was the case.

Malloc and free use the heap a little less efficiently and inclusion of the malloc and free code also uses a considerable amount of program memory.

There is nothing in C++ that requires malloc and free, although it might seem that way. That's because most C++ programs run on PCs, where malloc and free are readily available, and most C++ programs are not embedded and do make good use of dynamic memory.

Some people recommed not dynamically allocating and freeing of memory while an embedded program is running. Maybe the heap software today is good enough, but that wasn't always the case.

I worked on a large and expensive embedded program that ran on PCs and had around 45 threads. We could run most of the software on our desktop machines but the customer, the Department of Defense, got ruggedized machines with a compact PCI chassis.

The rule was to allocate all memory at startup, and delete everything at shutdown. The shutdown thing was for the convenience of the programmers. The customer shut it down by powering it off. We used malloc and free, via new and delete, because there was no reason not to do so. These funcions were there and there was plenty of memory. But again, we only used them at startup and shutdown.
 
 View user's profile Send private message  
Reply with quote Back to top
nigelb
PostPosted: Mar 25, 2009 - 04:05 PM
Newbie


Joined: May 25, 2007
Posts: 1


Not wanting to appear dumb - just starting out on my first serious C++ project - but what is 'Student-Lockroom' programming?
 
 View user's profile Send private message  
Reply with quote Back to top
dpharris
PostPosted: Mar 25, 2009 - 05:27 PM
Hangaround


Joined: Sep 10, 2002
Posts: 118
Location: Victoria, BC, CANADA

Do you have a reference to "Student-Lockroom programming" -- Google only brings up this thread.

Thanks.
 
 View user's profile Send private message  
Reply with quote Back to top
Ali_dehbidi
PostPosted: Mar 28, 2009 - 07:59 AM
Posting Freak


Joined: Dec 22, 2005
Posts: 1281
Location: shiraz , iran

Dear freaks

any body has a sample project in c++.containing all of stuff like makefile and main c file.
please post it.

_________________
I love Digital
and you who involved in it!
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Mar 28, 2009 - 08:35 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Quote:
main c file

Why the need for a main C file? As you can't create and use C++ objects from C code this will add an extra layer of calls to the code.

The somewhat simplified truth is that C++ can call C but not the other way around. The slightly more complicated version is: If your main is in a C source file it has "C linkage". It can call a function in a C++ file but that called function also has to have C linkage (which you get by using the extern "C" language construct). This function in turn can create and use C++ objects.

I seems you want a small C/C++ demo, and having a main in C rather than C++ only makes that demo more complicated.

Could you do with a project with a main function in a C++ file?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Ali_dehbidi
PostPosted: Mar 29, 2009 - 07:21 AM
Posting Freak


Joined: Dec 22, 2005
Posts: 1281
Location: shiraz , iran

i mean the c++ main file sorry for that.all i want is a simple c++ demo.

_________________
I love Digital
and you who involved in it!
 
 View user's profile Send private message  
Reply with quote Back to top
steve17
PostPosted: Mar 30, 2009 - 02:45 AM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

This will blink the LED on my Olimex P40 board.


Last edited by steve17 on Mar 31, 2009 - 11:48 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
Ali_dehbidi
PostPosted: Mar 31, 2009 - 07:04 AM
Posting Freak


Joined: Dec 22, 2005
Posts: 1281
Location: shiraz , iran

thnaks a lot!

_________________
I love Digital
and you who involved in it!
 
 View user's profile Send private message  
Reply with quote Back to top
JSkywalker
PostPosted: May 04, 2009 - 06:35 PM
Newbie


Joined: May 04, 2009
Posts: 7


hey.. i've got a cuestion.. does the c++ compiler support the implicit convertions for integrated types like strings, integers, etc..? For example, when a function argument should be a string, and i pass it a integer, can the convertion be done by the compiler?


Thanks
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: May 04, 2009 - 09:21 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Quote:

For example, when a function argument should be a string, and i pass it a integer, can the convertion be done by the compiler?

Assuming that you by string mean a char * then the answer is no. This is not a pecularity of the avr-gcc compiler. This is how the C++ language is defined.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JSkywalker
PostPosted: May 05, 2009 - 07:32 PM
Newbie


Joined: May 04, 2009
Posts: 7


[quote="JohanEkdahl"]
Quote:

Assuming that you by string mean a char * then the answer is no. This is not a pecularity of the avr-gcc compiler. This is how the C++ language is defined.


Thanks for the answer.. I'm using the c++.exe file to compile my program instead of avr-gcc.exe (just like TFrancuz says at the fist comment)so it's c++ language(i guess.. Rolling Eyes ), and it still doesn't work.. so, is there a way to make it able to work with implicit convertions?


..thanks
 
 View user's profile Send private message  
Reply with quote Back to top
JSkywalker
PostPosted: May 05, 2009 - 08:09 PM
Newbie


Joined: May 04, 2009
Posts: 7


hey.. has anybody had a problem with strings (char *)? 'cause i'm trying strlen, strcat and itoa.. and they just dont work!!!! maybe there's something i'm doing wrong
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 05, 2009 - 09:01 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

and they just dont work

Shows as small a program as you possibly can that demonstrates them not working as far as you are concerned.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: May 05, 2009 - 09:18 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Quote:

so it's c++ language(i guess.. Rolling Eyes ), and it still doesn't work..

It does not matter if it is C or C++. There is no implicit conversion from int to char * in neither language. What makes you think there is?

And AFAIK the language is determined by the filename extension of the source file. Not that it matters in this case, though. You can easily determine if the compiler thinks it is a C or a C++ file that you are sending to it. Just throw a very simple class into it, eg
Code:
class Test
{
public:
   int i;
};

and if it barfs over that then it is C, not C++. There are other methods, including testing if CPLUSPLUS (or some such, I really don't recall and don't have the energy to search the correct preprocessor symbol name out) is defined.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: May 06, 2009 - 12:42 AM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6144
Location: Great Smokey Mountains.

Johan,

I want to drive my Jeep to Tahiti, but Jeeps get pretty poor gas mileage and I'm afraid I won't be able to make it from California to Hawaii so can you tell me how to flag down tankers along the way?

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: May 06, 2009 - 06:55 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

I totally lost you there, Joe. Honestly. Knowing you (netwise), quite good I think, I suppose there is some really to-the-point wittiness or sarcasm somewhere in there regarding some mistake I made, but I cant spot it.

I have tried Googling "Smileys Jeep gas shortage bottom Pacific" with and without "driver nuts" but came up with nothing..

Help this stupid Swede out, and give me a clue. Please?!
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: May 06, 2009 - 04:29 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6144
Location: Great Smokey Mountains.

Johan,

It wasn't aimed at you, but an attempt to wisecrack about getting into details like char * while using the wrong vehicle for the job in the first place. Some people want to use C++ as C without studying the basics or the philosophical differences between procedural versus object oriented programming. Not pointed at you, just a poor joke about other folks who want to use C++ when they don't seem to know anything about why one would choose C++ over C.

Sorry,
Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JSkywalker
PostPosted: May 06, 2009 - 05:14 PM
Newbie


Joined: May 04, 2009
Posts: 7


smileymicros wrote:
Johan,

It wasn't aimed at you, but an attempt to wisecrack about getting into details like char * while using the wrong vehicle for the job in the first place. Some people want to use C++ as C without studying the basics or the philosophical differences between procedural versus object oriented programming. Not pointed at you, just a poor joke about other folks who want to use C++ when they don't seem to know anything about why one would choose C++ over C.

Sorry,
Smiley


So.. i guess you're talking about me.. are not you? And i wonder, why does a philosopher (haha) say that other folks don't know anything about programming paradigms without asking them first?


Before you say anything, try to be sure... this is a tip for life
 
 View user's profile Send private message  
Reply with quote Back to top
JSkywalker
PostPosted: May 06, 2009 - 05:24 PM
Newbie


Joined: May 04, 2009
Posts: 7


Quote:

Shows as small a program as you possibly can that demonstrates them not working as far as you are concerned.


i've overloaded the << operator to work with a class lcd and strings like: lcd<<"something";

in the function definition i've tried to use the strlen function like this:

Lcd & Lcd::operator<<(char *s)
{

...

int length = strlen(s);

...

}


and i use the variable length at a for loop to print the string.. but it does not make any loop
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: May 06, 2009 - 08:00 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

OK, I'd actually like to see a bit more, eg the whole of the implementation of the operator overload, a declaration/creation of an Lcd object and a call/use of the operator.

I dont have AVR Studio handy right now (just taking a break with working overtime). But I did pull together this small test in MS VC++ which works like a charm. I of-course simulate sending the characters to the LCD proper with a call to putchar, but apart from that I suppose I am close to what you have?
Code:
// JSkywalker.cpp

#include "stdafx.h"
#include <string>

class Lcd
{
public:
   Lcd & operator<<(char * s)
   {
      for (size_t i= 0; i<strlen(s); i++) {
         putchar(s[i]);
      }
      return *this;
   }
};

int _tmain(int argc, _TCHAR* argv[])
{
   Lcd lcd;
   lcd << "Hello overload";
   return 0;
}


I will try something similar in AVR Studio when I get home, if I'm not too tired.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: May 06, 2009 - 08:10 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Quote:

It wasn't aimed at you, but an attempt to wisecrack about getting into details like char * while using the wrong vehicle for the job in the first place.

That's okay, Joe. I wasn't upset but rather in wisecrack mode myself. Still, and you know this, my position is that many (dare I say "most"?) times C++ is just as good vehicle as C for embedded systems. We might then be in a situation where someone uses an appropriate vehicle but does not know why (bad), and maybe how to operate it (worse).

Please note that I am not accusing JSkywalker being in either situation, but merely dwelling on Joes scenario in general!

Quote:

Sorry

No need to be, Joe. If you actually succeed in hurting me for real, we will settle that in a PM or two. No need for old grumpy beards to fight such things out in public. Anfd you haven't even gotten close yet. Wink
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: May 06, 2009 - 09:48 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Here's what what I did:

1) Put the Lcd class in a C++ file, and in that file also put a global function test() that exercises the overloaded operator and gave that function C linkage (so that it can be called from main() that is in a C file):
Code:
//JSkywalker.cpp
#include <avr/io.h>
#include <string.h>

class Lcd
{
public:
   Lcd & operator<<(char * s)
   {
      for (size_t i= 0; i<strlen(s); i++) {
         PORTB=s[i];
      }
      return *this;
   }
};

extern "C" void test()
{
   Lcd lcd;
   lcd << (char *)"Hello overload";
}


2) wrote a simple main.c, containing main() that calls test(). No, I didnt bother to create a header file for the test() function. Call me sloppy if you like...
Code:
//main.c
#include <avr/io.h>

void test();

int main(void)
{
   test();

   return 0;
}


3) Fiddled a bit with the makefile before I got it right (it's been a while since my last experiments with C++ on AVRs).

4) Built the whole shebang, started up AVR Studio, loaded the ELF file and stepped through the code. I see it looping inside the overloaded Lcd::operator<< outputting the chars to PORTB one after the other.

A total success as far as I am concerned.

So now tell us in similar detail, and preferrably in a likewise minimal test/demo project, what your problem is.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: May 07, 2009 - 01:04 AM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6144
Location: Great Smokey Mountains.

Never mind

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: May 07, 2009 - 09:29 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Quote:

Never mind

What?
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JSkywalker
PostPosted: May 13, 2009 - 04:11 AM
Newbie


Joined: May 04, 2009
Posts: 7


All strings r working.. i've debugged it and i saw it works.. thanks for the help
 
 View user's profile Send private message  
Reply with quote Back to top
abrecht
PostPosted: Jun 02, 2009 - 12:46 AM
Newbie


Joined: May 13, 2009
Posts: 4


Hello Anyone,
doing embedded stuff with winCE for some time, now i'm back to 8 bit uC but won't miss c++ anymore. Thanks to a few hints from this great thread i'm quite happy now with AVRStudio and C++. Debugging is not as comfortable as with VisualStudio, but in former time we were happy when we had a console for debug output.

Now i would like to do some things like wrapping the peripherals i work with in C++ classes, or create waitable events and stuff.

Therefore it would be necessary to hook the handler methods of some objects to certain ISR vectors.
The only approach coming to my mind would be a dispatcher class. I could create some ugly file with all the ISR handlers in it, which call a static function of this dispatcher class, forwarding some ID or the current IP value to it, to tell which ISR was firing. Objects could then register their instance pointer and the address of a handler method to a global object of that dispatcher class.

This is of course ugly and absolutely not uC-like. Probably you cracks can tell a much better way. Any ideas?

Regards
Manuel
 
 View user's profile Send private message  
Reply with quote Back to top
atomicdog
PostPosted: Jun 02, 2009 - 01:31 AM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

There has been a few discussions here and at avr-libc and avr-gcc lists about ISR's and C++

http://jennaron.com.au/avr/classinterrupts.html

http://lists.gnu.org/archive/html/avr-gcc-list/
http://lists.gnu.org/archive/html/avr-libc-dev/

_________________
~~John
TWI C source code
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
abrecht
PostPosted: Jun 02, 2009 - 03:31 PM
Newbie


Joined: May 13, 2009
Posts: 4


Thank you for those links, the first one already pretty much answers my questions.

Manuel
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 02, 2009 - 08:30 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Although not AVR or avr-gcc specific, these might also be interesting reads:
http://www.embedded.com/9900245?_requestid=232727
http://www.embedded.com/columns/program ... tid=233499
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
steve17
PostPosted: Jun 03, 2009 - 12:00 AM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

abrecht wrote:
i'm quite happy now with AVRStudio and C++. Debugging is not as comfortable as with VisualStudio,
Yes, the AVRStudio debugger says all class member data is "out of scope". That could be considered "not so comfortable". Smile

Still, for me C++ is the only way to go.
 
 View user's profile Send private message  
Reply with quote Back to top
quantum-leap
PostPosted: Aug 16, 2009 - 07:59 PM
Newbie


Joined: Nov 20, 2007
Posts: 9
Location: Chapel Hill, NC

I belive that readers of this forum would appreciate some concrete, AVR-specific examples that would allow for a quantitative comparison between C and C++ implementation of essentially the same problem specification.

To draw a fair comparison, one would need two equivalent AVR projects designed in object-oriented way, one in C and the other in C++. Otherwise, one would compare different programming paradigms and designs, not the direct impact of the programming language and compiler.

In this context, I believe that the projects at:

http://www.state-machine.com/avr

provide a unique opportunity to quantitatively compare the impact of C++. Specifically, the "QDK/C AVR-GNU" and "QDK/C++ AVR-GNU" projects use object-oriented designs with classes and single inheritance. They are both based on a small state-machine framework on top of which runs the classic "Dining Philosophers Problem" test application consisting of five Philosopher state machines and one Table state machine. The framework code consists mostly of a conditional logic to execute hierarchical state machines as well as an event queue, a timer module, and a tiny preemptive kernel. The Dining Philosophers application consists of state machines. I believe that this code is quite representative for typical projects that run on AVRmega MCUs. (These specific projects have been compiled for the AVR Butterfly board with the AVRmega169 MCU.)

So, here is the quantitative size comparison for the WinAVR/avr-gcc compiler (data taken from the map files in the release configuration):

Code:
                | "QDK/C AVR-GNU"  | "QDK/C++ AVR-GNU"
----------------+------------------+--------------------
Code size (ROM) |   5454 bytes     |  6200 bytes (+14%)
----------------+------------------+--------------------
Data size (RAM) |     48 bytes     |    88 bytes (+80%)

The C++ code uses the "Embedded C++" subset, which avoids exceptions and templates leaving basically only the object-oriented features (classes, inheritance, and virtual functions). Also, the C++ code is not using new and delete (and the C code is not using malloc and free).

The code size increase of 14% of C++ compared to C is typical, although for other compilers I've seen an increase of only about 5% for the same "Dining Philosophers" project.

However, the data size increase of 40 bytes is unusually high. I would expect an increase of some 12 bytes for the virtual pointers stored inside the 6 state machine objects that have virtual tables. The mapfiles indicate that the WinAVR compiler allocates virtual tables in the data space (RAM), which is not optimal because v-tables are synthesized at compile time and can typically be stored in ROM. I'm not aware of any compiler options for WinAVR to control placement of virtual tables. Perhaps someone knows how to force the v-tables into the program space (ROM)?

Finally, I hope that my post could help dispel the widespread belief that you can't do object-oriented (or at least object-based) programming in C. In fact, it is quite easy to implement classes and single inheritance in C. I've blogged about it at EmbeddedGurus.net:

http://www.embeddedgurus.net/state-spac ... -in-c.html

_________________
Miro Samek
www.state-machine.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: Aug 16, 2009 - 08:08 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Quote:

The mapfiles indicate that the WinAVR compiler allocates virtual tables in the data space (RAM), which is not optimal because v-tables are synthesized at compile time and can typically be stored in ROM. I'm not aware of any compiler options for WinAVR to control placement of virtual tables. Perhaps someone knows how to force the v-tables into the program space (ROM)?


AFAIK there is no way to get avr-gcc to store the V-tables in ROM (ie in flash memory). This is a performance hit that you get when using C++ (with the avr-gcc compiler) on AVRs.


Thank you for this post. I'll try to find some time to analyze in more detail what constitutes the increases in code and data size.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
steve17
PostPosted: Aug 17, 2009 - 12:24 AM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2564
Location: New York State

I took a quick look at the code. It seems it wasn't written as a C++ program. I'd guess it was either a quick copy from C code or it was written by a C programmer masquerading as a C++ programmer. I don't know how that would affect the code size.

I'm reminded of a task switching kernel we used at my previous job. It was taken from Dr. Dobbs Journal. It was written in the C language but it was obviously written by a Fortran programmer. I re-wrote every line of code, which typically happens when I use someone elses code. It was buggy too. It suffered from the "priority inversion" problem. Once fixed and cleaned up, it was pretty neat.
 
 View user's profile Send private message  
Reply with quote Back to top
MikkoSaarisalo
PostPosted: Mar 07, 2010 - 03:11 PM
Newbie


Joined: Mar 07, 2010
Posts: 1


Hi All,

I browsed through this thread and failed to find source files where this discussion would be captured. Are those available anywhere? I could do a shot and upload something I have been using - based on the topmost parts of this thread. However, I am rather new in C++ and especially in embedded environment. I am not sure how *right* my files would be and certainly would appreciate more experienced developers to confirm or fix the files to a good shape.

It would also be nice to have these files available on the first post or other easily found location.

-mikko
 
 View user's profile Send private message  
Reply with quote Back to top
atomicdog
PostPosted: Mar 08, 2010 - 12:45 AM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

When just starting out with C++ and embedded programming it's easier to start with single thread programs. So using the -fno-threadsafe-statics switch will allow you to bypass the __cxa_guard stuff for a while. With embedded systems __cxa_guard wont be standard and will depend a lot on how the program is implemented. The best you can do is create stub files that can be filled in later when the specifics of the program/RTOS are known.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
migit128
PostPosted: Apr 22, 2010 - 03:48 PM
Newbie


Joined: Apr 09, 2010
Posts: 11


which c++ compiler should we be using? the G++ one or C++ one?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 22, 2010 - 03:57 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

Just invoke avr-gcc, if the source files have a .cc or .C extension the C++ compiler will be invoked.

As you can see it doesn't actually matter which is actually used:
Code:
C:\WinAVR-20100110\bin>fc /b "avr-c++.exe" "avr-g++.exe"
Comparing files avr-c++.exe and AVR-G++.EXE
FC: no differences encountered

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
vandenzel
PostPosted: Nov 19, 2010 - 02:10 AM
Newbie


Joined: Jun 20, 2007
Posts: 3
Location: Nijmegen, Netherlands

Whatever discussed here, it seems the people at Arduino[1] are able to make C++ work (at least up to some point). Maybe their code can provide some pointers.

--
Alex.

[1] I hope I am allowed to use the A-word in this forum Smile
 
 View user's profile Send private message  
Reply with quote Back to top
kscharf
PostPosted: May 15, 2012 - 02:22 PM
Posting Freak


Joined: Aug 04, 2004
Posts: 1822
Location: Davie, FL

Has anybody got this to work with avr studio 5?
I couldn't find a way to configure a project for C++. I started a new project and added C++ files to it, but they didn't compile, they weren't even INCLUDED in the list of files to BE compiled, even though they were added to the project.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 15, 2012 - 02:36 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

Have you tried AS6? It fixes a lot of the problems AS5 had.

I just started AS6 said "new project" then "c++ executable". It created a .cpp file for me and I typed this into it:
Code:
/*
 * GccApplication2.cpp
 *
 * Created: 15/05/2012 14:29:00
 *  Author: cliff
 */


#include <avr/io.h>

class foo {
   public:
   void setvar(uint8_t c);
   void printvar();
   private:
   uint8_t myvar;
};

void foo::setvar(uint8_t c) {
   myvar = c;
}

void foo::printvar() {
   PORTB = myvar;
}

int main(void)
{
   foo x;
   x.setvar(37);
   x.printvar();
    while(1)
    {
        //TODO:: Please write your application code
    }
}

When I build the .lss contains:
Code:
void foo::setvar(uint8_t c) {
   myvar = c;
  92:   fc 01          movw   r30, r24
  94:   60 83          st   Z, r22
}
  96:   08 95          ret

00000098 <_ZN3foo8printvarEv>:

void foo::printvar() {
   PORTB = myvar;
  98:   fc 01          movw   r30, r24
  9a:   80 81          ld   r24, Z
  9c:   88 bb          out   0x18, r24   ; 24
}
  9e:   08 95          ret

000000a0 <main>:

int main(void)
{
  a0:   cf 93          push   r28
  a2:   df 93          push   r29
  a4:   0f 92          push   r0
  a6:   cd b7          in   r28, 0x3d   ; 61
  a8:   de b7          in   r29, 0x3e   ; 62
   foo x;
   x.setvar(37);
  aa:   ce 01          movw   r24, r28
  ac:   01 96          adiw   r24, 0x01   ; 1
  ae:   65 e2          ldi   r22, 0x25   ; 37
  b0:   0e 94 49 00    call   0x92   ; 0x92 <_ZN3foo6setvarEh>
   x.printvar();
  b4:   ce 01          movw   r24, r28
  b6:   01 96          adiw   r24, 0x01   ; 1
  b8:   0e 94 4c 00    call   0x98   ; 0x98 <_ZN3foo8printvarEv>
  bc:   ff cf          rjmp   .-2         ; 0xbc <main+0x1c>

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
larryvc
PostPosted: May 15, 2012 - 09:10 PM
Raving lunatic


Joined: Dec 06, 2007
Posts: 2512
Location: Redmond, WA USA

clawson wrote:
I just started AS6 said "new project" then "c++ executable". It created a .cpp file for me and I typed this into it:

Cool. Very Happy

I was suprised to see this feature when I started to use AS6.

_________________
Larry

Those afraid to embrace the future will quickly fade into the past. - larryvc
 
 View user's profile Send private message  
Reply with quote Back to top
jack_kelly
PostPosted: Oct 16, 2012 - 09:52 AM
Newbie


Joined: Oct 10, 2012
Posts: 4
Location: London

Hello. Brilliant post; thanks loads for all the information. I'm trying to use new[] and delete[] on an Arduino (using Eclipse) and I think that native support for new[] and delete[] might have made some progress since the original post at the top of this thread.

Specifically, on avr-gcc 4.7.0 (installed on the latest version of Ubuntu: 12.10) it appears that new, new[], delete and delete[] all work out of the box.

But on avr-g++ 4.3.2 (installed by latest version of the Arduino IDE on Windows: 1.0.1) it appears that new and delete work out of the box but new[] and delete[] produce a undefined reference to `operator new[](unsigned int)' error.

Please may I ask two specific questions:

Firstly, is there any way to automatically detect whether new[] and delete[] are already defined? (e.g. a preprocessor directive of some sort)? For example, could we do something like #ifndef _OPERATOR_NEW_[]_ ?!

Secondly, on a platform which already has native new and delete but doesn't have new[] and delete[], should we make use of new and delete and our definitions of new[] and delete[]? e.g. something like this (I'm rather new at this game of manually defining new[] and delete[] so forgive me if this is a dumb suggestion):

Code:
void * operator new[](size_t size)
{
    return operator new(size);
}

void operator delete[](void * ptr)
{
    delete ptr;
}


This appears to compile but produces this warning:

Code:
new_test.cpp: In function 'void operator delete [](void*)':
new_test.cpp:25: warning: deleting 'void*' is undefined
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Oct 16, 2012 - 10:16 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Firstly, is there any way to automatically detect whether new[] and delete[] are already defined? (e.g. a preprocessor directive of some sort)? For example, could we do something like #ifndef _OPERATOR_NEW_[]_ ?!

Well one way would be to use these symbols:
Code:
E:\arduino-1.0.1\hardware\tools\avr\libexec\gcc\avr\4.3.2>avr-gcc -E -dM junk.c | grep GNU
#define __GNUC_PATCHLEVEL__ 3
#define __GNUC__ 4
#define __GNUC_MINOR__ 3

(it seems rather curious that the directory is called 4.3.2 but it appears to be 4.3.3?). Anyway just check the minor with something like:
Code:
#if __GNUC_MINOR__ == 3
 // define new/delete
#endif

Or perhaps more rigorously:
Code:
#define GCC_VERSION (__GNUC__ * 10000 \
                     + __GNUC_MINOR__ * 100 \
                     + __GNUC_PATCHLEVEL__)
...
#if GCC_VERSION <= 40302
 // define new/delete
#endif

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
atomicdog
PostPosted: Oct 16, 2012 - 05:34 PM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

jack_kelly wrote:


This appears to compile but produces this warning:

Code:
new_test.cpp: In function 'void operator delete [](void*)':
new_test.cpp:25: warning: deleting 'void*' is undefined
The compiler can't know how to properly delete the pointer since it's void and the actual type it points to isn't specified.

_________________
~~John
TWI C source code
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
maschwarz
PostPosted: Oct 16, 2012 - 06:52 PM
Newbie


Joined: Sep 07, 2012
Posts: 6


I have the following base class:
Class SerialPort
[
public:
SerialPort(size_t inputSize, size_t outputSize, uint_32 baudRate);
virtual bool Put(uint8_t data) = 0;
MyBuffer *GetInputBuff();
MyBuffer *GetOutputBuff();
// member variables are protected and not shown
};

I derive a class SerialPort0 from this
class SerialPort0 : public SerialPort
{
Public:
SerialPort0(size_t inputSize, size_t outputSize, uint32_t baudRate);
bool Put(uint8_t data);
};

And finally I build my main class
class MainClass
{
public:
MainClass();
~MainClass();
void Tick();
SerialPort *GetSerialPort();
void SetPort(SerialPort* _port);
private:
SerialPort *m_serialPort;
}

In the init code
I do the following

MainClass x,y;

x.setPort(y.GetSerialPort());

when I look at the m_serialPort I'm getting a Runtime Error message "An invalid DIE offset was passed to getDieFromId".

I'm stuck any ideas?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 16, 2012 - 07:11 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

I'm stuck any ideas?

This is not the place to discuss this - this thread serves to hold long time information that will be of benefit to all users of avr-g++. For specific usage questions start a separate (non sticky) thread.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
jack_kelly
PostPosted: Oct 16, 2012 - 09:33 PM
Newbie


Joined: Oct 10, 2012
Posts: 4
Location: London

Thanks loads for the quick replies! I've been grepping through my /usr directory to see if I can find where new, new[], delete and delete[] are defined on my shiny new Ubuntu 12.10 system.

It appears Arduino 1.0.0 introduced the files <arduino_core>/hardware/arduino/cores/arduino/new.cpp and new.h, the latter of which defines NEW_H and the functions new and delete (but not new[] or delete[]).

It also appears the binary file /usr/lib/gcc/avr/4.7.0/cc1plus includes the text delete[] several times. So I guess gcc-avr 4.7 has support for new, new[], delete and delete[]. Which is nice!

For reference, it seems that the x86 version of new etc. is defined in /usr/include/c++/4.7/new (which defines _NEW)

There is some discussion of adding new and delete to avr-libc: http://savannah.nongnu.org/patch/?7467 and http://lists.nongnu.org/archive/html/av ... 00005.html

Some discussion about adding new and delete support in Arduino: http://code.google.com/p/arduino/issues/detail?id=523
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
atomicdog
PostPosted: Oct 16, 2012 - 09:54 PM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

jack_kelly wrote:
It also appears the binary file /usr/lib/gcc/avr/4.7.0/cc1plus includes the text delete[] several times. So I guess gcc-avr 4.7 has support for new, new[], delete and delete[]. Which is nice!
cc1plus is the actual c++ compiler, so you shouldn't assume support just from that. Since the compiler needs to know that new is a special keyword even if there is no library present that supports it.

_________________
~~John
TWI C source code
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
jack_kelly
PostPosted: Oct 16, 2012 - 10:02 PM
Newbie


Joined: Oct 10, 2012
Posts: 4
Location: London

Here's my "new.h" file which hopefully detects whether the relevant functions are defined and, if not, defines them:

Code:
#ifndef _CUSTOM_NEW_H_
#define _CUSTOM_NEW_H_

/* It appears that version 4.7.0 of avr-gcc defined
 * new[] and delete[] so if we detect an earlier version
 * then we must define new[] and delete[] ourselves.
 * This "#define GCC_VERSION" trick from clawson:
 * http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453&start=all&postdays=0&postorder=asc#1002400 */

#define GCC_VERSION (__GNUC__ * 10000 \
                     + __GNUC_MINOR__ * 100 \
                     + __GNUC_PATCHLEVEL__)

#if GCC_VERSION < 40700

/* Arduino 1.0.0 introduced the files
 * hardware/arduino/cores/arduino/new.cpp and new.h
 * the latter of which defines NEW_H. 
 * So if NEW_H is not defined then we should
 * define new and delete. */

#ifndef NEW_H
#define NEW_H
#include <stdlib.h>
void * operator new(size_t size);
void operator delete(void * ptr);
#endif /* NEW_H */

// Arduino 1.0.1 doesn't include new[] or delete[]
void * operator new[](size_t size);
void operator delete[](void * ptr);

#endif /* GCC_VERSION */

#endif /* _CUSTOM_NEW_H_ */


let me know if this looks wrong!


Last edited by jack_kelly on Oct 16, 2012 - 10:08 PM; edited 1 time in total
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
jack_kelly
PostPosted: Oct 16, 2012 - 10:04 PM
Newbie


Joined: Oct 10, 2012
Posts: 4
Location: London

atomicdog wrote:
cc1plus is the actual c++ compiler, so you shouldn't assume support just from that. Since the compiler needs to know that new is a special keyword even if there is no library present that supports it.


Ah, cool, thanks. That's interesting. So where do you think new[] and delete[] might be defined on my Ubuntu 12.10 system? (new[] and delete[] work out-of-the box on Ubuntu 12.10... the only reason I'm having to define them again is for folks on older systems).
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
atomicdog
PostPosted: Oct 17, 2012 - 12:04 AM
Posting Freak


Joined: Jan 14, 2008
Posts: 1157
Location: San Diego

jack_kelly wrote:
atomicdog wrote:
cc1plus is the actual c++ compiler, so you shouldn't assume support just from that. Since the compiler needs to know that new is a special keyword even if there is no library present that supports it.


Ah, cool, thanks. That's interesting. So where do you think new[] and delete[] might be defined on my Ubuntu 12.10 system? (new[] and delete[] work out-of-the box on Ubuntu 12.10... the only reason I'm having to define them again is for folks on older systems).
I'm not sure where exactly it would be but should be in a library or object file somewhere. I believe looking at the Map file will tell you exactly which library file the function new was pulled in from.

_________________
~~John
TWI C source code
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Oct 17, 2012 - 09:04 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

I'd imagine they'd most likely be in libc.a so try avr\lib

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
felixo54
PostPosted: Feb 04, 2013 - 06:19 PM
Newbie


Joined: Feb 04, 2013
Posts: 2


pls,i try to install avr-gcc compiler on my window 7 but its not installing what im i to do pls help me
 
 View user's profile Send private message  
Reply with quote Back to top
felixo54
PostPosted: Feb 04, 2013 - 06:30 PM
Newbie


Joined: Feb 04, 2013
Posts: 2


[quote="Broxbourne"]
Quote:
You can use Student-Lockroom programming to achieve the result.

Thanks, I didni want to install avr-gcc compiler on my window 7 but not installing what im i to do
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Feb 04, 2013 - 06:35 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62941
Location: (using avr-gcc in) Finchingfield, Essex, England

Felix,

This is not the correct thread to diagnose problems about installing avr-gcc. Start a new thread and in it give more detail about what you are trying to do and what does not work. For example where did you get the avr-gcc you are trying to use on Win7 and what happens when you try to install. Do NOT answer in this thread - start a new one with clearer description.

Moderator.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits