IoT Zephyr

Zephyr Weekly Update – New GNSS subsystem

Happy Friday! Zephyr now supports GNSS modems, and this is definitely one of the main highlights of this week. I can’t wait to see what kind of applications people will build now that there is a standard, out-of-the-box, way to feed location/navigation info into Zephyr applications.

GNSS Support

The recently introduced modem subsystem added a chat module that allows to pretty much “script” the interactions with a modem.

In the context of cellular modems, it would typically mean dealing with AT commands. This week, a new massive pull request was merged that adds support for GNSS (Global Navigation Satellite System) modems. And, guess what, it too builds on top of the modem subsytem and chat module in particular.

The NMEA 0183 specification standardizes the way GNSS devices output data. Whether it is actual location data, information about the satellites in sight, date/time, … there is a well-defined ASCII representation for it. Below is an example of what you would see if you were to listen to the UART of a GNSS modem:









The chat module is therefore a perfect fit to easily hook up the appropriate parsers for each type of NMEA 0183 frame a GNSS module may spit out.

One thing that I really like with this new feature, is that it’s providing much more than the raw infrastructure to “talk” to the GNSS modem. It can effectively–and optionally, should you be too resource-constrained!–parse all the collected data into proper data structures that you can use in your code.

/** GNSS info data structure */
struct gnss_info {
	/** Number of satellites being tracked */
	uint16_t satellites_cnt;
	/** Horizontal dilution of precision in 1/1000 */
	uint16_t hdop;
	/** The fix status */
	enum gnss_fix_status fix_status;
	/** The fix quality */
	enum gnss_fix_quality fix_quality;

/** GNSS time data structure */
struct gnss_time {
	/** Hour [0, 23] */
	uint8_t hour;
	/** Minute [0, 59] */
	uint8_t minute;
	/** Millisecond [0, 59999] */
	uint16_t millisecond;
	/** Day of month [1, 31] */
	uint8_t month_day;
	/** Month [1, 12] */
	uint8_t month;
	/** Year [0, 99] */
	uint8_t century_year;

/** Navigation data structure */
struct navigation_data {
	/** Latitudal position in nanodegrees (0 to +-180E9) */
	int64_t latitude;
	/** Longitudal position in nanodegrees (0 to +-180E9) */
	int64_t longitude;
	/** Bearing angle in millidegrees (0 to 360E3) */
	uint32_t bearing;
	/** Speed in millimeters per second */
	uint32_t speed;
	/** Altitude in millimeters */
	int32_t altitude;

See PR #61073, documentation page, and code sample for more details on this very neat new feature 🙂

Boards & SoCs

Arduino Uno R4 Minima

It is hard to believe that the first release of the Arduino Uno dates back to 2010! In June of this year, Arduino released the fourth release of the Uno, the Arduino Uno R4.

Where the original Uno was using an 8-bit AVR ATmega328P microcontroller with 32 KB of Flash and a whopping 2 KB of RAM, the Uno R4 is using a 32-bit Arm Cortex-M4 from Renesas (RA4M1) running at 48 MHz, with 256KB of Flash and 32 KB of RAM.

This week, PR #60760 was merged, adding support for the Arduino Uno R4 Minima in Zephyr.

Other boards added this week include:

  • The PRO is to ST Microelectronics what Thingy is to Nordic: a feature-packed devkit built around an impressive amount of sensors: temperature, IMUs, humidity, microphone, etc. It is a great starting point for a wide variety of applications, from wearables to environment sensing. It’s nice to see a dedicated code sample to directly exercise all the sensors. (PR #64039)
  • STM32L4R9I-DISCO Discovery kit, which features a Cortex-M4, 640Kb of RAM and 2Mb of Flash, as well as a round 390×390 pixels OLED panel with touch interface. (PR #64514)


  • Telit ME910G1 Cat M1/NB2 modem is now supported thanks to a first contribution from Jeff Welder! (PR #63711)
  • Maxim MAX20335 PMIC is now supported. This PMIC targets low-power wearable applications. (PR #64555)
  • New watchdog driver for Infineon XMC4xxx (PR #62954)
  • A new GPIO monitor driver is available. It allows to link the on/off status of a power domain to the state of a GPIO (PR #61166)


  • New shell commands have been added to start, stop and set properties of an Audio Codec device. (PR #57580)
  • Regulator API now allows to access the list of current limits supported by a given regulator. It’s also made available through the newly added regulator clist command. (PR #64516)
uart:~$ regulator clist BUCK1
50.000 mA
75.000 mA
100.000 mA
0.125 A
0.150 A
0.175 A
0.200 A
0.225 A
0.250 A
0.275 A
0.300 A
0.325 A
0.350 A
0.375 A
  • Ongoing work to refactor keyboard scanning drivers so that common code and configuration can be better shared. (PR #64456)

A big thank you to the 10 individuals who had their first pull request accepted this week, 💙 🙌: @Ayush1325, @LuckeTech, @majunkier, @TomKeddie, @ddeshat, @yangnin, @jeffwelder-ellenbytech, @jrversteegh, @pin-zephyr, and @gbarkadiusz.

As always, I very much welcome your thoughts and feedback in the comments below!

If you enjoyed this article, don’t forget to subscribe to this blog to be notified of upcoming publications! And of course, you can also always find me on Twitter and Mastodon.

Catch up on all previous issues of the Zephyr Weekly Update:

IoT Zephyr

Zephyr Weekly Update – Hello 3.5.99!

Zephyr 3.5 has been out for a week (here’s the announcement blog post if you missed it!), and earlier this week we celebrated the release by having a live stream where many maintainers as well as our release managers Fabio and Johan joined me to discuss some of the additions to 3.5.

Catch up with the recording on YouTube, and consider subscribing to the channel if you haven’t already to be notified of upcoming videos and live streams.

The main development branch is now open again, so it’s time for for this week’s update!

Documentation improvements

  • I have said it many times and will say it again: you don’t have to contribute code to help make Zephyr better! Helping us improve our documentation is also highly appreciated 🙂

    When browsing you now have the opportunity to directly open an issue regarding the documentation page you are currently browsing.

    Furthermore, the page footer now indicates the last time someone updated the contents of a page. This can give you a hint about how up-to-date the information you are reading is.
  • In an effort to better document all the APIs in Zephyr, a new CI task is generating a documentation coverage report for all the public headers.

    All contributors and maintainers are encouraged to look at the report to see if there’s areas where Doxygen comments might be missing. Reports are generated for each pull request (e.g. and are also available for main here:
Doxygen comments coverage report for include/zephyr/drivers headers.

New configdefault Kconfig keyword

In order to make it easier for developers to define custom default values downstream without needing to re-specify dependencies of the symbols they which to “override”, a new configdefault extension to Kconfig allows to do just that.

Jordan Yates, who contributed this extension, shared the following example which I think is pretty self-explanatory:

    bool "Apply defaults for internal applications"

configdefault BT
     default y if MY_COMPANY_APPS
configdefault MCUMGR
    default y if MY_COMPANY_APPS && BT

See PR #51316 for more background and details, as well as Zephyr documentation.

west 1.2.0

A new 1.2.0 version of west was released ahead of Zephyr 3.5.0, and I wanted to call out a welcome addition to the list of commands.

west grep allows you to… well… grep for content across your entire workspace. This can be really useful when you want to look for something both in the Zephyr codebase and in the various HALs (or any other module really).

More at

Boards & SoCs

DA14695 Development Kit USB
  • The DA14695 Development Kit USB is a low cost development board for DA14695 MCU from Renesas. (PR #60086)
  • The DSP core of NXP MIMXRT595-EVK is now supported. (PR #61356)
  • The Panasonic PAN1783 evaluation board is a development board for the nRF5340 from Nordic Semiconductor. (PR #63104)
Accel 13 Click – Mikroe
  • The MikroElektronika ACCEL 13 Click shield is now supported. It features an IIS2DLPC ultra-low power 3-axis accelerometer sensor in a mikroBUS form factor. (PR #63297)
  • Added RTC driver for Atmel SAM series. (PR #63962)
  • Added CAN controller driver added for Nuvoton numaker series. (PR #64018)
  • Added crypto and RTC drivers for Renesas Smartbond. (PR #60238, #63983)


  • Several LCD displays from SparkFun expose a so-called SerLCD interface, and there is now an auxiliary display driver available for them. (PR #61445)
  • Driver added for MEMSIC MC3419 3-axis accelerometer sensor. (PR #62095)
  • Some AMD SoCs feature a temperature sensor that can be accessed using a “Sideband Temperature Sensor Interface” (SB-TSI in short). A new driver has been added with PR #60818.
  • The ADXL367 is an ultra-low power, 3-axis accelerometer that consumes only 0.89 μA at a 100 Hz output data rate and 180 nA when in motion-triggered wake-up mode! You will have guessed that it now has a driver, added with PR #63800. 🙂 Note that both SPI and I2C are available.
  • Introduced new battery charging properties (ex. “health”, precharge current”, …) and support for the BQ24190 from Texas Instruments. (PR #62551)


  • In Devicetree, a parent node now “inherits” all dependencies from its child nodes. (PR #62417)
  • CoAP library now supports echo and request-tag from RFC9175. (PR #63913)
  • The handling of unexpected TCP packets within Zephyr’s TCP stack has been improved. A reset (RST) packet is now sent in response to unexpected TCP packets. (PR #64029)
  • Network sockets now leverage the recently introduced “object cores”. You may use the net sockets shell command to access socket information and statistics. (PR #63339)
  • IPv4-to-IPv6 mapping is now supported. (PR #63579)

A big thank you to the 24 individuals who had their first pull request accepted since my last post, 💙 🙌: @TomzBench, @karthi012, @marnold-b, @davedesro, @mimbriani, @dennisgr102, @pkoscik, @augustozanellato, @yf13, @Spice-Weasel, @jpmur, @martincalsyn, @nandogalliard, @yeweizy, @mgritz, @pres2300, @photonthunder, @sousapedro596, @FranciszekPin, @Alex-T-Stark, @quic-lingutla, @hlukasz, @arun-mani-tech, and @akaiserUS.

As always, I very much welcome your thoughts and feedback in the comments below!

If you enjoyed this article, don’t forget to subscribe to this blog to be notified of upcoming publications! And of course, you can also always find me on Twitter and Mastodon.

Catch up on all previous issues of the Zephyr Weekly Update:

IoT Zephyr

Zephyr Weekly Update – Getting ready for Zephyr 3.5

Apologies for missing last week’s update. Last Friday was the feature freeze for Zephyr 3.5 and everyone, including myself, was pretty busy trying to push everything over the finish line!

Because of the feature freeze, no significant changes happened in the last week, so this update will still pretty much feel like a “weekly”, I guess 🙂 I will try to keep it short (…ish) since I am preparing a full write-up about what’s new in Zephyr 3.5, and I don’t want to spoil all the fun! I would also like to apologize to the Bluetooth contributors and maintainers in particular as I’m pretty sure I am missing important stuff — I definitely spotted lots of stabilization and bug fixing but if I forgot something important, please let me know in the comments or on Discord!

Also, remember to join Peter and me next Wednesday, Oct. 11, for our 3rd Zephyr Tech Talk, where we’ll discuss everything you need to know about Renode! I’d actually recommend you “RSVP” on LinkedIn, as this is the best way to make sure you will get a reminder as we go live. You can also of course spread the word in your network, if you feel like it.

Linkable loadable extensions (llext)

The newly introduced Linkable Loadable Extensions (llext) subsystem makes it possible to dynamically extend the functionality of an application at runtime. Extensions can be loaded from pre-compiled ELF formatted data which is verified, loaded, and linked with other extensions.

As often, an example is worth a thousand words and I encourage you to use the llext shell commands to get a feel of what it’s all about. A dedicated sample will give you all the instructions you need to build a “Hello World” binary, and then dynamically load it and invoke it using shell commands (there is even a command to load the hex-encoded binary, so you can actually do the whole thing without leaving your Zephyr shell!).

uart:~$ llext help
llext - Loadable extension commands
  list          :List loaded extensions and their size in memory
  load_hex      :Load an elf file encoded in hex directly from the shell input.
                 <ext_name> <ext_hex_string>
  unload        :Unload an extension by name. Syntax:
  list_symbols  :List extension symbols. Syntax:
  call_fn       :Call extension function with prototype void fn(void). Syntax:
                 <ext_name> <function_name>

I am really excited about what’s going to come next now that one of the most requested feature since many years is basically unlocked. There’s still a lot that needs to be done (as an example, in this initial version, one may need to disable memory protection for llext to work…) but that makes things even more exciting! (PR #57086)

Binary descriptors

Binary descriptors are a new feature that makes it super simple to describe data objects (think: “model number” of your device, “kernel version”, etc.) that end up being linked at a known offset in your binary.

Like I just said, binary descriptors are really easy to use:

#include <zephyr/bindesc.h>


“Standard” binary descriptors such as build time, or kernel version, can be enabled without having to change anything in your code, just by enabling the dedicating Kconfig options.

A new west bindesc command has been introduced to allow developers to read binary descriptors in .bin, .hex, .elf, or .uf2 binary files.

You may want to check out the new code sample to familiarize yourself with the different macros and tools surrounding binary descriptors.

(PR #54464)

Object cores

Object cores are a new kernel debugging tool that can be used to both identify and perform operations on registered objects.

Kernel objects such as semaphores, message queues, etc. may now (if enabled via the dedicated CONFIG_OBJ_CORE_ * Kconfig options) embed a new “object core” that can be used to gather and access all sorts of statistics about the object.

The documentation page for this new feature is quite frankly excellent, so I would recommend you check it out as it’s gonna do a better job than I ever will at explaining things!

(PR #59075)

Boards & SoCs

Raspberry Pi Model 4 B
  • As everyone is talking about the Raspberry Pi 5 these days, this will likely not get all the attention it deserves, but did you know that Zephyr now supports Raspberry Pi 4 Model B?
    It is very early stage and very few peripherals are supported at the moment, but the idea of being able to run Zephyr on an MPU board that many people already have handy is very cool. And it’s always nice to see new Arm64 SoCs and boards being added!
    (PR #62320).
  • Support for Nucleo U5A5ZJ-Q was added. As a reminder the U5 series features Arm® Cortex®-M33 cadenced at up to 160 MHz, and the “U” stands for ultra low-power 🙂 (PR #63144)


HM330X particle sensor
  • Added TMAG5170 3d Hall effect sensor driver. It is a pretty complete driver with power management, CRC-based error detection, trigger mode, … so you may want to bookmark it for next time you need to write a sensor driver! (PR #61346)
  • New HM330X particle sensor driver. I actually wrote this driver as it’s a sensor that I’ve been using to monitor dust levels in my pottery studio. It’s proven to be very accurate and reliable even when running 24/7 which, to be honest, is not always the case for “cheap” maker-oriented sensors. I think it might have been my first sensor driver contribution to the project, and I have to admit it went pretty smoothly! (PR #62786)
  • New Microchip CAN-FD MCP251xFD driver, “an important addition to the existing range of Zephyr CAN drivers” to quote Brix, one of the maintainer of the CAN subsytem. (PR #59968)
  • New DMA driver for NXP SMARTDMA. This IP is is a custom peripheral intended for graphics acceleration on the NXP RT595 (PR #57616)
  • STM32 I2C driver now supports 10-bit addressing (PR #60620)
  • RTC driver for STM32 now supports sub-second ticks (note that this increases power consumption). (PR #61580)
  • New PWM pulse capture driver for S32K344. (PR #62695)
  • Added eDMA support for S32K344. (PR #61311)
  • New bit-bang driver for MDIO. (PR #56679)
  • New ALTERA Parallel I/O (PIO) driver. It supports calibration, setting/getting alarms, and alarm callbacks. (PR #61162)
  • New Ambiq AM1805 RTC driver. (PR #62357)
  • Support has been added for Intel eMMC host controller. (PR #61108)
  • New vertical decoder API for decoding sensor data. (PR #61022)
  • adc_read_dt() function to read from an ADC by providing a Devicetree node . (PR #63010)


A big thank you to the 21 individuals who had their first pull request accepted in the past 2 weeks, 💙 🙌: @moritzstoetter, @ivaniushkov, @fkwasowi, @nik012003, @meshium, @jandriea, @hlord2000, @wouterh, @srisurya1, @JeroenReeskamp, @bjda, @Fladdan, @zohavas, @lifenggitacc, @dcorbeil, @stasys0, @AirChandler, @lindblandro, @graffiti, @rahul-sin, and @tbr-tt.

As always, I very much welcome your thoughts and feedback in the comments below. See you in two weeks, as I don’t think next week will see any noteworthy update as the final release approaches.

If you enjoyed this article, don’t forget to subscribe to this blog to be notified of upcoming publications! And of course, you can also always find me on Twitter and Mastodon.

Catch up on all previous issues of the Zephyr Weekly Update: