| Author |
Message |
|
|
Posted: May 13, 2009 - 04:11 AM |
|

Joined: May 04, 2009
Posts: 7
|
|
| All strings r working.. i've debugged it and i saw it works.. thanks for the help |
|
|
| |
|
|
|
|
|
Posted: Jun 02, 2009 - 12:46 AM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Jun 02, 2009 - 01:31 AM |
|


Joined: Jan 14, 2008
Posts: 1147
Location: San Diego
|
|
|
|
|
|
|
Posted: Jun 02, 2009 - 03:31 PM |
|

Joined: May 13, 2009
Posts: 4
|
|
Thank you for those links, the first one already pretty much answers my questions.
Manuel |
|
|
| |
|
|
|
|
|
Posted: Jun 02, 2009 - 08:30 PM |
|


Joined: Mar 27, 2002
Posts: 18585
Location: Lund, Sweden
|
|
|
|
|
|
|
Posted: Jun 03, 2009 - 12:00 AM |
|

Joined: Sep 07, 2004
Posts: 2527
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".
Still, for me C++ is the only way to go. |
|
|
| |
|
|
|
|
|
Posted: Aug 16, 2009 - 07:59 PM |
|

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
|
| |
|
|
|
|
|
Posted: Aug 16, 2009 - 08:08 PM |
|


Joined: Mar 27, 2002
Posts: 18585
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. |
|
|
| |
|
|
|
|
|
Posted: Aug 17, 2009 - 12:24 AM |
|

Joined: Sep 07, 2004
Posts: 2527
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. |
|
|
| |
|
|
|
|
|
Posted: Mar 07, 2010 - 03:11 PM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Mar 08, 2010 - 12:45 AM |
|


Joined: Jan 14, 2008
Posts: 1147
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. |
|
|
| |
|
|
|
|
|
Posted: Apr 22, 2010 - 03:48 PM |
|

Joined: Apr 09, 2010
Posts: 11
|
|
| which c++ compiler should we be using? the G++ one or C++ one? |
|
|
| |
|
|
|
|
|
Posted: Apr 22, 2010 - 03:57 PM |
|


Joined: Jul 18, 2005
Posts: 62354
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
|
_________________
|
| |
|
|
|
|
|
Posted: Nov 19, 2010 - 02:10 AM |
|

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  |
|
|
| |
|
|
|
|
|
Posted: May 15, 2012 - 02:22 PM |
|


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. |
|
|
| |
|
|
|
|
|
Posted: May 15, 2012 - 02:36 PM |
|


Joined: Jul 18, 2005
Posts: 62354
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>
|
_________________
|
| |
|
|
|
|
|
Posted: May 15, 2012 - 09:10 PM |
|


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.
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
|
| |
|
|
|
|
|
Posted: Oct 16, 2012 - 09:52 AM |
|

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
|
|
|
| |
|
|
|
|
|
Posted: Oct 16, 2012 - 10:16 AM |
|


Joined: Jul 18, 2005
Posts: 62354
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
|
_________________
|
| |
|
|
|
|
|
Posted: Oct 16, 2012 - 05:34 PM |
|


Joined: Jan 14, 2008
Posts: 1147
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
|
| |
|
|
|
|
|