Parallel Programming For the Arduino 140
blackbearnh writes "As more non-traditional programmers start playing around with embedded platforms like the Arduino, the limitations and complications of interrupt-driven event handling can become an annoying barrier to entry. Now a group of academics have ported the parallel-processing language Occam to the Arduino. In an interview on O'Reilly Answers, Matt Jadud of Allegheny College describes how Occam helps artists using the Arduino in their installations, and how the advent of low-cost computing platforms is changing the educational experience for proto-makers in school. 'Basically, an artist or a tinkerer or a hacker has a goal. They don't really care about learning Occam. They don't care about how this language is different from C. They just want to make a cat door that keeps their cat out when the cat comes back with a mouse. Or they want to make some kind of installation piece. Trying to focus as much on the user and the possible goals they might have is what's motivating our work right now.'"
Re:Threads (Score:5, Interesting)
In my limitted experience, threads are one of the more difficult things for... people to understand. I find it difficult to describe their position, which I think Matt Jadud had a tough time too, (See how he said "an artist or a tinkerer or a hacker"). In my situation, I have a friend who is taking an engineering major at the local university. Now, a little background information; I don't know how it is in other cities across the world, but here, Engineering at the university is considered one of the hardest courses. You know, really ridiculously high drop out rates, cause most people can't handle it. Opening orientation, they say look to your left, look to your right. 2 out of the 3 of you won't make it past second year. So anyone who manages to make it through the first 2 years of Engineering gets this perception that they know to do stats as well as a stats major or know how to program as good as a programming major.
Anyways, so my buddy is in engineering, and he knows enough C++ to essentially do any calculation he wants through the command line. He hasn't had to work with GUI's or anything like that. The most he did was a turn based Star Trek game where the command prompt simply reprints the "game board" everytime you make a move or perform an attack, prompting the player what to do at the end of each turn.
So he tends to be the kind of user that they target with these kinds of ports. He's already loaded with a bunch of information in some other field. Be it engineering, arts, hacking, radio signals, whatever. They don't have a whole lot of time to run through the tutorials to learn threading and how its supposed to be done properly. There's no telling how long it'll be before they get into an issue with threading and they won't have enough knowledge on how to fix it and it'll be a big headache if they went and built their entire code that revolves around this segfault they created.
So thats where these other languages come in. They are similar enough to a common language like C that anyone who does a beginner course can pick them up. They offer the features that users WANT without all the complications that come with learning how its done.
I know, I know, teach a man to fish, right? But what if he only ever needs 1 fish in his entire lifetime?
Interrupt Service Routines (Score:3, Interesting)
There is no limit to the functionality of Interrupt Service Routines (ISR) and the interrupt-driven "event model," as the OP put it.
Programming an ISR may be difficult, but even the topic of this post, a parallel environment running on the Arduino, will be based upon ISR routines. The user-level programs will not interact with ISRs, but the Ocaml implementation will abstract them.
Fundamentally, the hardware will continue to use interrupts to signal the availability of data from human input devices. Therefore, the fastest and most direct way to access this data is to write an assembly language ISR. The difficulty is that embedded systems programming such as this requires specialized technical knowledge on the part of the programmer.
Clearly the Ocaml solution posted will ease the burden on the coder, and that is a good thing. But the way it works is not that it no longer uses ISRs. It almost certainly implements its own ISRs and polling routines. In this way, it will be like a library. The beneficial result is that individual programmers do not have to reimplement the ISRs. But there is no benefit in, and no possibility of, eliminating the very needed ISR itself.
Personally, I question whether the MCUs selected for the Arduino are appropriate for the "cute tech" market that the Arduino-series-PCB-module (a.k.a. "shield") manufacturers seem to be going for. Possibly the availability of Ocaml will bring the platform more in line with, e.g., the BasicStamp or similar. Overall, I see an impedence mismatch between what people would like to do (make costumes) and what they get (asking their friends to write code for them).
The fundamental first step will be describing to the Ocaml environment how it is that the peripherals have been wired to the chip. Then the Ocaml environment can, presumably, service these interfaces either through ISRs or polling. We'll see what transpires in simplifying the Arduino software landscape.... ;)
Reasonable enough. (Score:4, Interesting)
Good idea. I'm impressed that they were able to cram Occam into an Atmel ATMega. Occam syntax is rather clunky by modern standards, but it gets the job done. It has a sane concurrency model and is safer than C.
Next, Ada?
Re:That kind of thinking... (Score:5, Interesting)
Isn't this kind of thinking that lead us to why we have the security holes, shoddy programming, and bloat-ware today? People just want to code and not to learn the ins and outs required to craft a well-heeled, tuned, and functioning program or application?
Repeat after me: programming languages and frameworks do not make developers dumber. It's this kind of thinking that forces every developer-user of a complicated system to be continually faced with issues outside of their domain of expertise, or even just the current problem focus. *That's* what causes these problems.
For example, when doing embedded programming some years back, I noted that team members working on codec optimization were starting to crank out bad, broken ad-hoc synchronization logic to take advantage of some unique parallel hardware. Their specialties ran into numerical analysis and implementing low-level numerical optimizations, not into synchronization algorithms. I could take these folks and run them through an OS class, and walk them through the inevitable sea of mistakes...
Or I could do what I did: I created a framework that abstracted away all of the platform synchronization concerns. They did their jobs neatly and cleanly by writing a class that contained some shared state and implementing just two virtual methods that embodied the parallel work. They were much happier, and the whole team was much happier because there was now *one* place to look for synchronization bugs. This was quickly hammered out into a very stable foundation for the other teams' work.
Allowing our programming languages, libraries, and frameworks to do the heavy lifting so we humans can focus on the real problems we want to solve pretty much describes the history of real progress in software development.
Re:Parallax Propeller (Score:3, Interesting)
Very true. I've done 2 games with the Propeller, and hit the 8 core ceiling both times. So a lot of people are now doing projects with 2 (or more) propellers.
Maybe not a great choice for production electronics. But great fun for tinkering and one off projects.
Re:Parallax Propeller (Score:3, Interesting)
"I'm somewhat familiar with the Propeller. Parallelizes quite well up to eight simultaneous tasks. Nineth? Well, turn back around and back to hell."
In that case take a look at the XMOS chips. Each core supports eight hardware threads and there are 1, 2, and 4 core versions available. Each core runs at 400 MHz. With the 4-core chip, you have 32 hardware threads to work with. Need more? No problem, just add more chips and connect them using the built-in Links hardware. XMOS sells a development board that has 16 of the 4-core chips for a total of 512 hardware threads.
The development tools (IDE, compiler, debugger) for Windows, Linux, and OS X are free downloads from the XMOS site. XMOS has added parallel processing capabilities to C (calling it XC), but the development tools also support C, C++, and assembly. JTAG units are US$50, which is quite reasonable.
Check it out: www.xmos.com www.xcore.com
Disclaimer: I have no relationship with XMOS except as a satisfied customer.
Artists are NOT going to be programming AVRs (Score:3, Interesting)
I'm an AVR programmer. I prefer to work with assembler, because I come from an electronics background and assembler is closer to the electrons. I can, and occasionally do, work in C on the AVR and Visual BASIC on the PC.
Let me say, this stuff is hard. It's hard for programmers and electronic technicians. It's really hard for hobbyists and people who have little technical background. Artists are not going to be programming AVRs to make cool performance art projects with Arduinos. OK, maybe one or two, but not many.
Even rock-bottom beginning simple stuff like blinking an LED or making a beep when a button is pressed can be challenging on a microcontroller. It's not hard to know what to do; it's hard to actually do it and make it work 100% all the time.
Your average guy or performance artist is NOT going to be making a cat door that won't let the cat in the house with a mouse. Let's see, the cat pushes on the door with its nose. This flips a sensor that activates a camera that relays an image of the cat's face to a microcontroller. The MCU parses the pixels to determine that the image sector of the mouth of the cat is significantly different from the analysis of previous images of the cat's face. The door won't open.
Now if you're reading this, then yes, you can program something that might be able to do this. You're a Slashdaughter, for Christ's sake, you can do anything technical, and you know it.
But you wouldn't be able to do it on a $1.59 microcontroller. And you sure wouldn't be able to do it if you didn't have thousands of hours of programming experience and technical training.
It doesn't matter what language or integrated development environment that you use, it's just not going to happen.
And frankly, most of the cool projects that performance artists want to do with computers would require a real gigahertz/gigabyte/advanced_OS PC to do, not an 8-bit microcontroller with 1K of RAM that can just barely run a microwave oven, let alone a telephone.
Performance artists want professional-level programming ability and talent at bargain-basement artists prices. But if you're not a beautiful woman into performance art who has the ability to hook up her beautiful friends to nerdy techno-geeks who actually do the programming, it's unlikely to happen.
Re:That kind of thinking... (Score:3, Interesting)
I was thinking more that all Engineering degrees require a combined combined LEGO/Mecchano device as a final-year project (to demonstrate interoperability), with internship at LEGOLand.
Re:Threads (Score:2, Interesting)
C can do you wrong (Score:3, Interesting)
#define SET_PIN12(z) ((z)>0)? PORTH |= (1 << 3) : PORTH &= (0 << 3)
Then usage would simply be like the following:
SET_PIN12(1);
SET_PIN12(0);
There are some problems with this. ((z)>0) will not do what the programmer intended if z, an int, is negative. And there's no need to test for Z being non-zero. The expression should be replaced with z alone.
The first statement of the conditional if, (1 << 3) : PORTH, works fine as it sets the desired bit to 1 while leaving the other bits as-is. But PORTH &= (0 << 3) resets ALL 8 bits to zero. I suspect he was thinking that (0<<3) is 11110111.
In any case, PORTH &= 0b11110111 functions properly. (The Arduino language is a subset of C++ with a few additions.) A simpler version is
#define SET_PIN12(z) (z ? PORTH |= (1
Another example. This is their code to read an input on pin 13. (Pin 13 has been set as an input pin.)
#define READ_PIN13(z) ((PINL & 0x08) > 0) ? (z) = 1 : (z) = 0
Usage would be
READ_PIN13(temp);
So we have
(z) = 0;
(z) = 1;
being executed. I didn't realize this would compile.
The macro functions correctly but I simplified it and changed its usage from a conditional if to to a simple assignment
#define READ_PIN13 ((PINL & 0x08) > 0)
//
temp = READ_PIN13;
I was tempted to simply further to
#define READ_PIN13 (PINL & 0x08)
But since there was a lot of this kind of (proper) code I didn't go that far.
#define HIGH 1
//
temp = READ_PIN13;
if (temp == HIGH) {... // tests temp == 1, versus "true" (non-zero)
After looking through lots of code on the web sites it got me thinking about how easy it is produce C code with unintended consequences.
Interesting, (Score:3, Interesting)
This is interesting and I hope that it helps bring in new people to the embedded field. Having easy tools to introduce people to a system can make a big difference in the learning curve. Once they get hooked they can start to learn how to do things manually.
For things like the ARM, Blackfin, etc. having multitasking is a huge benefit. But on lower end systems like PIC, AVR, etc. it's really just for show and tell.
I have a fair bit of experience programing these low end devices and the golden rule is ISRs (Interrupt Service Routines) for everything. Everything should be done via ISRs, and when not running an ISR the chip should be in low power mode. A lot of embedded systems are battery powered and they simply don't have the power to waste on things like polling. If you have no choice but to poll (and there are very, very few cases for this) then use a timer ISR. Additionally ISRs give you interrupt priority and hard-realtime responses, something that many applications (especially safety) require.
Putting occam on Arduinos should help people get started on these devices, but I seriously doubt it will see any use in the professional world.