Go here to sign up for The Embedded Muse.
The Embedded Muse Logo The Embedded Muse
Issue Number 468, April 17, 2023
Copyright 2023 The Ganssle Group

Editor: Jack Ganssle, jack@ganssle.com

   Jack Ganssle, Editor of The Embedded Muse

You may redistribute this newsletter for non-commercial purposes. For commercial use contact jack@ganssle.com. To subscribe or unsubscribe go here or drop Jack an email.

Editor's Notes


Tip for sending me email: My email filters are super aggressive and I no longer look at the spam mailbox. If you include the phrase "embedded muse" in the subject line your email will wend its weighty way to me.

The Embedded Online Conference is coming up in April. I'll be doing a talk about designing hardware and software for ultra-low-power systems (most everything one hears about this subject is wrong).

RIP Gene Ganssle (1927 - 2023). Mechanical engineer in the space program from its earliest days.

Quotes and Thoughts

It’s one thing to be able to write software; it’s another thing entirely to know HOW to write software. - Anonymous

Tools and Tips

Please submit clever ideas or thoughts about tools, techniques and resources you love or hate. Here are the tool reviews submitted in the past.

People are increasingly turning to Microsoft's Visual Studio for embedded work. Here's a good article about this.

Freebies and Discounts

The Active-Pro is a highly performance optimized “printf” debugger that captures detailed debug information sent from a single line of code in your firmware, and can contain the graphed values of variables and the exact timings of textual debug messages as they are executed. The folks there generously donated one for this month's giveaway.

Enter via this link.

AI - The Death of Software Engineering?

Much has been written recently about the latest AI products, like ChatGPT. Much of that is insightful. Much is hogwash.

A long and meandering article here posits that "Software production has been too complex and expensive for too long, which has caused us to underproduce software for decades, resulting in immense, society-wide technical debt." It goes on to claim that AI will largely automate software engineering.

First, the notion that software is "too complex and expensive" is silly. Sure, it's expensive. And complex. The complexity is what gives it value. A few lines of simple code can blink an LED. To do something useful, like guide a spacecraft, requires complexity. Ma Bell's black rotary-dial phone could make calls. An iPhone, with its complex software, has a universe of capabilities.

If it were "too expensive" no one would buy it. Yet the demand continues to accelerate. We all wish it were cheaper to produce, but no one is advocating an alternative.

One can argue that software is insanely cheap. What would it cost to build a machine that could implement Microsoft Excel if one were not allowed to use a programmable computer? Build it from AND gates - or cams and gears - and you'd have a device that filled a city, that consumed insane amours of power, and that had an MTBF of microseconds. And the cost? Incalculable, yet Excel today is cheaper than a tire.

The author writes about the difficulty of the grammar of programming languages, that compilers demand perfection in placing constructs like semicolons. Yet the grammar is not a problem for software professionals. We know it, inside and out, and though the compiler will complain about a mistake, these are quickly corrected. Few hard bugs are grammar related. Algorithms, race problems, and the like are where the real problems occur.

A couple of examples of AI-generated code are given. But these are toys. A few lines of code. This is the same problem that plagues so many academic papers on software, where three college sophomores write a few hundred lines of code, and the results are extended to say something not-terribly-profound about all of software engineering.

The examples I have seen of AI-generated code are not complex. All are tiny. They are to real problems what a matchbox-car is to a Tesla.

Old timers will remember the claims made about COBOL. It was so easy that pundits predicted programmers would be obsolete. Any money manager could whip up a bit of Cobol to run an entire department. What they missed so long ago, and that some AI advocates miss today, is that programming is not the problem. What's hard is problem analysis and design. Tending to the corner cases. Managing error conditions. Figuring out exactly what it is we're trying to do.

The toy problems we see AI addressing never seem to include commands to deal with all of the permutations of a problem. That's because expressing all of those possibilities is best done via, well, a programming language. By the time you tell the AI that the UV lamp's power must be modulated due to OSHA requirements, and a hundred or hundred thousand other nitpicking details, you've basically written the program.

When we address an AI in English we're framing a problem using an imprecise form of communication. It's easy to say X which is then interpreted as Y. Or, being human, we leave out a "not" or stumble over an adjective phrase, commanding the tech to create a design that is orthogonal to our intentions.

Everyone admits AI makes mistakes. Some silly, some profound. How will you know if the code from the AI is correct? Testing does not work. Test is only part of a QA strategy. No one knows how to test, for example, for security. To check the code you'd have to draw up a correct specification document, explore every nuance of every combination of conditionals in the software, trace its operation, and develop a complete understanding of what it is the AI generated. In other words, pretty much write the code.

AI can be brittle. Researchers demonstrated how changing a single pixel in an image can completely confuse an AI trained to recognize that image. One pixel out of millions!

I do think AI will be a great assistant for us. It will be able to mine OSS and suggest patterns. Maybe replace some routine operations like setting up configuration registers. But pulling code scoured from the net brings its own perils, as there's plenty of crap out there.

Perhaps in the future the technology will progress to the point where an uber-AI can create real, useful (i.e., complex!) software. In the meantime I think we're on the "inflated expectations" portion of the hype cycle.


In Muse 465 Brad Nelson discussed the merits of Rust. Another interesting language that has a somewhat longer pedigree is Python. Though there is an implementation targeting MCUs, mostly Python is found in embedded support code, like test harnesses.

I've been playing with it quite a bit recently. While I'm no expert, there are some interesting features I find compelling.

Outside of firmware most of my coding is for processing text files. Whether it's analyzing web logs, astrophotography data, or any of a myriad of tasks it seems there's always a set of files that need manipulation. Historically I used C via Visual Studio, but I find that tedious for the quick handling of many tasks. For many years I preferred Linux scripts, whether run on a Linux machine or via Cygwin under Windows. Awk, sed and a host of other utilities make it pretty easy to parse data.

But they are not great when one needs to maintain state information. Clumsy workarounds exist, but they can be so arcane that oceans of comments are needed to make one's intent clear.

Enter Python, an interpreted lingo, which means there's practically no friction between editing source and trying a test. The language is OO and structured. It has several interesting features. Like Basic it is dynamically typed and variables do not have to be declared before they are used.

Block structure is denoted by indentation, which the interpreter rigorously enforces. I find this strangely compelling. Careful C crafting means being meticulous with indentations, so it's something we already do. Why not eliminate the braces?

Blocks are also denoted by colons. An "if" statement looks like:

if minutes < 0:
    minutes = 0 - minutes
    inc = inc + 1

Note that all of the statements after the "if" that have the same indentation are part of the decision. Add a space before the "inc" and the interpreter will respond with an error message. However, one can use a single-line conditional:

if minutes < 0: print("minutes < 0")

Interestingly, one can include conditionals in other statements, like:

x = a if b else 0

(Which I find friendlier than C's ternary operator). Another form of this:

print a if b else 0  

For statements are similar, though you can't say something like for (i=0; i < 100; i++). Instead, for a simple counting loop one must use the range() function:

for x in range(11):
    line = input_file.readline()

In this case the loop iterates the specified number of times in the range().

Methods return arguments, of course, but can return multiple arguments. For example:

def something(argument):
    value1 = 2 * argument
    value2 = 3 * argument
    return value1, value2

which is called via:

a, b = something(data)

Note that the method returns multiple values. Kind of cool.

String handling, which for me is mostly what's going on with text files, is much easier than in C, though there are many similar constructs. Many methods are included for this. Formatting is powerful and simple; C folks will be very familiar with much of this.

One useful and quite interesting mechanism is the notion of dictionaries, where values are stored as pairs, and one can reference a value by its associated name. For instance:

dict =	{
    "brand": "TI",
    "MCU": "430",
    "timers": 2

There are a huge number of third-party libraries available for all sorts of specialized processing, from web scraping to scientific applications. I find there are so many it's a bit hard to find what one wants.

The interpreter does not error-check the code prior to execution; mistakes are flagged as a statement is executed. The error messages localize problems well and are informative. There are no grand hunts for missing semicolons and braces.

It's not possible to describe a programming language in a few paragraphs, but I hope you see that Python is an interesting option for certain kinds of problems. For me, I'm hanging up my Linux scripts in favor of this lingo.

Active-Pro Firmware Debugger

So many embedded devices hide much complexity inside a box with limited, or no, visibility. We developers struggle to see exactly what our creations are doing. With real-time systems, the question also extends to "when". A bench full of gear - oscilloscopes, logic analyzers, source-level debuggers and more - helps see into the arcania, but anything that increases our ability to peer into those sometimes inscrutable interiors is very valuable.

Enter the Active-Pro Firmware Debugger (the kind folks there gave us one of these products for this month's giveaway). It plays on the old idea of instrumenting your code. Printfs are useful, at times, but come with a lot of baggage in terms of memory usage and performance hits. Active-Pro provides simple functions you call to send data, in real-time, to the monitoring hardware. A key idea is that the system never stops; there are no breakpoints, the system runs while Active-Pro harvests data passed at high speed via these calls. It sends data out of your system via a 1-wire (UART) or 2-wire (GPIO) interface.

But there's more. The provided hardware is a combo oscilloscope, logic analyzer, and signal generator. So in addition to monitoring data sent via the function calls, it monitors and controls external signals. The unit's hardware is a small box that provides a number of I/Os

4 analog and 8 digital inputs are accepted, and the unit can generate a pair each of similar outputs.

The UI displays data from all of these sources, including the function calls.

Active-Pro UI. Click on this thumbnail to see a full-sized image.

The cool thing here is that you can see the world (scope, logic analyzer, etc.) plus events in your code which are being sent by the function calls. Instead of trying to correlate, in time, events from a bench full of instruments it's all in one display. The unit can monitor activity sent by up to four different MCUs.

A variety of function calls are included. Two will show the ideas. The first sends unformatted data; the second a formatted string:

ACTIVEValue ( 2,  ADCValue ); 
ACTIVEprintf ( 4, "%d: %d", index, data); 

Intriguingly, Active-Pro has a protocol decoder that the user can configure to understand pretty much any protocol, even proprietary ones. There's even a lookup table feature, which appears to allow one to transform signals from arcane binary values to strings.

There's far more information here, and the user manual is actually readable and complete. The Active-Pro is $649.

Failure of the Week

Have you submitted a Failure of the Week? I'm getting a ton of these and yours was added to the queue.

From Pedro Silva:

 Leon Bazdor sent this:


Let me know if you’re hiring embedded engineers. No recruiters please, and I reserve the right to edit ads to fit the format and intent of this newsletter. Please keep it to 100 words. There is no charge for a job ad.


Joke For The Week

These jokes are archived here.

I just found out Albert Einstein was a real person! All this time, I thought he was a theoretical physicist.

About The Embedded Muse

The Embedded Muse is Jack Ganssle's newsletter. Send complaints, comments, and contributions to me at jack@ganssle.com.

The Embedded Muse is supported by The Ganssle Group, whose mission is to help embedded folks get better products to market faster.