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
coverclock
PostPosted: Apr 17, 2012 - 04:28 PM
Newbie


Joined: Mar 08, 2012
Posts: 13
Location: Denver Colorado USA

So this is the latest idea that I've gotten all obsessive-compulsive over: using Arduino, FreeRTOS, and C++ to teach real-time software design and embedded software development. I like the combination as a platform to teach both introductory students (using the Arduino Uno, SW and IDE), and to advanced students (using Arduino Mega or clone, FreeRTOS, C++, Eclipse, make, etc.). I really like the progression of starting out on the Uno with Arduino 1.0 and progressing to a multitasking RTOS, interrupt driven device drivers, etc. I like FreeRTOS because it's small, understandable, and it works. I like C++ because having spent many years in commercial product development (after having spent part of graduate school teaching real-time software design) I believe you need to climb as high on the abstraction ladder as you can to control costs, yet you need to see what's going on under the hood. The combination of Arduino and FreeRTOS hits a sweet spot of "just complex enough to be worth learning about".

So I started out doing exactly that: learning the AVR architecture on the Uno using Arduino 1.0, got FreeRTOS running on a Freetronics EtherMega (a Mega clone that incorporates the equivalent of an Ethernet Shield on the same board), wrote C++ OO wrappers around the FreeRTOS facilities (Task, MutexSemaphore, PeriodicTimer, etc.), wrote interrupt-driven device drivers in C++ (Serial, SPI), and a main program using a simple unit test framework that exercises all of it and demonstrates how it works. And there's plenty of room for student projects to write software for various applications, shields, hardware control, etc.

Recent blog articles I've written on this project:

http://coverclock.blogspot.com/2012/03/ ... -city.html

http://coverclock.blogspot.com/2012/04/ ... doing.html

Link to tarball can be found on project page:

http://www.diag.com/navigation/downloads/Amigo.html

For years I've futzed around with stuff like an Atmel AT91 evaluation board, a couple of BeagleBoards, etc. But even though I've spent years doing commercial development with Linux on ARM and PowerPC targets, I think when you throw in a memory management unit and the machinations that Linux goes through to be platform-independent, the result is too complicated for anything other than an advanced course. An RTOS like VxWorks, for which I've done a lot of commercial development, is too big, complex, and expensive, to use in anything except an advanced class. But once students got though Arduino, and then FreeRTOS, I think they could easily progress to VxWorks, and even to Linux, without much problems. The progression of Arduino and FreeRTOS would give them the confidence that they could figure out the more complex stuff.

I know this is my thing and I don't necessarily expect anyone else to be interested in it. But here it is.

-- Chip
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 17, 2012 - 04:47 PM
10k+ Postman


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

Quote:

I know this is my thing and I don't necessarily expect anyone else to be interested in it.

Thank you very much for posting this. I will most certainly read the blogs this evening. I am especially interested in your "interrupt-driven device-drivers in C++", but I'll have a look at it all.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: Apr 17, 2012 - 06:28 PM
Raving lunatic


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

I personally question skipping over C and jumping directly into C++ for microcontrollers. I can see how an ARM or such like with an OS can be an appropriate platform for programming to preexisting libraries, but on an ATmega328 using the UNO? I know that the Arduino mixes C and C++ in its libraries, but I think that leads to a lot of problems for novices trying to transition from the restrictions of the Arduino libraries to doing regular embedded system tasks that lack pre-built libraries.

Isn't learning about microcontrollers difficult enough without adding the extra layer of complexity involved in using C++. Isn't it better to teach C and the AVR architecture as programmed in C (and assembly) first so that the student really understands what is going on under the hood and once they have mastered the core concepts, them moving on to C++ when they are ready to work on very large projects with teams of other programmers? I see two courses, the first C based course introduces how to program to the hardware with C and the second introduces how to program to the software system using C++. The low-level hardware versus high-level system concepts are quite different from my perspective, one requiring an understanding of hardware systems and the other requiring an understanding of hardware systems (like OSs) and I can't see how trying to teach it all in one go would be useful for the vast majority of folks wanting to learn this.

I know we keep going over this, but I still think C++ is a major jump in complexity from C and for novices it just makes a nearly impossible task, fully impossible.

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: Apr 17, 2012 - 08:33 PM
10k+ Postman


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

OK, so now we're going (at least slightly) OT again:

I largely agree with you, Joe. But..

While I suppose historically most people have come to "C in embedded" from assembler, I think we see a growing crowd of people coming from today's PC programming - and that is dominated by OO languages i.e. Java and C#/VB.NET.

I suspect that a substantial part of the posts we see here where novices wonder why it isn't enough to include "that header file" to get the program to build are due to the fact that in both C# and Java the specification of "libraries to link in" is not merely as explicit as in C.

I believe that if you come from one of those languages, and have actually learned it well, then the paradigm shift of going from an OO approach to a "plain procedural approach" is also a major jump. To rub in an old running example we've used before, they might come here with the concepts they are familiar with and go "All-right, I want to write a class that handles serial communication, perhaps using this USART". Should we tell them "No, you shouldn't do that. Instead you should create a struct that you will pass around explicitly to a bunch of functions which are 'coupled' only by the fact that they take this struct as a parameter." They might be just as flabbergasted over this as e.g. an AVR C programmer that tries to write his first C# or Java program on, say, a Windows system.

What the "OO-thinking AVR novices" will still meet is the same hardware, which might be low level but none the less complex. This is no different from someone coming from e.g. C on Windows, and the way to handle those "details" is no different in C++. You access the same bits in the same SFRs using the same notation.

For someone coming from C in a non-embedded context it makes sense to stay with C (but that species is diminishing and will one day be more or less extinct). For someone coming from e.g. BASIC it makes sense to start with C. But for someone actually thinking object-oriented I'm not so sure.

Go visit ten universities and see what the first programming courses on the EE and CS programmes are using. If you find more than one that uses something else than Java or C# the next beer is on me! Very Happy

This is where the world has been moving, and while small(ish) embedded systems are the last in the line it will hit us it will happen. Mind you, I'm not thinking Java or C# on a 8K flash AVR - I suspect no meaningful Java or .NET run-time will ever be compact enough for that (I gladly accept being proven wrong, though). But this is where C++ is different - you pay only for what you use. The language was explicitly designed not to bloat, and to a large extent it succeeds.

To summarize this rant: IMO it depends on where you are coming from, and the world is changing. Perhaps slowly, but it is changing. The nice thing is - there is room for us all!

-----

Now I'm off to read your blogs, Chip! If you think this OT/tread-jacking was wrong just let me know and I'll talk to a moderator about breaking it out to it's own thread.

Code:
Freak johan = AVRfreaks.GetMember("johanekdahl");
Freak chip = AVRfreaks.GetMember("coverclock");

foreach (Blog blog in chip.GetWebSite().blogs)
{
   johan.Read(blog)
}

...or, if you wish...
Code:
Freak johan = ForumGetMember(AVRfreaks, "johanekdahl");
Freak chip = ForumGetMember( AVRfreaks("coverclock");
WebSite webSite = GetWebSite(chip);

for (int i = 0; i < webSite.blogCount; i++)
{
   ReadBlog(johan, webSite.blogs[i];
}


Your call.. Very Happy
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 17, 2012 - 08:43 PM
10k+ Postman


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

Chip!

I just skimmed the two blogs for the last two minutes. I think I will have to waste a part of a tree and print them out, sit (ok, more lie than sit...) down in a sofa with some tea. Looks very interesting!

The second one touches on some of the things I have also thought. I will read the passage on templates extra carefully.

Just in case you've missed it: Let me point to the columns of Dan Saks at embedded.com . A lot (as in "A LOT!") of C++-for-embedded goodies there.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
coverclock
PostPosted: Apr 18, 2012 - 09:21 PM
Newbie


Joined: Mar 08, 2012
Posts: 13
Location: Denver Colorado USA

Thanks for all the kind words and just generally taking the time to respond.

I started out doing embedded stuff in assembler in the 1970s on PDP-11s. But my experience in large embedded development organizations, mostly at Bell Labs, has convinced me that C++ is a win in the embedded space. But perhaps not for beginners.

I have the privilege of knowing Dan Saks. Back when I was teaching this stuff in the 1980s, he and I were both faculty members at the same university and had offices across the hall from one another. I believe he may have been on the C standards committee at that time. I still keep up with him via email from time to time even though we're 1200 miles apart now. He's been kind enough to correct me from time to time on my blog when I've misspoke.

Thanks again.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
westfw
PostPosted: Apr 19, 2012 - 03:36 AM
Posting Freak


Joined: Jun 19, 2002
Posts: 1428
Location: SF Bay area

Quote:
...convinced me that C++ is a win in the embedded space. But perhaps not for beginners.

You mentioned Arduino as the "easy" environment. They seem to be doing a pretty good job of leveraging C++ features to make things easier for beginners. Though not without the occasional hiccup...
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Apr 19, 2012 - 03:54 AM
Raving lunatic


Joined: Dec 18, 2001
Posts: 5376


IMO (uh oh)

C++ on a small memory micro- where you don't use "new" (from malloc) and "delete" and constructors are ill-advised, leads you to the only advantage being dots in the function names. The objects are static.

The code is cute. But no real difference in just using prudent names in plain C.

I abhor function name overloading. Really obtuse code.

But, C++ may have some other advantage in a small micro that hasn't hit me.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 19, 2012 - 11:50 AM
10k+ Postman


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

Quote:

I abhor function name overloading. Really obtuse code.

But that is, for example, one of the "advantages" of Arduino. It overloads the Serial.print() stuff so you can say:
Code:
int n = 12345;
char c = 'A';
char text[] = "Hello";
float f = 3.141592;

Serial.begin(9600);
Serial.print(n);
Serial.print(c);
Serial.print(text);
Serial.print(f);

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
DesertGeek
PostPosted: Apr 21, 2012 - 04:36 PM
Newbie


Joined: Apr 21, 2012
Posts: 1


I am an engineer with over 25 years industry experience and have taught both seminars and semester-length CS and mech courses to high school students for several years as a part-time gig at two parochial schools. I have noted following:
1. The kids know a lot more than you realize.
2. The kids know a lot less than you assumed.
3. C++ and Java do not work for a semester or less.
4. Python works for general CS introduction.
5. C works for embedded introduction.
6. Embedded systems should not be used an instructional vehicle for introduction to programming or CS. The people using the Arduino contradict this, but represent a subset having an abnormally high motivation level.
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 21, 2012 - 05:41 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

stevech wrote:
C++ on a small memory micro- where you don't use "new" (from malloc) and "delete" and constructors are ill-advised, leads you to the only advantage being dots in the function names. The objects are static.


Huh ? You should never use new if you can achieve the desired object lifespan without it. There are plenty of advantages besides "dots in the function name".
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 21, 2012 - 06:02 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

The only negative thing about C++ in embedded systems, as well as in many other environments, is that it takes a long time to get good at it. This is particularly obvious when it comes to embedded systems where you have rather limited resources.

As a lot of people think the availability of features means they have to use them, even skilled C programmers fail to realize that they can get immediate advantages from C++ without doing anything OO. Anything sensible you can do in C, you can do in C++. There are a few things you are not allowed to do in C++, and those are things you shouldn't do in the first place.

A good first step that comes at no performance cost is to compile all your C sources as C++. First get rid of all the errors, then get rid of all the warnings, and the quality of your code has improved (unless you "fix" everything with a cast).

From there, you have access to all the improvements of C++ including function overloading, template functions, loop variables and all sorts of other neat features – still without doing anything OO unless you want to.

It is possible to gradually make the transition to C++ without messing up your existing systems.


(EDITed to fix character set problems (' and "))


Last edited by ChaunceyGardiner on Apr 21, 2012 - 11:14 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
smileymicros
PostPosted: Apr 21, 2012 - 07:10 PM
Raving lunatic


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

westfw wrote:
Quote:
...convinced me that C++ is a win in the embedded space. But perhaps not for beginners.

You mentioned Arduino as the "easy" environment. They seem to be doing a pretty good job of leveraging C++ features to make things easier for beginners. Though not without the occasional hiccup...
I honestly believe that this decision was a mistake on their part. Sort of like the one that requires them to use a 0.05" space between two 0.1" headers - a dumb glitch that everyone now has to live with to be 'Arduino'.

I have rewritten most of the Arduino library in regular C and IMHO it is just as easy to use as their version which mixes C and C++ in a most perplexing way. This is especially true for Cliff's example for the 'simple' Serial.xxx functions. You have to write long lists of these commands to get what you get immediately with printf.

By mixing C and C++ they pretty much assure that a novice will never go under the hood and grok what is going on with the core functions. It is difficult enough to learn C or C++ from scratch, but seeing code written in both and mixed willy-nilly doesn't give the student the opportunity to see either the strengths or the weaknesses of either language displayed logically.

Mind you, I think the Arduino is the greatest thing since sliced bread. But I tend to make my own bread and slice it myself. To me the Arduino is absolutely the best place for novices to start. But if they want to move on, they need to quickly get away from the underlying Arduino code and look elsewhere for a logical progression in programming knowledge.

Okay, this is a rant in which I am justifying a bunch of stuff I've been pushing for the past several years, but it is also something I believe.

And sorry if this is to OT, but it seems the thread has already gone this way so... Back on topic, I think the OP suggestion to start with C++ is not as viable as starting with C, but I also think starting with C++ is MUCH preferable to starting with mixed C and C++.

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: Apr 21, 2012 - 07:51 PM
10k+ Postman


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

Joe!

Any reaction to my "it depends on where you come from"?

Also: I always thought that the Arduino framework was designed primarily for people who did not have as their primary interest neither to learn about the hardware nor to design performance-critical stuff.

There was examples like artists mentioned.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Apr 21, 2012 - 08:31 PM
10k+ Postman


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

Quote:

You have to write long lists of these commands to get what you get immediately with printf.

I still use printf() in C++ code. I find the overloading of << painful at best. I know it's "clever" that the same thing can print a sting or a float but I still prefer good ole %s and %f Wink One day perhaps I'll "get it". The hoops you have to go through for %04.2f are especially painful with all that setw() and setfill() nonsense. Exactly who thought this was an improvement?

Cliff "The Luddite"

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 21, 2012 - 08:54 PM
10k+ Postman


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

I mostly agree cliff. For just outputting a few variables and/or literals w/o demands on specific formatting the streams might be easier. For most any structured output, printf() is my use also.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: Apr 21, 2012 - 08:58 PM
Raving lunatic


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

JohanEkdahl wrote:
Joe!

Any reaction to my "it depends on where you come from"?
Well, thiat is an excellent consideration.

However, I come from the bottom end of things and don't really feel like I understand C++ well enough to explain it to novices, so I stick with what I know. I also think that those coming from OOP must at some point learn that OOP is about the way humans think, while C is about the way computers work. For systems with the resources it only makes sense to offload the expensive human time to the cheap processor time and use OOP. But for restricted microcontrollers it still seems to me that it makes more sense to use human time to cater to system constraints. Finally, if a person never learns C and dare I say, assembler - they never really know what the machine is doing and are poorer for that. AND yes I admit that most folks, Arduino users included, could give a flip about how the thing works. But I chose not to deal with those folks. I am hungry for knowledge and just don't get folks who aren't.

I can see a pedagogical justification for using C++ with a more capable system, but for a 'real' engineer, I'd want to know that they had a good feel for the architecture, the assembler, and C before they get into the higher conceptual paradigm of OOP and C++.

JohanEkdahl wrote:
Also: I always thought that the Arduino framework was designed primarily for people who did not have as their primary interest neither to learn about the hardware nor to design performance-critical stuff.
Absolutely! And when the few that get curious about how this thing is really working, I pity them that look at the underlying code and think that it provides a path to real world embedded system development. It is the phase of 'Moving Beyond the Arduino' that concerns me, and I think that these folks should be learning something that mimics the underlying architecture as C does, rather than the way a human brain works as C++ sort of does.

JohanEkdahl wrote:
There was examples like artists mentioned.
That is who the system was designed for and is perfect for them. Remember - I am an Arduino fan, but I also understand that it has serious limits. But now everybody is using them and while it provides and easy start, I think it also creates a gulf between what the Arduino does and what can be done with a micro. In a way it is a bit like BASIC in that respect. BASIC does a bunch of things well, but there are things a micro can do that just aren't part of the BASIC implementations I've seen. To move on to serious programming you have to abandon BASIC for assembly or C, and I think the exact same case holds for Arduino. Our argument is whether they abandon it for C or a mix of C and C++. I think the latter just puts up a barrier for most intermediate folks.

Perhaps someone should take the opposite tactic that I'm taking and provide a path for the high level folks that teaches an entirely C++ version of Arduino and then if the folks want to understand the low level stuff, then a path to C and assembler can be given.

Yeah, I'm overthinking this.

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
ChaunceyGardiner
PostPosted: Apr 21, 2012 - 09:08 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

clawson wrote:
I still use printf() in C++ code. I find the overloading of << painful at best. I know it's "clever" that the same thing can print a sting or a float but I still prefer good ole %s and %f ;-) One day perhaps I'll "get it". The hoops you have to go through for %04.2f are especially painful with all that setw() and setfill() nonsense. Exactly who thought this was an improvement?
Overloading operators is not necessarily bad. It's not the overloading that causes lousy performance and awkward syntax.

The streams implementations, on the other hand, generally suck big time and no C++ programmer that knows his head from his axx uses them extensively.

printf() et al are a part of the C++ libraries anyway. Just some moron creating an alternative to the older libraries doesn't mean we have to use the alternative.
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 21, 2012 - 09:09 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

JohanEkdahl wrote:
For just outputting a few variables and/or literals w/o demands on specific formatting the streams might be easier.
Not if you're concerned about program size. Including a streams implementation in your executable is likely to cost you.
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Apr 21, 2012 - 10:44 PM
Raving lunatic


Joined: Dec 18, 2001
Posts: 5376


[quote="ChaunceyGardiner"]
stevech wrote:
There are plenty of advantages besides "dots in the function name".
In the context of embedded processor code that is easily maintained by other than the author, what are the C++ advantages? I've spent a lot of time learning C++ (coming from decades of C), and haven't yet found what's better than good modularized C with lots of typedefs and structs (for embedded).
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 21, 2012 - 11:21 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

stevech wrote:
ChaunceyGardiner wrote:
There are plenty of advantages besides "dots in the function name".
In the context of embedded processor code that is easily maintained by other than the author, what are the C++ advantages? I've spent a lot of time learning C++ (coming from decades of C), and haven't yet found what's better than good modularized C with lots of typedefs and structs (for embedded).


Function overloading, template functions, loop variables, reference variables and type safety for starters. Those are just off the top of my head, the list is much longer.

For the skilled C++ developer - classes, class templates, inheritance, improved resource handling, easier creation and use of reusable code, less duplication of code and so on.
 
 View user's profile Send private message  
Reply with quote Back to top
westfw
PostPosted: Apr 22, 2012 - 01:19 AM
Posting Freak


Joined: Jun 19, 2002
Posts: 1428
Location: SF Bay area

Quote:
template functions

I've seen Arduino folk use "template functions" to good effect, but they're not something I've come across in my reading of "introductory C++", so I've always assumed that they were one of those tools used by "advanced" tools writers, sort-of like stringification and catenation in multi-line macros would be in C.

But now you have it in the "immediately useful" category, while other concepts that the introductory texts are big on (classes, inheritance), you have in the "skilled" category.

Tell me more (point me to) more about templates and when they are appropriate/etc...

(This does point out one of the big problems with C++ in the embedded space. The usual TEACHING of C++ is done in ways that tend to be incompatible with deeply embedded systems. "we can make a class purpleWindow that inherits most of its behavior from the normal XYZGrpahicsWindow class, and use "new" to put them all over our display.")
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 01:39 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

westfw,

Template functions aren't that hard to understand. For instance, consider this:
Code:
template<class T>
inline T min(T a, T b)
{
    return a < b ? a : b;
}

int i = min(1, 2);
This, as opposed to a macro, adds type safety, lacks side effects and will give you a more or less sensible error message if you try to compare apples to oranges and assign the result to a peach.

Also note that C code compiled as C++ will have to conform to a stricter standard, which allows you to avoid some of the common pitfalls of C. C is way too lenient.

The reason I put classes and inheritance in the "skilled C++ developer" list is that you need some knowledge about the code generated in different cases before you can put this to good use in a context with limited resources.

The same goes for using new – it should be avoided when not necessary, and you need skills to know when it's necessary. The skilled C++ developer will avoid this on any platform, but the consequences of lacking this knowledge are bigger on embedded systems because of the limited resources.
 
 View user's profile Send private message  
Reply with quote Back to top
smileymicros
PostPosted: Apr 22, 2012 - 02:23 AM
Raving lunatic


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

<sarc>
Oh yes that is so much easier and clearer than:
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
</sarc>

_________________
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
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 02:30 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

smileymicros wrote:
<sarc>
Oh yes that is so much easier and clearer than:
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
</sarc>

Yes, it is. There is no telling what X and Y might be.

The parenthesis doesn't help readability, either.

The main point of using the template version, though, is that your user source code looks the same while there are less ways to fudge things up.
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Apr 22, 2012 - 07:21 AM
Raving lunatic


Joined: Dec 18, 2001
Posts: 5376


Opinion: Chauncey's remarks above about the merits of C++, function overloading (for me, it makes for confusion during debugging); Inheritance - if it's all compile-time, since in my embedded work there's not enough RAM to fool with new/Malloc; Better resource management: If one doesn't (cannot) do object creation/deletion in a small RAM micro, is this applicable? ; Templates - yes, these are better than Macros, but the learning curve on Templates is daunting, and I worry that it would be too obtuse to understand a year later.

In my C++ studies, I figured out how (couldn't find in texts) for an ISR to have shared variables with a static instance of a class' variables. Never have figured out how to "friend" those to protect from access by other than the class functions and the ISR. Nor have I figured out (other than an ugly way) for a class instance at run time (new) to collaborate with an ISR, on a CPU without memory management like our little 8 bitters.

I welcome the rebuttal!

I have written a couple of AVR-targeted thousand-line C++ programs which include ISRs (in C, not C++), and have mastered the basics of C++ with static instances of classes (no malloc). That's good enough, I suppose, for micros with just a few KB of RAM. A garbage collector for RAM (free()) in some instances can cause unpredictable timing for an embedded micro. And worse, iterating to try to conjoin free'd RAM blocks. Not gonna work in 4KB RAM devices without multi-tasking.

Good discussion.
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 02:34 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

stevech,
Using classes doesn't mean you have to use new, just like using C structs doesn't mean you have to use malloc. Think of classes as C structs, where you can take advantage of additional features if you want to.

You worry about unrestricted access to your class members. While that is good thinking if it leads you to a good solution, it doesn't make much sense worrying about this when the "solution" is to go back to C and allow everything access to everything.

The ISR use of an object boils down to this : are you able to access a C struct from your ISR ? If so, what stops you from accessing an object the same way ? C++ classes are C structs. It's just that you're allowed to do more with them.

Most of the things you have given up on finding out are things you could have asked about in a suitable forum. That applies to function templates too - if you find them hard to learn, post a macro you want to convert to a template and ask how to do it. The fact that you can create complicated templates doesn't mean that you have to make them complicated. And complicated macros are worse anyway.
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Apr 22, 2012 - 06:26 PM
Raving lunatic


Joined: Dec 18, 2001
Posts: 5376


Chauncey... Of course, classes can be static. And I assert, they must be in a small RAM micro, especially when deterministic timing is necessary as is often the case in small micro embedded.

I did start a dialog here on how to properly access variables in a C++ class from an ISR, or vice-versa. I didn't get a usable answer, and the 'net and texts didn't tell me, so I resorted to trial and error. Probably still don't have it right. It's because of the name-mangling C++ does and the C based ISR doesn't.

I'll be the first to day that despite a lot of time on C++ and ISRs and so on, I still don't know what I don't know. Wish there were a proper and in depth tutorial on this, in the context of 8 bit micros with small RAM and bare metal (no OS).
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 06:54 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

stevech,

It's not clear to me what you mean when you use the word "static" like you do.

The lack of learning material for efficient use of C++ on embedded systems is one of the reasons I separated "advanced" stuff from easy stuff. You can use the easy stuff without years of experience.

Name-mangling can be turned off by using extern "C".

You will need a reference to your object to use inside the ISR, just as you would need a reference to your struct if you did it in C.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 22, 2012 - 07:58 PM
10k+ Postman


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

Quote:

Chauncey... Of course, classes can be static.

Or automatic.

I assume here that we are talking about the allocation of them, i.e. "static, automatic or dynamic" as those terms are used in C. They can be used the same in a C++ context.

The confusion arises because the language keyword 'static' exists in C++, and while there are philosophical similarities this is a different "mechanism".

When using "static" in a C++ context, make sure it is clear from the context if the allocation scheme (i.e. static-automatic-dynamic allocation of objects) or the keyword (e.g. as in "a static member") is intended.

Quote:

And I assert, they must be in a small RAM micro

So must a C struct. No difference.

Here is the gist of it:

- If you in C need to handle only one istance of a data structure then you set up that data structure as one or several global and let a set of C functions operate on them. You will not have control of that other functions meddle with the data structures. In C++ you package the data and the functions in a class, making all members static, and use the access restrictions of classes (public, protected, private) to shield your data structure form "external meddling". No extra cost involve as compared to C.

- If you need to handle several instances of the data in C, then your functions will have to take (a pointer to) the data structure as a parameter. Again your data structure will be available for "meddling". And you will have to pass the data explicitly to all your functions. In C++ you protect your data as above, the difference being that now data and functions are not declared static. C++ will implicitly pass a pointer to the instance data, the 'this' pointer. There will be no extra cost involved as compared to C.

- If you don't want/need inheritance then there will be no extra cost involved not using it in C++. If you do want/need inheritance then...

- if it is non-polymorphic inheritance then C++ will help you with that. You might pull this off with C, but you as a programmer would be the one responsible for calling the correct version of a function. In C++ the compiler will do that for you. Just as for the case above with no inheritance there will be no extra cost as compared to C.

- if it is polymorphic inheritance (or if you wilsh "using virtual member functions in C++") then you can get away with this in C also, but again there will be no help from the compiler. Your C source code will be full of convoluted function calls and handling of tables of virtual function pointers. Again, the C++ compiler will be helping you here at no extra cost as compared with the C implementation.

And again, if you opt not to use a C++ feature, there will be no cost for it.

For the discussion on ISRs, the most straight-forward solution seems to be to implement the ISR as a C function, and if performance so demands make it a friend of the class for which it needs to manipulate data. If the performance demands aren't high, then you could let it call a member function of the class (and pay the usual penalty for calling a function from an ISR).

Or you could let the ISR follow the idiom of setting a global flag and perhaps a variable, let the main loop inspect the flag and manipulate the object. This is a compromise, but I'm not religious about C++ so if that works in a specific situation that might be fine for me.

None of the statements on performance above is a statement on any specific compiler, and a badly written C++ compiler could well be very inefficient. There is nothing inherent in C++ that makes it inefficient for the above cases, though. A badly written compiler is a badly written compiler and could/should be criticized regardless of what language it compiles.

Finally: If you take the stance that you dislike or am reluctant towards <any thing> then you will have a hard time learning it. If you are reasonably skeptic but curious in a positive way, you will have an easier time. If <any thing> is actually C++ and you are reluctant or disliking it, then you will be better off not going for it. There is room for both C and C++ - use what makes you happy, not what makes you sad.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 22, 2012 - 08:12 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

I agree with everything Johan just wrote. However, it is important - especially in the context of small embedded systems - to be aware of what code is actually generated by some C++ features (typically related to classes). It is possible for the programmer to affect this, but it takes experience to know what to do and what not to do.

_________________
Sid

Life... is a state of mind
 
 View user's profile Send private message  
Reply with quote Back to top
coverclock
PostPosted: Apr 23, 2012 - 04:04 PM
Newbie


Joined: Mar 08, 2012
Posts: 13
Location: Denver Colorado USA

It's easy to get into a C versus C++ argument because both parties are right.

I'm old enough (almost a brain in a jar connected to wires and tubes) that I remember the assembler versus C arguments when I was writing real-time stuff for PDP-11s in assembler. And the assembler folks are right too. In the 1990s even as I was writing in C++ for one chip on a board I was also writing code in assembler on DSPs on the same board. Just depends on the circumstances.

But part of my goal in this project was to figure out if the C++ techniques I'd been using since 1996 on PowerPC and ARM processors could be carried over to eight-bit microcontrollers. The answer, for me, was "yes". Not that it doesn't take discipline and care. You can write inefficient, hard to maintain, buggy code in C++, just as you can in C, and for that matter in assembler.

C++'s greatest strength is also it's greatest weakness: it allows you to climb higher on the abstraction ladder. This can reduce your development costs, both short term and long term, and can also reduce your project to a smoking heap of crap. Climbing higher on the abstraction ladder does not free you from having to know what's going on under the hood.

This is really always true, but is especially always true in highly resource constrained environments. ("Especially always" meaning elsewhen you can get away with being ignorant without being bitten right away... unfortunately.)

I don't believe C++ is a good language for students just starting out to learn programming. It's just too darn complicated. I like Java, or script-like languages like Python (which I've never used, but colleagues whose opinions I trust recommend it).

But for more experienced students who are beginners at embedded, I think C++ is a win. And for very experienced embedded developers who are looking for more capability from their language, it is a big win.

I like OO design. My first experience at OO design was working with the OS/360 I/O Subsystem written circa 1969, although I first started poking at it in 1976. No, I'm not kidding. Almost all the mechanisms that C++ uses under the hood I first saw in IOS.

Algorithms have two big picture components: action, and state. The question "which is more important, action or state?" is meaningless, it's like asking "which is more important to life, blood or oxygen?"

OO languages are a way of combining action and state into a single lexical component, with some rules to prevent developers from inadvertently dealing with one but not the other. Back when I was using C for pretty much all development, i found myself writing in a style that combined action and state (structures and functions). C++ gave me the means to combine the two in a way that the language supported what I wanted to do automatically.

Thank you, thank you, I'll be here all week. Don't forget to tip the bartender!
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: Apr 23, 2012 - 05:15 PM
Raving lunatic


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

coverclock wrote:
Algorithms have two big picture components: action, and state. The question "which is more important, action or state?" is meaningless, it's like asking "which is more important to life, blood or oxygen?"

OO languages are a way of combining action and state into a single lexical component, with some rules to prevent developers from inadvertently dealing with one but not the other. Back when I was using C for pretty much all development, i found myself writing in a style that combined action and state (structures and functions). C++ gave me the means to combine the two in a way that the language supported what I wanted to do automatically.
This is an excellent statement - thank you!

I've often said that anyone who does enough assembly programming will eventually invent C-like methods for organizing his code. I'm guessing the same applies for C, anyone who does enough of it (especially in teams) will likely develop methods that are C++-like.

There is a lot of gray in the area for folks starting out on microcontrollers. I'm coming to take to Johan's idea that lots of folks will be coming from higher level programming and therefore will already be OOP oriented so they could start out with C++. Unfortunately from my perspective, I don't honestly think I have the experience to lead that charge, so I'll stick with the never-ever programmed folks and continue to promote C. I'll just be fairer when I hear the novice C or C++ argument.

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
coverclock
PostPosted: Apr 23, 2012 - 06:06 PM
Newbie


Joined: Mar 08, 2012
Posts: 13
Location: Denver Colorado USA

Quote:

I've often said that anyone who does enough assembly programming will eventually invent C-like methods for organizing his code. I'm guessing the same applies for C, anyone who does enough of it (especially in teams) will likely develop methods that are C++-like.


Well said. That has been my experience exactly. Before I ever heard the term "structured programming" back in the 1970s I found myself writing structured programming constructs in assembler just because it was the only way I'd found to write reliable, debuggable, understandable code.

BTW, different sub-thread, I have written some on using C++ templates in embedded projects. As usual, the higher level the language, the more tools it gives you to shoot yourself in the foot, so approach with caution.

http://coverclock.blogspot.com/2007/01/ ... using.html

I would NOT recommend trying to use the C++ STL on an eight-bit microcontroller (the underlying library won't have the STL stuff anyway, so non-issue). But careful use on less constrained PowerPC and ARM platforms has been a win in my experience, and use of your own templates even on AVRs etc. can be a win if done very carefully. Templates used correctly also fall into the category of "automating what you were doing by hand anyway" and depending on the application may have zero additional overhead. Templates are a form of code generation, just like the C preprocessor, and like the CPP, can be great or terrible.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 23, 2012 - 06:23 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

smileymicros wrote:
I'll stick with the never-ever programmed folks and continue to promote C.

Nothing wrong with that, but why dismiss the approach I suggested ? No matter how far you go, you will benefit.

For instance, if you just compile your C code as C++, the compiler will enforce some very good programming habits.

From there, you may be tempted to take advantage of several easy to understand C++ improvements, while your source code still looks pretty much like C.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 23, 2012 - 07:00 PM
10k+ Postman


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

Quote:

From there, you may be tempted to take advantage of several easy to understand C++ improvements, while your source code still looks pretty much like C.

I'd agree this is the best approach. Start with C in .cpp files but then maybe start to dabble in namespaces or classes with member functions (the infamous class.function() syntax), then use things like function over-loading.

A bit like when you make the transition to C99 you just start to use the new bits then wonder how you ever lived without them.

I'd be interested to hear from the C++ experts here what is the best 10 features to dabble in first(*). A bit like when the MCU programmer starts and does:

1) light LED
2) blink LED with delay loops
3) blink LED with timer
4) PWM LED to fade up/down
5) read pot using ADC and use to vary blink/fade/etc.
6) and so on...

(*) with emphasis on MCU usage!

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
smileymicros
PostPosted: Apr 23, 2012 - 08:42 PM
Raving lunatic


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

coverclock wrote:
As usual, the higher level the language, the more tools it gives you to shoot yourself in the foot, so approach with caution.


Quote:
"C makes it easy to shoot yourself in the foot. C++ makes it harder, but when you do you blow your whole leg off." - Bjarne Stroustrop


I'll probably wait a few more years and then start working on teaching materials for embedded Linux on an ARM using C++. It seems to me we really are in a transition point where transistors are becoming so cheap that adequate systems will be available for a few dollars. Really the only thing in the way in the moment are well documented free and easy tools like WinAVR. I assume in the next few years these tools and documents will become available.

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
ChaunceyGardiner
PostPosted: Apr 23, 2012 - 09:02 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

clawson wrote:
I'd be interested to hear from the C++ experts here what is the best 10 features to dabble in first(*).

(*) with emphasis on MCU usage!
My first attempt at such a list :
    1) declare variables at first use
    2) loop variables
    3) bool data type
    4) function overloading
    5) default parameters
    6) new[] and delete[]
    7) template functions
    8) simple classes, i.e. C-style structs with the addition of non-virtual member functions
    9) simple class inheritance
    10) exception handling (if the overhead is acceptable)
Some of those may be included in C99 ? I ditched C for C++ more than 20 years ago, so I don't stay fully updated on C.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 23, 2012 - 09:44 PM
10k+ Postman


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

Quote:
8 ) simple classes, i.e. C-style structs with the addition of non-virtual member functions

I'd probably have that as #1 . Apart from the "addition of member functions" you also have to deal with access specificers (public-protected-private), constructors and destructors. And then you have the concept of aggregation (ie objects within objects) and then you will have to return to talking about constructors and destructors and the order in which they are executed. And I'm probably missing a lot of things. There is enough here for items #1 to #5 on the list...

Quote:
7) template functions

No opinion on that ordering, but I'd say that template classes should be on the list and are more important than template functions. I've taught C++ many times (a three day introductory course), and while we always introduced templating with template functions I am actually wondering if that is the wise way. Don't get me wrong - both are usable, but while template functions are convenient template classes are about something much bigger. Think "Abstract Data Types" if that term is familiar.

Quote:
3) bool data type

I could deem this a detail, if it wasn't for another big difference between C and C++: While C has the type concept, there is very little inherent type safety. C++ is a lot stronger here. And the notion of "a real boolean type" is an indicator of that C++ was designed with types as a central concept.

Quote:
9) simple class inheritance

I'd have this fairly early on the list, definitively before any templating.

Quote:
6) new[] and delete[]

Where did new and delete disappear? Quatum leap to dynamic allocation of arrays of objects - oh my! Wink
Quote:

1) declare variables at first use
2) loop variables
4) function overloading
5) default parameters

All details in the big picture. Not simply syntactic sugar perhaps, but not central to "thinking in C++".

Quote:
10) exception handling (if the overhead is acceptable)

I'll have to think about this..

-----

I have a few "mental mantras" about OO:

Mantra 1: Encapsulation, Inheritance, Polymorphism

Mantra 2: Favour aggregation instead of inheritance.

Mantra 3: Program against an interface.

Mantra 4: Initialize in the constructor, tear down in the destructor (a.k.a RAII).

Those would control and influence the items, and the order of them, on my C++ list.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 23, 2012 - 10:36 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

Johan,

My list is ordered more or less according to ease of use for the experienced C developer.

What I wrote about “simple” classes is aimed at this audience. They would be better served by starting with C structs, only adding non-virtual member functions, as this adds no implicit overhead. Throw in constructors, destructors and aggregation and you increase the demands on the developer’s knowledge considerably – especially in the context of embedded systems. Also, starting with a C struct means that you don’t have to deal with access specifiers. Keep it simple, once people master the basics they may (or may not) decide to learn more.

Simple function templates are useful and easy to understand. Big gain, small cost.

new and delete should be avoided whenever they are not needed, for the skilled C developer it’s best to avoid them completely unless he is mallocing structs in his C code.

new[] and delete[] on the other hand is a type-safe alternative to malloc()/calloc() (to create C arrays), and easy to understand for the skilled C developer.

Template classes are best avoided until you are fully competent on classes.

What you refer to as “details in the big picture” are simple little things that improves your source code, and they most likely appeal to the skilled C developer that can immediately use them. They are small details to you and me, but good points for convincing others that there may be something to this other language even without years of study.

I don't disagree with you about C++ but you have the wrong focus for this audience.
 
 View user's profile Send private message  
Reply with quote Back to top
coverclock
PostPosted: Apr 29, 2012 - 02:06 AM
Newbie


Joined: Mar 08, 2012
Posts: 13
Location: Denver Colorado USA

Regarding slowly transitioning from C to C++: this is something I've had to deal with for some time in large product line code bases (where code is shared across many embedded products, including ones with different processors, not just different models but completely different architectures. I wrote a blog article about some techniques to ooze C++ into an existing C code base.

http://coverclock.blogspot.com/2011/02/ ... and-c.html
 
 View user's profile Send private message Visit poster's website 
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