I’ve never programmed in Zig before, so I thought I’d give it a go on my microcontroller, which is an STM32F411 blackpill.
I’m using Debian Stable, which doesn’t have Zig on it. You can get Zig from the download page. I tried to build v0.9.0 dev version, but it required a more recent version of llvm than I had installed. So, instead, I used a precompiled earlier version: zig-linux-x86_64-0.8.1.xz. Download it, unxz it, untar it, and put the zig executable in your PATH.
Next, I cloned zig-stm32-blink. It is designed for an STM32F4 discovery board, which appears to be incompatible with the STM32F411 blackpill.
So you need to generate a new version of src/registers.zig. To do this, you need svd4zig, which you can get here. Build it:
zig build -Drelease-safe
You need the appropriate svd file. You can probably find it somewhere online, but I have stm32cubeide installed, so I could use that. Type
to find out where it is. Then convert it:
./zig-out/bin/svd2zig /path/to/svd > registers.zig zig fmt registers.zig
Note that the first line above is a little different from the one shown in the github README instructions.
Then, in the zig-stm32-blink repo, replace src/register.zip with the file you created above.
Getting closer now! In src/main.zig, comment out the call to systemInit(), which makes it go wrong. Replace GPIODEN with GPIOCEN, and references to GPIOD with GPIOC. Then issue the commands:
zig build zig build bin cd zig-out/bin st-flash --connect-under-reset write zig-stm32-blink.bin 0x8000000
Then, with a bit of luck: bingo! The user LED light, PC13, should be blinking. If you’re using a Nucleo board, then you’re going to have to tweak the code so that the built in LED on PA5 is blinked instead.
And there we have it. My first zig program.
It’s difficult to give much in the way of impressions about Zig as a programming language, as I’ve only just started using it. One obviously really nice feature is that it supports cross-compilation out of the box. The syntax seems fairly intuitive. Without knowing the syntax rules, it’s pretty obvious what the code is doing.
I think Zig supports bitfields by the looks of it (?) I hear it also lays out structs in a nice way, with no padding.
It also seems to have a curious feature where it can run code at compile time. I wonder if this is a way of being able to provide semantic information at compile time. The kind of thing I had in mind is that it could act as the Cube MX configurator.
I’ve never actually been able to get a Rust embedded project to flash properly to my microcontroller, so Zig is slightly in the lead on that score.
So, it works. Zig also has coroutines and stuff, which seems potentially quite interesting from a microcontroller viewpoint.
Hmmm. We shall see.