IoT Zephyr

Zephyr Weekly Update – New Hardware Model

Howdy! Before diving into this week’s news, I would like to extend an invitation to all of you reading this weekly update to consider submitting a talk for an upcoming Zephyr Tech Talk. As you have probably noticed if you watched previous episodes, these are very informal sessions, so you shouldn’t worry about having to prepare super polished slides (but cool demos are definitely a nice to have!).

If you are a maintainer of a Zephyr area you feel deserves more attention, or simply a Zephyr contributor or enthusiast eager to share insights about a topic you’re passionate about, please propose your idea here!

New Hardware Model

As announced in previous weeks, a new hardware model has been introduced for making it easier to support hardware configurations that were becoming difficult or impossible to describe with the legacy model.

This new model allows to better address multi-core (and sometimes multi-archictecture, too!) SoCs, as well as boards with multiple SoCs.

All the hundreds of boards supported in Zephyr have already been migrated, and what you need to do to migrate your own existing board definitions that you may be maintaining out-of-tree is descibred in the Board porting guide.

We will be having a Zephyr Tech Talk on the topic in just a few weeks, so stay tuned for that!

LED matrices as regular display controllers

I am sure some of you may have a love & hate relationship with Devicetree. It certainly takes some time to get used to the syntax and the sometimes opaque error messages in case of misconfiguration, but it is a super powerful and versatile tool.

This week, a new driver was introduced that I believe really illustrates quite well how one can really decouple their application code from the underlying hardware.

Zephyr already has a generic driver class for LED strips. You will find several drivers in the Zephyr tree (ex. for the popular WS2812 RGB LEDs) that implement the LED strip API and allow to set the colors of all the LEDs in the strip. As you can imagine, on the Devicetree side of things, the configuration of the driver includes things like how many LEDs are in the strip, or which pins/bus should be used to control the strip.

There is also a driver class for all things display controllers. Here, we’re talking about drivers exposing properties for configuring the resolution of the display, which pins to use to transmit pixel data, etc. In most cases, the application developer couldn’t care less about the specifics of the display controller, and they only use the display driver API to effectively put pixels on the screen. In fact, there’s even higher levels of abstraction, like the pre-integration with LVGL, which you’ve heard me talk about many times.

OK, so can you guess where I am going with this? Yep, a new driver now sits kind of in the middle of these two classes of drivers. It’s a display controller driver for LED matrices. Give it a phandle to an led-strip node, and you have your new display ready to rock & roll!

chosen {
    zephyr,display = &led_strip_matrix;

led_strip_matrix: led_strip_matrix {
    compatible = "led-strip-matrix";
    status = "okay";
    led-strips = <&led_strip>;
    chain-lengths = <256>;
    width = <16>;
    height = <16>;

(PR #68614)

Boards & SoCs

  • New MIPI DBI host controller driver for Renesas Smartbond. (PR #68426)
  • New WWDT watchdog driver for Nuvoton Numaker. (PR #68044)
  • New RTC driver for Raspberry Pi RP2040. (PR #64939)
  • nRF54 SoCs have two IP blocks that help with inter-domain signaling and IPC scenarios, namely VEVIF (VPR Event Interface) and BELLBOARD. These two peripherals now have drivers in-tree. (PR #69303).
  • Added support for Renesas Smartbond LCD controller (LCDC) display controller driver. (PR #67649)
  • If you are a user of the M5Stack Core2, you may have noticed that by default, the Grove connectors are not powered. Thanks to PR #67280 you can now control whether the Grove connectors should be powered or not using the bus_5v regulator.

General drivers

  • New cellular model driver for the Nordic nRF91 series. (PR #68981)
  • New flash driver for MRAM (Magnetic Random Access Memory) as found on the new nRF54H20. (PR #69800)
  • You may already be familiar with the regulator-boot-on Devicetree property which allows to ensures a given regulator is enabled when your application start. The new regulator-boot-off property now allows to do the opposite. (PR #69319)
  • New input driver for the Pixart PMW3610DM, a low-power laser mouse sensor. (PR #69722)
  • In the context of #69303, some work has also been done on cleaning up the mbox API (PR #69390)
  • #68776 i2c: RTIO context and some small drivers +1119 -140 (@teburd)


  • Support has been added for using QEMU on Windows in Twister. (PR #67595)
  • It’s now possible to set multiple IPv4 netmasks per network interface. (PR #68419)
  • Significant improvements were made to the State Machine Framework (SMF) to better support hierarchical state machines. (PR #66753)
  • LVGL exposes an API for rounding the coordinates of areas to redraw, as this can be needed for some display controllers. The new CONFIG_LV_Z_AREA_X_ALIGNMENT_WIDTH and LV_Z_AREA_Y_ALIGNMENT_WIDTH KConfig options allow to make use of the rounding mechanism when needed. (PR #69410)
  • DTLS sockets now allow to send multiple fragments in the same sendmsg(). (PR #69280)
  • Breaking API change for CAN controllers as part of a rework of the manual bus-off recover. (PR #69460)
  • New POSIX APIs:
    • Support for getting and setting POSIX environment variables has been introduced (environ, getenv(), setenv(), and unsetenv()). (PR #66762)

A big thank you to the 12 individuals who had their first pull request accepted this week, 💙 🙌: @Dermiste, @jthm-ot, @zhaynxp, @jonathonpenix, @cradzik, @ajf58, @Deedone, @pfarwsi, @ChangNice, @glenn-andrews, @sibertdeclercq, and @gangli02.

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 – Zephyr 3.6.0 is a go, Hello 3.6.99!

Zephyr 3.6 was released a week ago and it is really amazing to see how well it was received. I am particularly happy to see that thousands of people have already watched the video highlighting some of the changes and additions available in this release, such as the added support for GNSS receivers, keyboard matrix driver, and more. Please check it out if you haven’t had a chance already!

I also encourage you to check out our special Zephyr Tech Talk episode earlier this week!

Zephyr 3.7, which will be the next Long-Term Support version of the project, is already starting to shape up, and below are some of the highlights from the first couple hundreds of commits already merged into the main branch.

Native UART TTY driver now supports interrupt-driven API

In an effort to make it increasingly easier to emulate Zephyr on host systems, the native UART TTY driver now supports an interrupt-driven API. In order to use the new driver for your zephyr,native-tty-uart UARTs, you may simply enable CONFIG_UART_INTERRUPT_DRIVEN in your project configuration.

I find it particularly interesting as this means that it’s now easier to e.g. simulate a GNSS receiver on your host system, by attaching your Zephyr app to a virtual UART into which you can inject your mock NMEA sentences. (PR #68857).

Boards & SoCs

As the project is in the process of transitioning to a new model for describing the SoCs and boards in the source tree, no work has been merged in the main branch this week.

The maintainers are holding off with adding new boards/SoCs and making changes in main until the working branch (collab-hwm) where the migration is happening is ready to be merged (which should be very soon).

General drivers

  • An interesting new input driver allows to define input keys that are implemented using an ADC and a resistor ladder.
Image credit:

This is a pretty clever way to add multiple buttons while only using a single ADC channel, and the driver allows to basically define the mapping of how each ADC values / voltage ranges correspond to each key, or key combination. (PR #68446)

/ {
        buttons {
                compatible = "adc-keys";
                io-channels = <&adc 2>;
                keyup-threshold-mv = <0>;
                key_0 {
                        press-thresholds-mv = <1650>,  /* KEY0 */
                                              <2536>;  /* KEY0 + KEY1 */
                        zephyr,code = <INPUT_KEY_0>;
                key_1 {
                        press-thresholds-mv = <2300>,  /* KEY1 */
                                              <2536>;  /* KEY0 + KEY1 */
                        zephyr,code = <INPUT_KEY_1>;
  • RRAM (or ReRAM, Resistive Random-Access Memory) is a type of non-volatile memory that stores data by changing the resistance across a dielectric solid-state material. It’s a relatively new technology and one of its benefit is that it is several orders of magnitude faster than flash memory.
    A new flash driver for the RRAM controller found on some Nordic nRF SoCs has been contributed this week. (PR #68309)
  • New regulator driver for the Cirrus CP9314 buck switched capacitor DC/DC Converter (cirrus,cp9314). (PR #68177)
  • New driver for the ScioSense ENS160 environmental, multi-gas, sensor (sciosense,ens160). This sensor allows to measure CO2, VOC, as well as a general air quality index (AQI). (PR #67343)
  • The PixArt PAT9125EL is a low-power optical tracking sensor that doesn’t require a lens to work, and a new input driver for it has been added (pixart,pat912x)!
    This sensor is particularly well suited for tracking movement over a shiny/glossy surface. (PR #69492)
Video courtesy of Fabio Baltieri
  • The charger subsystem now allows to define output limits for the discharge rate and the system voltage, allowing to issue alerts when these limits are reached. (PR #67810)
  • The Ethernet driver for the W5500 now supports link status detection. (PR #68752)
  • The ESP-AT Wi-Fi driver now allows to bind and receive from UDP sockets. (PR #68586)


  • Various improvements to the DHCPv4 server.
  • New lwm2m_set_bulk() API allows to set multiple resource values at once. (PR #68988)
  • New network shell command (net iface set_ipv4_gateway) allows to set the IPv4 gateway of a network interface. (PR #68465)
  • It is now possible to use CONFIG_SHELL_MSG_CMD_NOT_FOUND and SHELL_MSG_SPECIFY_SUBCOMMAND to indicate what message (if any) will be printed when a given command or subcommand is not found. (PR #69002)
  • New sign_extend() and sign_extend_64() helper functions to perform sign extensions. (PR #68828)
  • Bluetooth CAP Commander now supports the “Change Volume Mute State” procedure. (PR #66281)
  • New POSIX APIs:
    • fattach()
    • fdetach()
    • syslog() (PR #68515)

A big thank you to the 16 individuals who had their first pull request accepted this week, 💙 🙌: @JayHCloud, @bmihelcic, @thompsa, @jaz1-nordic, @vshymanskyy, @rntsoma, @sageve, @jerome-pouiller, @ngphibang, @celinakalus, @MaochenWang1, @allemanm, @Brianmm94, @rysiof, @jpanisbl, and @cmrdrbz.

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 – 1 week left before feature freeze

We are entering the last few weeks of the Zephyr 3.6 release cycle, with the feature freeze scheduled for next Friday, February 2. If you have pull requests that are still pending, now might be a good time to make sure they get reviewed and approved to make it in time for 3.6! 🙂

Second round of updates to the Sensing API

PR #64478 has introduced another round of updates to the Sensing API. I haven’t had time to look into all the details so I encourage you to look at the changes directly in the PR.

As a reminder, there is now also a Sensors Working Group that meets every Monday to discuss all things sensors.

Boards & SoCs

  • The SDP-K1 evaluation board from Analog Devices (ADI) is a system demonstration platform (SDP) designed to connect to various evaluation shields containing ADI components. (PR #67278)
  • The STM32WB5MM-DK Discovery Kit is a dev kit for the STM32W5MMG module (dual core Cortex-M4/Cortex-M0+) that comes with an ultra-low-power BLE 5.2 / 802.15.4 radio module, an LCD display, 16MB of external Flash, and a couple of on-board sensors. (PR #67819)
  • All ESP32 boards saw a significant decrease of their minimal heap size thanks to PR #67787.

SoC driver updates

  • Clock initialization has been reworked across all Microchip/Atmel SAM SoCs. (PR #66499)
  • Suspend-to-RAM support has been added for STM32. (PR #67534)
  • New driver for NXP enhanced Direct Memory Access (eDMA). (PR #65671)
  • Driver for Microchip/Atmel SAM flash controller has been redesigned to fully utilize the flash page layout and capabilities of each individual SoC. (PR #64215)

General drivers

  • A new display driver is available for the Galaxy Core GC9A01A display controller, used to drive many round LCD displays these days (at least the ones from AliExpress ^^), like the ones used for smart watches and smart dials. (PR #67012)
  • Bosch BMP581 is a barometric pressure sensor with high accuracy that can be used for e.g. fitness tracking use cases where detecting a change of altitude is required.
    With an average current consumption of 1.3 µA @ 1 Hz, it definitely qualifies as a low-power sensor :). (PR #61535)
  • The driver for BD8LB600FS 8-channel low-side switch now supports daisy-chaining. (PR #65982)
  • New Kconfig options (CONFIG_POWER_DOMAIN_*_INIT_PRIORITY) have been introduced to allow changing the initialization priority of power domains. (PR #67939)
  • A noteworthy breaking API change in the CAN drivers: it is no longer possible to perform run-time filtering of frames based on the Remote Transmission Request bit, and filtering is now instead configured via Kconfig. (PR #67127)

Input drivers

This week’s numerous updates to the input subsystem make for a perfect excuse to shamelessly plug the recent Zephyr Tech Talk with ZMK firmware creator Pete Johanson. Whether you are a mechanical keyboard aficionado or simply curious about hearing how Zephyr was put to good use to enable custom keyboard firmware creation, check it out!

  • Optical encoders are now supported. (PR #66121)
  • A new keymap driver allows to use a Devicetree node to provide the mapping between your keyboard matrix and the actual keys at each row/column intersection. (PR #67757)
kbd {
      keymap {
          compatible = "input-keymap";
          keymap = <
              MATRIX_KEY(0, 0, INPUT_KEY_1)
              MATRIX_KEY(0, 1, INPUT_KEY_2)
              MATRIX_KEY(0, 2, INPUT_KEY_3)
              MATRIX_KEY(1, 0, INPUT_KEY_4)
              MATRIX_KEY(1, 1, INPUT_KEY_5)
              MATRIX_KEY(1, 2, INPUT_KEY_6)
              MATRIX_KEY(2, 0, INPUT_KEY_7)
              MATRIX_KEY(2, 1, INPUT_KEY_8)
              MATRIX_KEY(2, 2, INPUT_KEY_9)
          row-size = <3>;
          col-size = <3>;


  • Starting with GCC 10, GCC ships with a static analyzer. It is now possible to use Zephyr’s static code analysis infrastructure to easily run GCC static analyzer for your application, simply pass the following parameter when running west build: -DZEPHYR_SCA_VARIANT=gcc. (PR #64595)
  • It is now really easy to build an LLEXT (Linkable Loadable Extension) module thanks to a new add_llext_target() CMake function.
    See the CMakeLists.txt file of the Hello World sample to see how to use it. (PR #67431)
  • New CMake helper function (zephyr_blobs_verify()) allows to verify that blobs fetched using west have a valid checksum. (PR #67593)
  • New APIs allow to check if an IPv6 address is link local or global, see net_ipv6_is_sl_addr() and net_ipv6_is_global_addr(). (PR #67838)
  • A bunch of modules were updated this week:
    • LVGL version has been updated to 8.3.11, with 9.0.0 coming shortly as it’s just been released this week! (PR #66314)
    • zcbor version has been updated to 0.8.0. (PR #67418)
    • LittleFS version has been updated to 2.8.1. (PR #65414)
    • picolibc version has been updated to 1.8.6 (PR #67891)
  • Added support for Wi-Fi STA disconnection. (PR #68007)
  • New POSIX APIs:
    • mq_notify()

A big thank you to the 8 individuals who had their first pull request accepted this week, 💙 🙌: @renpytom, @javad123javad, @itmm, @tanmaykathpalia, @msalau, @73jn, @sandip-dalvi, and @adri1mart1.

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: