megaAVR + Arduino + FreeRTOS + C++ = Teaching Platform

41 posts / 0 new
Last post
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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/small-town-big-city.html

http://coverclock.blogspot.com/2012/04/learning-by-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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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! :D

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.

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

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

...or, if you wish...

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.. :D

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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:

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);

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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".

Sid

Life... is a state of mind

Pages