Announcing a New Embedded Software Site: Embedded.fm/blog

I’m excited to announce that Elecia White, Chris White, Andrei Chichak, and I have started collaborating on a new embedded software engineering blog over at Embedded.fm/blog.

It’s slightly related to the Embedded.fm podcast because it’s about embedded software and embedded systems, but most the content will be separate from the podcast.

Andrei and I will both be writing about getting started in embedded systems (using two completely different approaches), Elecia will be sharing excerpts from her upcoming book about taking apart toys, and Chris White will be talking about various projects. Hopefully there will also be entertaining embedded-ish rants.

Please stop by and check it out! I’ve had a blast reading pre-published stuff that will show up on the blog, and I hope that you’ll enjoy it too.

Why C Arrays Start at Zero: I Don’t Know.

Why do C arrays start at element zero? It’s probably not why you think.

Mike Hoye did a detailed investigation here: http://exple.tive.org/blarg/2013/10/22/citation-needed/

The TL;DR is that Hoye says most programmers think C has zero-indexed arrays because the creator of C chose zero for the run-time efficiency of pointer and array arithmetic. Hoye says this is wrong; he claims that C uses zero-indexed arrays because its predecessor BCPL used them, and that BCPL chose zero-indexed arrays for compile-time efficiency. (I’m not convinced by his technical arguments, by the way, but that’s beside the point I’d like to make.)

The history of zero-indexing is interesting if you enjoy reading about the history of programming languages. Otherwise it’s hardly notable.

Except.

Except you probably thought you knew why C arrays start at element zero. “Well, it’s because pointer and array math are efficient when starting at index zero.” If asked, you’d probably say it confidently, definitively, as a Fact with a Capital F. You might even be correct, but you’re only guessing.

Hoye goes on to say that programmers who think they know something as Fact without actually knowing it are living in a “mythology.” They’re fooling themselves and others.

The honest answer to “why zero?” should probably be “I don’t know.” Perhaps followed by, “I think it makes some pointer and array operations more efficient at the machine level, but I don’t know why Dennis Ritchie chose it when he created C.”

We don’t use the phrase “I don’t know” often enough. Maybe we’re afraid of being thought of as dumb or ignorant or more junior than we want to appear, or maybe we’re afraid of being found out as impostors.

Recognizing and admitting your ignorance is one of the fastest ways to learn. Recognize and admit when you don’t know something, at least to yourself.

Why did it take me 20 years of being a software engineer to realize how important this is?

I don’t know.


 

I wrote this piece for Embedded.fm (http://embedded.fm/blog/2016/2/9/why-c-arrays-start-at-zero) and am cross-posting it here.

Empathy Driven Development slides

Here are the slides from my Embedded Systems Conference 2015 talk on Empathy Driven Development:

Empathy Driven Development slides (pdf)

The slides include a rough transcript of what I said.

I had a great time giving the talk and discussing it with others at ESC.  I’ve given this talk a number of times for software engineers, electrical engineers, mechanical engineers, and a few mixed groups as well, and I’ve learned that it applies to almost any engineering group.

I’ve had a few requests to give the talk for people’s teams & companies and to explore what it might look like in your particular environment, which I’m happy to do. Please email me at svec at this site if you’d like to arrange a visit to your user group/meetup/team/company.

Thanks!

 

Edit: I reduced the pdf file size (and image quality) so the pdf is now 2MB instead of the previous 50MB.

Computers are the wrong smartness.

From Isaac Asimov’s 1975 short story “Point of View,” talking about Multivac, a malfunctioning computer:

“…if Multivac were as smart as a man, we could talk to it and find out what was wrong no matter how complicated it was. If it were as dumb as a machine, it would go wrong in simple ways that we could catch easily. The trouble is, it’s half-smart, like an idiot. It’s smart enough to go wrong in very complicated ways, but not smart enough to help us find out what’s wrong. And that’s the wrong smartness.”

That accurately describes most computers and software today, almost 40 years later: they’re the wrong smartness.

Learnable Programming, Bret Victor, and Other Two Word Phrases

Bret Victor just published his latest essay, “Learnable Programming.”

In “Learnable Programming” Bret criticizes the Khan Academy’s latest “interactive” programming education tools and suggests a better way to teach programming.

He footnotes the essay with this summary:

This essay was an immune response, triggered by hearing too many times that Inventing on Principle was “about live coding”, and seeing too many attempts to “teach programming” by adorning a JavaScript editor with badges and mascots.

“Inventing on Principle” was the talk he gave at CUSEC 2012.

If you haven’t seen/read both you must immediately:

  1. Get a cup of coffee, tea, or whatever comfort beverage you prefer.
  2. Find a comfortable place to sit and pay attention for about two hours.
  3. Watch the video of Inventing on Principle.
  4. Read the Learnable Programming essay.

It’s fantastically worth your time.

Bret sidenotes* the essay with this exciting teaser:

Forward reference: Some work that I’ve done in automatic visualization of ad-hoc data structures will be published later this year, in collaboration with Viewpoints Research.

I’m looking forward to that!

* I just invented the verb “sidenote,” as in, “He sidenoted the heck out of that teaser in the side note.”

Embedded software and open source

Embedded guru and author Jack Ganssle’s latest “Embedded Muse” newsletter has a lot of good commentary on open source in embedded software projects:

http://www.ganssle.com/tem/tem199.htm

I subscribe to very few newsletters, and Jack’s is one of them.  I read every issue, it’s that good.

If you work in embedded software, or software of any kind, you should subscribe!  (I don’t get anything if you subscribe, I just think it’s a worthwhile read.)

While I’m in fanboy mode, I’ll also recommend Jack’s other articles – click on a random one, you’ll probably learn something. My personal favorite is his guide to debouncing.  He does some good experiments and then shows hardware and software solutions to the pesky debouncing problems we embedded folks face.

Assigning Task Priorities with RMA

Embedded gurus Michael Barr and David Stewart have written a couple of great articles about assigning task priorities with RMA (the Rate Monotonic Algorithm):

  1. Introduction to Rate Monotonic Scheduling, by David Stewart and Michael Barr
  2. 3 Things Every Programmer Should Know About RMA, by Michael Barr

The first article lays out the basics: RMA is an algorithm that assigns static priorities to periodic tasks in order to maximize “schedulability.”  That’s a mouthful: 16 words, 37 syllables.  And one of the words isn’t real: “schedulability,” which means “able to be scheduled so that all tasks complete before their deadline every time.”

Let’s try again: RMA helps tasks get done in time.  That’s better: 7 words, 9 syllables.

The second article expands on the basics of RMA, giving some additional guidelines for when it should be used, especially as it applies to interrupts (which it does!).

I want to talk a bit more about the basics of RMA.  RMA is easy to describe: a task’s priority is based on how often it runs.  The task that runs the most often gets the highest priority, the task that runs the second most often gets the next highest priority, and so on.  Or, to quote the first article, “Assign the priority of each task according to its period, so that the shorter the period the higher the priority.”

RMA does not guarantee that your tasks will all complete in time; RMA does guarantee to find the optimal static prioritization assignment if one exists.  If RMA doesn’t produce a “schedulable” task set then no “schedulable” static priority scheme exists.

RMA’s greedy nature makes intuitive sense: starting at time zero, assume all tasks are ready to run.  Then run the task with the shortest period.  Since this task runs more often than any other task, it “feels” right to run it first to give it the best chance of finishing before it has to run again.  Next run the task with the next shortest period, and so on, until all tasks have been run.

Fortunately the intuition and “feel” that RMA works is backed by the fact that it does!

I’ve given a very basic overview of RMA here.  Please check out Stewart and Barr’s articles for more about RMA.

Technology vs. Psychology

Do you write software for a living?  Or design hardware?  Or maybe some of each?  While the particular projects any two software or hardware designers do may be worlds apart, we can characterize what we do in the same way: our work is 20% technology and 80% psychology.

Most of the work we do is 100% solvable – it “merely” requires people and time to accomplish.  It may be difficult, it may be risky, but it’s doable.  Most projects don’t require quantum leaps in technology to accomplish – current hardware and software platforms will do just fine, thank you.  Most projects don’t fail because the IDE wasn’t up to the task, or the compiler, or the linker.  Most projects fail because of the carbon-based part of the tool chain, not the silicon-based one.

All projects have some inefficiencies and problems.  They always start small but aren’t life- (or project-) threatening:

  • The build process is manual and annoying, and therefore error-prone; but most engineers run it before checking in new code, and the errors are always found quickly enough.
  • Code drops from external groups happen less frequently than we’d like, but it’s been okay so far.
  • The external contracting team has found a few bugs in the spec, but it’s nothing that can’t be fixed later, and we don’t have time to check the spec right now.

None of these problems will doom your project on their own.  And because you can live with the status quo, you won’t fix them now.  “I’ll get to that later when I have more time.”  But as the problems multiply, build in intensity and (gasp!) start to constructively interfere with each other, your forward progress will slow down.  It will take longer and longer to do what used to be quick tasks.  Many aspects of the job will become more frustrating, and morale will go down.

Inefficiencies and problems don’t persist because we lack the appropriate technology to fix them – they persist because we lack the appropriate psychology to fix them!

That’s an important thought, so I’m going to repeat it:

Inefficiencies and problems don’t persist because we lack the appropriate technology to fix them – they persist because we lack the appropriate psychology to fix them!

How do we address the psychological aspect?  We need to trick ourselves into doing the Right Things in the Right Ways to make continual progress.

Here are two guidelines for doing the Right Things in the Right Ways:

  1. We MUST make activities that are good for the project as easy as possible and as enjoyable as possible. 
    • Can your pre-commit tests be run automatically?  Yes?  Great – do it!  Make sure they run reasonably quickly, with easy to read status updates.  When the tests are done and passing, can we help the user enter a helpful commit message by supplying a list of the diffs automatically?  Yes?  Great – do it!
  2. We MUST make activities that are bad for the project as difficult and miserable as possible. 
    • Checking in without passing all tests?  Okay, but you have to run this ugly command line, fill out the TPS reports on this slow web page, and get a note from your mom.  Consider making “bad activities” impossible.  Checking in without passing all tests?  IMPOSSIBLE!  Can’t be done.

Two of my favorite geniuses agree with me, so I must be right:

  • Albert Einstein said, “Everything should be made as simple as possible, but not simpler.” We need to worry about making our processes as simple as possible.  Don’t worry about making them too simple, I doubt we’ll get that far.   Can you make it simpler?  Yes?  Then do it!
  • Kathy Sierra said, “Make the right things easy and the wrong things hard.”  She says it much better than me – go read her post!

Of course sometimes we don’t have time to improve a process right now, because we (hopefully) have paying customers banging on the door, deadlines to meet, product to ship.  You’ve got to pick your battles and manage your time wisely.

But we geeks need to spend more time thinking about our psychology – the “how” and “why” of what we do – instead of just focusing on the technology – the “what” we do.

The earlier you find and fix inefficiencies and bugs in a product, the more time and money you save.  In the same way, the earlier you find and fix inefficiencies and bugs in the way you create a product, the more time and money you save.  But you get an extra bonus from improving the way you create a product because it produces not just a one-time boost, it produces a many-time boost!  It’s like compounding interest.  Actually, it’s not just like compounding interest, it IS compounding interest!

Define the problem, define done

I. M. Wright’s latest post “Green fields are full of maggots” talks about defining the problem and defining done.

My favorite quote (which is, itself, a quote):

“What’s so evil about general solutions? After all, your code could be both a floor wax and a dessert topping.”

He makes some great points about building software to solve a real, concrete problem, instead of building software as a semi-abstract-solution-that-could-solve-any-problem-possibly-the-one-people-are-paying-us-for.

My second favorite quote (second favorite only because it doesn’t quote Saturday Night Live) sums up the danger of the abstract:

“You put the problem at the center instead of the customer. When the customer isn’t at the center, your code loses its soul. It goes from being astounding to being adequate, from marvelous to mediocre.”

What is your goal?  Mediocre, or Marvelous?

How to tell you’re a bad programmer

How to tell you’re a bad programmer:

1. You think you’re an awesome programmer.

2. But no one else has ever told you so.

3. You’ve never looked at old code you wrote and thought, “Ewwww! That is horrible code! What was I thinking???”

4. You’ve never looked at someone else’s code and thought, “Dang, whoever wrote this is a freaking genius.”

Note that this also works if you substitute <other profession> for “programmer,” and <output of other profession> for “code.”

If you don’t see growth, it probably ain’t happening.  If you don’t see growth potential, it probably ain’t happening either.