Welcome to the 39th issue of TMPDIR, a weekly newsletter covering Embedded Linux, IoT systems, and technology in general. Subscribe to future issues at https://tinyletter.com/tmpdir and pass it on to anyone else you think might be interested. Please send any tips or feedback to info@tmpdir.org.

Is there anything specific you'd like to hear about in future editions? Let us know!


Linux

Yoe i.MX8 support Story

We have started adding support into Yoe for i.MX8 boards -- particularly Varscite SOMs. Variscite's meta-variscrite-bsp layer is nicely maintained but is pinned to hardknott release (2021-04), where Yoe lives on the latest master branches. The yoe/master branch in Yoe's fork of this device layer is an effort to update the layer to support latest OE. meta-freescale, which provides the core i.MX8 support, is already well supported. So far, the update has gone really well and we're running wayland, LVGL, etc.

Clang 15 is around the corner

Clang 15 is next major release of the compiler and it has taken some bold steps -- e.g. to support C2X better it has removed support for Implicit function declaration and -Wimplicit-int is promoted to be error by default and the compiler now issues an error in C when a definition of a function without a prototype and with no arguments is an invalid redeclaration of a function with a prototype. This change has long ranging effects impacting many packages which now need to pay down their technical debt. Most interestingly, autoconf used these checks in interesting ways, so these checks can now fail and result in undesired build behavior. Autoconf has been fixed however this does mean that packages will need to regenerate the configure scripts using this patch or wait for next autoconf release. Fortunately in Yoe, we worry a bit less since OE does regenerate the configure scripts during builds and the needed autoconf patch is already applied to OE-Core.

Mangling of nested dependent names such as T::a::b, where T is a template parameter, to conform to the Itanium C++ ABI and be compatible with GCC. This breaks binary compatibility with code compiled with earlier versions of clang; use the -fclang-abi-compat=14 option to get the old mangling. Here are detailed Release Notes.

OE-core has been preemptively fixed as well as meta-openembedded layer to compile with clang-15 except few packages e.g. wekbit.


IoT

The Start()/Stop() pattern

IoT edge applications typically have a number of moving parts -- reading sensors, talking to devices over interfaces such as Modbus/1-wire, managing network connections/modems, and the list goes on. So you end up with a dozen or more long running threads. Additionally, the configuration of the device may change at any time. This is a highly dynamic system and it becomes imperative that the lifecycle of these various pieces be managed in a way that you don't end up with race conditions or leaks, which may destabilize the device. Concurrent code is hard. Getting to a simple solution that is reliable and easy to think about takes time. For me, this ended up at the Start()/Stop() pattern. The basics are:

  • any long-running thread needs a way to reliably stop() it.
  • you need to know when a long running thread stops and why.
  • the interface for long running threads should be synchronous. The caller can start threads/go-routines if needed.
  • in Go, channels should be used to synchronize access to state in a common select{} statement. Mutexes should rarely be used unless you have special performance requirements.
  • the essence is simple -- start() is called and blocks until the process is done and then returns an error. stop() simply sends a signal to start() to clean up and exit. stop() does not return anything.

The result is so simple that it appears trivial. However, simple is hard. Whenever you see something simple -- especially with concurrency and lifecycle management, it probably some effort to get there.

The alternative to the Start/Stop pattern is to pass around callbacks or channels through APIs. We all know from Javascript programming how painful callbacks can be. And passing channels through APIs in Go is a recipe for complexity that does not fit in a normal person's brain. Channels or callbacks in APIs (at least for lifecycle management) may be a code smell.

Do you need a way to reliably manage the different parts of your application? Check out the Start()/Stop() pattern.


Other

Brendan Eich created Javascript and has been involved with browser platforms for years. Here are two podcasts where Brendan talks about one of the most import technology platforms ever -- the browser.

When working on a hard problem or a large implementation task, having a notes system while working on the task is a helpful habit.

Measure value, don't value what you measure -- an interesting article about community building.


Quote for the week

There is no elevator to success, you have to take the stairs – Zig Ziglar


Join our Discourse forum to discuss these or new topics. Find past issues of TMPDIR here. Listen to previous podcasts at https://tmpdir.org/.

Thanks for reading!

Khem and Cliff