Go here to sign up for The Embedded Muse.
The Embedded Muse Logo The Embedded Muse
Issue Number 465, March 6, 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). The normal rate for people signing up in March is $190, but for Embedded Muse readers it's just $90 if you use promo code MUSE2023. The regular price goes to $290 in April, though the $100 discount will still apply.

Quotes and Thoughts

To invent, you need a good imagination and a pile of junk. Thomas A. Edison

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.

Are you aware of electromigration? Though we think of ICs as elements with an almost unlimited life, they do wear out. A recent article claims that for every 10°C above 100°C their life falls in half. Most of us are not designing circuits that run that hot, but a little noodling with Black's equation suggests that mean time to failures is highly temperature dependent, even well below 100°C. Electromigration is a very complex topic, though, and it's not clear that it would be an issue for parts not made with bleeding-edge geometries.

Regarding the recent Muse discussions about binary editors, Brian Cuthie passed along this interesting link to an open-source product.

Incrementing Build Numbers

Bob Paddock sent along a nice way to manage build numbers. Normally I would format the make file with the PRE html tag so it looks like code, but Dreamweaver, my least favorite program, is gorking on this. Here's the idea from Bob:

It is possible to create a simple incrementing "Build Number" purely with Make.

It is a lot easier to deal with a simple number than SHA1 hashes, if it is to be used as parts of file names or showing to Humans in a boot message.

Make will keep the build number in a file that looks like this:

# Automatically generated file - do not edit

#This section  assigns the name to the above file, once the $(TARGET) name has been established:

# After the target name has been defined
# create a prefix name for the project buildnumber file.
ifeq ($(TARGET),Project_FOO)

ifeq ($(TARGET),Project_BAR)

# $(TARGET) could also be used directly as the prefix.

Some place before final linking is done place this:

# Auto-incrementing number, which may be used in version numbers:
include $(BUILDNUMBER_PREFIX)_buildnumber
NEW_BUILDNUMBER := $(shell echo $$(( $(BUILDNUMBER) + 1 )))
$(info )
$(info Buildnumber = $(NEW_BUILDNUMBER))
$(info )

# Pass on Buildnumber to C:

Then at the point of final linking add the lines that update the build file's
contents for the next run:

# Link: create ELF output file from object files.
echo $(LINKING_MSG) $@ [$(TARGET_DIR)/$(TARGET).elf]

[Project Required Linker commands here.  Then add:]

# Update the Buildnumber for the next compile cycle:
echo "# Automatically generated file - do not edit" >

This does break the idea of reproducible builds.
Since that is already broken I go full in and add the Date and Time of the build:

Some place, such as before main() lives:

const char Date_Prj_str[]       = __DATE__;
const char Time_Prj_str[]       = __TIME__;

const uint16_t BuildNumber_value = NEW_BUILDNUMBER;     /* Build
number that can be found in the .elf file */

uint16_t build_number_get( void )

The Date, Time and Buildnumber clearly identify the embedded code in a human readable format, that can be output to a debugging terminal, shown in a boot message etc.

For those unaware __DATE__ and __TIME__ are part of the C Standard, which define human readable strings.

I don't claim originality for the Buildnumber concept.  It has been in my Makefiles for so long I don't know who to credit.

The only downside I've ever encountered is I was once left wondering why changing a comment in a file changed the CRC of the resulting output, until I remembered the Date/Time/Buildnumber code.
The Rust Language

Brad Nelson is a fan of Rust, and has kindly sent this take on the language:

I agree with you that Rust has many compelling features. After learning and using Rust at my current job in embedded Linux applications, there's something about it that I've not experienced in any other language.  As languages go, the Rust environment stands at the apex of modern developer solutions: build repeatability, library management, versioning, feature gates, deployment, linting, code style formatter, static analysis, cross-platform support, compiler message clarity, documentation autogeneration, on and on ... the list of built-in workflow features truly is long and comprehensively covers so many things experienced developers have spent entire careers creating manually for C/C++.  And then start over from scratch with new toolchains at their next employer, ha!

While you are correct there is no ANSI standard for Rust, it is not the "wild west" one might gather from your comments.  It has always been backwards compatible for me, rather it oddly has the inverse problem of most legacy code - all older code compiles just fine, it's only newer code (usually that library that you too-easily pulled in) that uses constantly improving features, which requires the latest compiler.  As opposed to older code requiring older compilers.  Rust does not deprecate compatibility.

There is something magical about Rust.  It takes a long time to get your code to compile, especially early on.  But then an amazing thing happens.  Your code just works.  It doesn't run for 5 minutes and then crash, it doesn't print garbage in your terminal.  Sure, there are application logic problems, but solving those problems has customer value.  Solving a buffer overflow, type conversion error, concurrency, or undefined math operations due to mismatched types are where many of us have spent most of our careers.  The latter category of problems bring zero product value to customers.  They don't go away entirely, but they are greatly diminished by compile time checks and that decreases the overall cost of development.

After learning Rust, I do wonder if I've ever made a C/C++ program that actually ran how I thought it did.

I haven't used Rust in truly embedded MCU applications yet, however I'm very excited to experience the Rust embedded-hal, which is a well-defined MCU- and middleware-agnostic abstraction that is picking up speed.  With Rust's extremely strong type system and traits, I expect great things on the embedded front in the coming years.

Embedded environments I have worked in have never had an integrated package management system that makes sharing code as trivial as Rust.  It literally takes seconds, not minutes or hours, and is tightly version controlled so you don't get blindsided with changes.

All the pros aside, I can completely agree Rust has risks that should be carefully evaluated.  Engineers with Rust skills are in short supply, the learning curve is steep.  The trade-off between "I can ship crappy C code, I cannot ship crappy Rust code" means there's inevitable linkage between quality and total development time is less severable in Rust applications.  And that limits business and market timing decisions, and is especially painful if agile principles are not applied well organization-wide.

Or, said tongue-in-cheek but frankly - it's not for organizations that don't culturally value quality.  Rust as a technology will swim against the current.

My experience has been the risks are lower in the technical and feature capability side than one might think.  (Recall the library system - it's nascent but surprisingly large, and due to the type, trait features and package management system, code reuse is far more attainable and robust than C/C++. Foreign language bindings also make using legacy C/C++ in Rust reasonably easy.)  The higher risks I see are mostly around resource availability and putting novice Rust programmers altogether on a greenfield project at once.  It's harder to pivot and iterate in Rust if the project requirements are unclear/constantly morphing.  Novice developers will struggle to think in the higher systems engineering plane when they are learning basics.  If the architecture is not designed up front to handle rapid prototyping iteration - you can quickly find yourself fighting the compiler against lifetimes and types, which impedes rapid prototyping.  Again, this risk should be weighted against how well both the engineers and the company are at thinking in small, releasable product quantizations.

For this engineer, Rust has proven its mettle and its widespread adoption seems a matter of when, not if, in the embedded space.  It's in our nature as engineers to graft ourselves into the most efficient systems.  Not today, but I do see an inflection point in the near future.  Many an embedded engineer's pipe dreams of today are delivered on a silver platter by Rust.

Security by Fiat

Despite many temptations to use the platform of the Muse as a place to rant about politics, I don't, and won't, unless perhaps in a future final issue I chose a Viking-like bit of virtual self-immolation before sailing off into the sunset.


The US's current administration is (quite rightly) addressing the issue of infosec. They've issued a national cybersecurity document that is long on tropes but rather lacking in specifics. One paragraph, though, bears on the embedded space:

The Administration will work with Congress and the private sector to develop legislation establishing liability for software products and services. Any such legislation should prevent manufacturers and software publishers with market power from fully disclaiming liability by contract, and establish higher standards of care for software in specific high-risk scenarios. To begin to shape standards of care for secure software development, the Administration will drive the development of an adaptable safe harbor framework to shield from liability companies that securely develop and maintain their software products and services. This safe harbour will draw from current best practices for secure software development, such as the NIST Secure Software Development Framework. It also must evolve over time, incorporating new tools for secure software development, software transparency, and vulnerability discovery.

I'm not entirely sure what this word-salad means. It appears that developers, or at least their organizations, will be held accountable for insecure code. Unless, that is, that they conform to some unknown "standards" that I cannot imagine being specific enough to mean much.

There have been some examples of legislation leading to great code. Commercial avionics generally must conform to DO-178C, and, in general (yes, there have been a very few notable exceptions) the results have been impressive. And yet, we really don't know if that's due to the requirements of the standard, or to a culture that embraces safety at any cost.

The most critical avionics resembles embedded systems of years ago. Unconnected, some hacker in one of the 'Stans is not a problem. Now, when practically any net-connected transistor is a threat vector the most innocuous of products can be a gateway to chaos.

Though I appreciate an effort to address these issues, it's hard to see a way forward that works. Alas, "works" has to include market forces as products are made to be sold. Security costs money. When our perfectly-engineered device competes against one from China at half the cost with ten times the vulnerabilities, it's hard to see how we can be successful.

In many industries regulation works. The MGM Grand Hotel inferno in 1980 killed 85 people. Management failed to spend $192,000 to install a sprinkler system, as the code at that time did not require one. Estimates pegged the cost of the fire at a cool billion dollars. Today, the code would never permit a hotel without sprinklers. But I just don't see a practical way to mandate secure code. And even the best software still has an obvious failure mode: users. Social engineering is pretty difficult to overcome.

Failure of the Week

Harold Kraus sent this anomaly:

And this bit of fun is from Thomas Osbrink:

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


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.

Cesanta is looking to fill several positions in the embedded engineering field. Positions are fully remote and fulltime (but part time is also an option):

  • C/C++ Software Engineer [REMOTE]
    This position requires strong requirements gathering, design, coding and debugging skills, with a passion for developing high-quality and well-architected software.
  • C/C++ Junior Embedded Software Engineer [REMOTE]
    This position requires desire to learn new skills and work on requirements gathering, design, coding and debugging, developing high-quality and well-architected software.

Check us out https://cesanta.com/jobs.html.  Contact jobs@cesanta.com

ABB is hiring a Senior Embedded Engineer. The successful candidate will be in charge of firmware development for power monitoring devices for industrial applications.

You can find the job description here: https://careers.abb/global/en/job/85434682/-Senior-R-D-Engineer-f-m-d-Embedded-Systems

Embedded Engineer 
Rochester, NY 
This design and development position for multiprocessor control systems can see ARM through ATTINY hardware, and software mostly in C. 
Capabilities working in real-time systems within bare metal to small operating systems experience desired. 
FPGA, peripheral interface, and even the occasional web page and analog knowledge are appreciated. 
New product design opportunities are in-process and planned! 
Please apply at: https://recruiting.paylocity.com/recruiting/jobs/All/dab5060f-4102-4ef1-ad68-232f873f47e0/Ambrell-Corporation

Nova Tech Engineering designs, develops and markets automated system for agriculture industry, primarily in poultry and shrimp.  We have a team of embedded developers, and we are recruiting to add 1-2 more to our team. 


I'm the CTO at Kelvin (dba Radiator Labs), and our mission is to decarbonize legacy buildings. We have a PCBA for our radiator enclosure, and we have more devices coming in our future (Heat Pump, Thermal Battery, Remote Thermostat, etc.)

Looking for a very senior (principal level) firmware / embedded engineer with 14+ years of experience. 

Here's the LinkedIn Posting: # Principal Embedded / Firmware Engineer

Joke For The Week

These jokes are archived here.

Einstein, Newton, and Pascal decide to play hide-and-seek. Einstein is "It," closes his eyes, counts to 10, and then opens them.

Pascal is nowhere to be seen.

Newton is sitting right in front of Einstein, with a piece of chalk in his hand. He's sitting in a box drawn on the ground, a meter to one side. Einstein says, "Newton, you're terrible, I've found you!"

Newton says, "No no, no. You've found one Newton per square meter. You've found Pascal!"

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.