Skip to content

Announcing Zig•EM v25.0.1

With support from The EM Foundation, we announce the initial release of Zig•EM – a novel programming framework for developing and deploying applications which target resource-constrained MCUs, where every byte of memory and every μJoule of energy matters.

Setting expectations

As rationalized in our previous post, Zig•EM strives to reconstitute  core concepts and constructs of the EM Programming Language into Zig – a system programming language favorably compared with Go and Rust, but with the simplicity and transparency of C.

But downgrading the EM language into a programming framework hosted by Zig does introduce some challenges.  For one, the Zig language itself remains a work-in-progress; reaching an "official" Zig 1.0 release will realistically require years of effort.(1)

  1. see Andrew Kelley's Zig 2024 Roadmap talk

Furthermore, Zig eschews much of the "syntactic flexibility" (operator overloading, optional lexical elements, etc) found in contemporary languages ranging from C++ to Ruby – leaving us with a somewhat rudimentary set of programmatic mechanisms to realize Zig•EM.

As a stand-alone language, EM could introduce keywords like config and proxy to reinforce its novel concepts; and EM's language translator could impart very specific meanings to otherwise stock programming constructs like module and interface.

Grafting EM onto Zig, however, requires us to operate within the syntactic and semantic constraints of the latter language.  Ensuring that EM's concepts and constructs don't become "lost in translation", so to speak, emerges as our greatest challenge.

FULL DISCLOSURE – My first impressions of Zig

Six months ago, I hadn't even heard  of Zig !!  In the interim, of course, I've not only immersed myself in the language but also managed to field my first iteration of the Zig•EM framework.

To understand my ever-growing fascination with Zig, let's roll the clock back to the 1980s – a time in which C had firmly established itself as a universal "middle-level" language – used for system programming on 8-bit microprocessors, 16-bit mini-computers, and 32-bit mainframes alike.

Like Zig, the C language has no inherent runtime environment supported across all target processors.  Building upon a "bare-metal" foundation, libraries of C functions (general-purpose or domain-specific) would address the runtime needs of a broad range of applications.

Programmers generally characterize both C and Zig as inherently small  languages – embodying a set of rudimentary mechanisms for constructing higher-level libraries, while staying close to the underlying hardware.  As a consequence, C and Zig can remain maniacally focused on performance.(1)

  1. Andrew Kelley (the language's creator) refers
    to Zig as a DSL for emitting machine code.

Pursuing an analogy, I've always viewed C as a "small town" – one whose streets and neighborhoods I've come to know like the back of my hand.  By constrast, C++ has morphed into a "big city" – one with more streets than I could ever explore, and one with certain neighborhoods that the guide-books now tell me to avoid !!

By maintaining a level of "small town" simplicity lacking in many modern compiled languages, Zig has emerged as a worthy alternative to C.  This aspect of Zig also earns the language high-marks when compared against the complexity of Rust – another "big city" language that looks to supplant C++.

And finally, I can't say enough about the warm and welcoming Zig community I've joined at Ziggit – where you really do feel that "small town" vibe.  😎

Getting started

We've updated this material to reflect the latest release of Zig•EM

You can provision Zig•EM v25.0.x on your host computer(1) in three simple steps:

  1. presently – windows-x86_64, linux-x86_64, macos-x86_64

  download/unpack Zig v0.13.0, and add the zig command to your path
  download/unpack the latest Zig•EM sources, and cd into zigem-dev/workspace
  execute zig build, which will compile/install the Zig•EM CLI program

When finished, verify your installation by executing zig build verify:

[zigem-dev/workspace]
$ zig build verify
compiling META ...
    board: LP_EM_CC2340R5
    setup: ti.cc23xx://default
compiling TARG ...
    image sha: 57a5b811
    image size: text (1376) + const (364) + data (12) + bss (4)
done in 4.79 seconds

You should install Git for Windows, which includes the Git Bash shell as well as other stock CLI tools.

Going forward, we'll rely upon the zig build zigem sub-command to compile designated Zig•EM programs targeting a particular MCU.  For example, the following command explicitly compiles our verification example:

[zigem-dev/workspace]
$ zig build zigem -- compile -f em.core/em.examples.basic/BlinkerP.em.zig
compiling META ...
    board: LP_EM_CC2340R5
    setup: ti.cc23xx://default
compiling TARG ...
    image sha: 57a5b811
    image size: text (1376) + const (364) + data (12) + bss (4)
done in 4.67 seconds

Consider creating a zigem command-line alias for the zig build zigem -- prefix shown above

Exploring Zig•EM

Zig•EM supports just one target at this time – the Texas Instruments CC2340R5 wireless MCU featuring a low-power Arm Cortex-M0+ CPU, a familiar suite of embedded peripherals, and a generic 2.4 GHz radio with BLE 5.x support.(1)

  1. While EM itself has supported dozens of 8/16/32-bit MCUs over the years, let's first focus on "getting Zig•EM right" before we branch out to other hardware platforms.

We strongly encourage you to purchase an inexpensive LP-EM-CC2340R5 board from TI in their popular LaunchPad  form-factor.  In addition, you should obtain this emulator board if you don't already have TI-XDS110 support through another LaunchPad.

You'll also need to download TI-UniFlash and install the application at its default location.

Armed with target hardware, we can now compile and  load our sample program by simply appending the --load (-l) option on our command-line:

[zigem-dev/workspace]
$ zigem compile -f em.core/em.examples.basic/BlinkerP.em.zig -l
compiling META ...
    board: LP_EM_CC2340R5
    setup: ti.cc23xx://default
compiling TARG ...
    image sha: 57a5b811
    image size: text (1376) + const (364) + data (12) + bss (4)
done in 4.91 seconds
loading...
done.

Use  zigem --help followed by  zigem <COMMAND> --help to learn more about the Zig•EM CLI.

The em.core/em.examples.basic sub-folder contains over a dozen sample programs – each of which you can now compile and load onto your LP-EM-CC2340R5 hardware.  While these programs do little more than blink LEDs, start immersing yourself in their overall structure:

em.examples.basic/BlinkerP.em.zig
pub const em = @import("../../zigem/em.zig");
pub const em__U = em.module(@This(), .{});

pub const AppLed = em.import.@"em__distro/BoardC".AppLed;
pub const Common = em.import.@"em.mcu/Common";

pub const EM__TARG = struct {
    pub fn em__run() void {
        AppLed.on();
        for (0..10) |_| {
            Common.BusyWait.wait(500_000);
            AppLed.toggle();
        }
        AppLed.off();
    }
};

Our next few blog posts will deep-dive into this and other examples – focusing on core concepts and constructs first introduced in EM , but now seen through a Zig language lense.

Browsing the Zig•EM sources using VS Code

The VS Code - Zig Language extension goes a long way towards streamlining your exploration of Zig•EM through features such as syntax highlighting and code navigation; a companion language server (ZLS) enables outline views, hover help, and intellisense completion.

At the same time, the Zig Language extension knows nothing about the Zig•EM framework per se; the extension renders BlinkerP.em.zig no differently from build.zig or any other Zig source file.

We'll now released a fork of the Zig extension and language server which (through some minor modifications) has rudimentary awareness of Zig•EM.  As illustrated by the example above, files like BlinkerP.em.zig would now have their EM-based constructs distinctly highlighted – further flattening your learning curve.

Looking ahead

skill-up on the Zig language, using Karl Sequin's Learning Zig as a starting-point

spend some cycles browsing the zigem-dev snapshot downloaded earlier

direct all questions/comments to this showcase post on the Ziggit forum

Happy coding !!!   🌝   💻