IoT Zephyr

Zephyr Weekly Update – Emulated DMA controller

Happy Friday, folks! Once is not custom, let’s dive right into this week’s updates from Zephyr RTOS land, although don’t forget to submit a talk to FOSDEM 2024 before midnight!

New emulated DMA driver

It is nice to see an increasing amount of emulated drivers added to Zephyr recently.

This week, a new zephyr,dma-emul binding was introduced. The associated driver provides a software implementation of a DMA controller that can be used to enable testing of areas and drivers otherwise difficult to test for they rely on DMA to be present.

See PR #58375 for more details.

Support for LVGL keypad input binding

Until PR #65002 being merged earlier this week, the LVGL keypad input device interface was the only input interface not yet supported in Zephyr (pointers, encoders, and buttons were already supported).

The new zephyr,lvgl-keypad-input binding allows to declare a new LVGL input device in your Devicetree that maps input codes (ex. INPUT_KEY_DOWN) coming from a Zephyr input device, to LVGL ones (ex. LV_KEY_NEXT).

The LVGL sample has been updated to support keypads, and is therefore now a neat showcase for all four LVGL input interfaces!


  • Added support for setting multicast IPv4 TTL and IPv6 hop limit. (PR #65886)
  • It is now possible to perform multicast join/leave operations through the standard BSD Sockets API. (PR #66018)
  • A new fallback mechanism has been added to LwM2M subsystem.
    It is very common for a LwM2M client to have a list of several bootstrap server it may be trying to connecting to, so it only makes sense for the subsystem to support that and automatically try another bootstrap server from the configured list should connecting to the main one fail. Similarly, the fallback mechanism can be used for the connection to the actual LwM2M server, to switch to another one in case of lost connection. (PR #65745)
  • The CoAP server now implements network management events. These can be quite convenient to be notified when e.g. a new observer is added/removed, or when the server start/stops.

Boards & SoCs

Adafruit Grand Central M4 Express
  • Adafruit Grand Central M4 Express is a devkit based on the Microchip ATSAMD51, with 1MB flash, 256 KB RAM, and a whooping 70 GPIO pins in total! (PR #62618)
  • STM32WBA55 SoC series is now supported, alongside the ST Nucleo WBA55CG board. Featuring both Arduino and STMorpho headers, and based on a Cortex-M33, this devkit aims at ultra low-power BLE applications. (PR #66073)


  • The keyboard matrix driver keeps getting nice improvements. It now supports polling and scan mode, to help in situations where one is not able to use interrupts for the GPIOs corresponding to the rows/columns.
    For example, large keyboard matrices might typically be accessed through a GPIO multiplexer that allows you to only “talk” to one row or column at a time.
    I am really looking forward to putting this new feature to use to add support for the M5Stack Cardputer and its cool keyboard 🙂
  • Several fixes to Sierra Wireless HL7800 modem driver for better low-power support. (PR #66237)
  • Added support for NTCG103JF103FT1 thermistor. (PR #62185)
  • Quadrature decoder support has been added for NXP S32 series. (PR #65035)
  • Added support for the ST LPS28DFW pressure sensor. (PR #65416).


  • When using SNTP (Simple network time protocol), a new CONFIG_SNTP_UNCERTAINTY allows to get a more reliable timestamp. (PR #66233)
  • When using Bluetooth Mesh, advertising is automatically suspended/resumed when enabling disabling Mesh. (PR #64721)
  • OpenThread version has been updated, with added support for BLE TCAT (commissionning over BLE). (PR #66160)
  • New POSIX API:

A big thank you to the 7 individuals who had their first pull request accepted this week, 💙 🙌: @rabarar, @pillo79, @lukas-jung, @mikevoyt, @naNEQ, @jrhrsmit, and @TangleZ.

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 – Multiplexing all the things!

Howdy! Before diving into this week’s updates, I would like to take a minute to encourage you to have a look at the Call for Papers for two really good open source conferences where I would love to see lots of cool Zephyr content 😉

  • FOSDEM 2024, Feb. 3-4 in Brussels, Belgium—The CfP for the Embedded, Mobile and Automotive devroom closes a week from now, on December 8, so don’t wait to submit.
  • Zephyr Developer Summit 2024 (co-located with Embedded Open Source Summit), Apr. 16-18 in Seattle, WA— You have a bit more time for this one, but make sure to not miss the January 14, 2024 deadline if you are interested in speaking at the event!

Also, a quick plug for the next Zephyr Tech Talk live stream on Wednesday, December 6 (note: we’ll be going live one hour later than our usual time, at 2pm GMT).

I will be chatting with open source rockstar Keith Packard about Picolibc, and how it can help you make your Zephyr application faster and leaner. I am very much looking forward to this one and hearing tons of C trivia from Keith 🙂

You can register here to make sure you get a reminder when we’ll go live, and you may of course consider spreading the word with your network, it’s always much appreciated!

Device multiplexing

There are many (maybe too many!) interesting tricks that can be implemented on top of Devicetree, and it gives a lot of flexibility in describing and tweaking the capabilities of your hardware.

This week, a new device multiplexer pseudo-device has been introduced. In a nutshell, this gives you a way to have a node in your Devicetree that acts as a proxy for other devices.

A typical application for this would be to be able to dynamically change which UART to use as the Zephyr console. Another interesting use case would be to have the devmux act as that one accel0 accelerometer sensor you’re using in your code, except that you could easily switch back and forth between an actual sensor, and an emulated one, for example. And all of this without having to continually update your Devicetree, recompile it, and run it again.

A picture being worth a thousands word, here’s a diagram that summarizes what’s going on under the hood.

            +----------+                            +----------+
            |  devmux  |                            |  devmux  |
            |          |                            |          |
 dev0       |          |                 dev0       |          |
 +---------->   \      |                 +---------->          |
            |    \     |                            |          |
 dev1       |     \    |       dev0      dev1       |          |       dev2
 +---------->      O   +---------->      +---------->      O   +---------->
            |          |                            |     /    |
 dev2       |          |                 dev2       |    /     |
 +---------->          |                 +---------->   /      |
            |          |                            |          |
            |          |                            |          |
            |          |                            |          |
            +-----^----+                            +-----^----+
                  |                                       |
   select == 0    |                       select == 2     |
   +--------------+                       +---------------+

From a Devicetree perspective, and for a use case where you’d want to multiplex multiple UARTs, it would look like the below:

/ {
    chosen {
        zephyr,console = &devmux0;
        zephyr,shell_uart = &devmux0;

    &uart0 {
        status = "okay";

    euart0: uart_emul0 {
        compatible = "zephyr,uart-emul";
        current-speed = <0>;
        status = "okay";

    euart1: uart_emul1 {
        compatible = "zephyr,uart-emul";
        current-speed = <0>;
        status = "okay";

Memory attributes based allocator

When configuring memory regions in the Devicetree, one can use the zephyr,memory-attr property to specify some flags that can then be used at runtime. This may be used for example by some drivers to indicate that they won’t function properly if used with specific types of memory, e.g. a DMA driver may require the use of non-cacheable memory.

A recently added feature makes it possible to fine-tune the way memory can be allocated from the heap, to help you easily get the right type of memory for your use case.

When CONFIG_MEM_ATTR_HEAP is set, all memory regions marked with specific flags (ex. DT_MEM_SW_ALLOC_CACHE) are added to a pool of memory heaps from which one can then allocate memory from by requesting chunks of memory of the desired type.

// Init the pool

// Allocate 0x100 bytes of cacheable memory
block = mem_attr_heap_alloc(DT_MEM_SW_ALLOC_CACHE, 0x100);

// Allocate 0x200 bytes of non-cacheable memory aligned to 32 bytes
block = mem_attr_heap_aligned_alloc(ATTR_SW_ALLOC_NON_CACHE, 0x100, 32);

// Allocate 0x100 bytes of cacheable and dma-able memory
block = mem_attr_heap_alloc(DT_MEM_SW_ALLOC_CACHE | DT_MEM_SW_ALLOC_DMA, 0x100);

Adding support for recvmsg()

Zephyr’s BSD Sockets now implement proper support for the recvmsg() API.

As opposed to recv(), recvmsg() can be used with both connected (ex. TCP) and connection-less (ex. UDP) protocols to receive a message from an arbitrary network address.

When used alongside the IP_PKTINFO flag, it can also be useful to get additional information about an incoming packet, for example the address of the sender.

Check out PR #65694 for more details.

Boards & SoCs

  • Arduino has gone a long way since its beginnings as a protyping tool for interaction design students. There is now a plethora of Arduino products very much geared towards industrial applications, and Arduino OPTA is one of them.
    Based on an STM32H747XI dual-core Arm® Cortex®-M7 +M4 MCU, it is basically a highly capable PLC (Programmable Logic Controller), that includes high-power relay switches, Modbus TCP and RTU capabilities, and more.
    As of this week and PR #64101, the M4 core of the Arduino OPTA is now officially supported in Zephyr!
Arduino OPTA.
  • The NXP UCANS32K1SIC is a CAN signal improvement capability (SIC) evaluation board designed for both automotive and industrial applications that provides 2 CAN SIC interfaces and is based on a Cortex-M4F NXP S32K146 MCU. Now supported 🙂 (PR #65461)
  • The Renesas R-Car Spider board is the reference board for evaluating the Renesas R-Car S4 SoC family.
    Both the SoC and the board are now supported as of this week! (PR #56043)
  • The Waveshare Pico UPS-B shield is a UPS (Uninterruptible Power supply) module designed for the Raspberry Pi Pico.
    It communicates with the Raspberry Pi Pico over I²C and allows to transparently control the charge of its battery and use it to power the Pi. It just joined the list of supported shields in Zephyr. (PR #60384)


  • The recently added GNSS subsystem gets a new generic NMEA driver, that can be used with any source of NMEA frames.
    When you really only care about getting and decoding the raw NMEA data straight from your GPS receiver, and have no interest in tinkering with the module’s settings (or maybe it doesn’t even have any), then this driver will be your new friend. (PR #65422)
&uart0 {
          current-speed = <9600>;
          gnss: gnss-nmea-generic {
                  compatible = "gnss-nmea-generic";
  • I²C support added for Nuvoton Numaker. (PR #65673)
  • Added support for NXP TJA1103 Ethernet PHY. (PR #65756)
  • New experimental NXP ENET Ethernet driver. (PR #62833)


A big thank you to the 9 individuals who had their first pull request accepted this week, 💙 🙌: @ShaharHD, @kilejin, @boz, @timwoolliscroft-opteran, @marcowidmer, @Grin00, @borrelunde, @arkwad, and @adamfc2000.

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 – Bringing userspace to Xtensa

It was a lot of fun to play the guest in this week’s Zephyr Tech Talk. There was a lot to cover in “just” one hour (and there were tons of great questions from the audience to answer!), but I am happy that all the demos I wanted to show worked like I wanted. There are quite a few things that made my life easier when deciding I would migrate my “hackish” Arduino code to Zephyr, and the video dives into what these are.

Interestingly, by the end of the talk, I had shown most of the code on screen, all while digressing about many other things, answering questions, etc. I hope that helps make the point that Zephyr can really help you not reinvent the wheel, and help you focus more on the code that’s actually your application, and less on the boilerplate low-level stuff 🙂

Catch up on the recording here:

And as a reminder, all the code of the project is on GitHub, at so I encourage you to check it out!

And now, for the news from this past week…

Userspace on Xtensa

When building your application on top of Zephyr, you probably don’t want or need your entire code to run in supervisor mode, with full access to the memory, kernel objects, etc. While, say, a custom driver of your might require low-level interactions with the system, but your “actual” application probably only really cares about calling into a few APIs that will expose the data or functionality you need in your applications.

For architectures that include an MMU/MPU (Memory Management Unit / Memory Protection Unit), it is possible to instruct Zephyr to create so-called user-mode threads that end up running in their own sandbox, with very limited permissions unless explicitly granted.

This week, PR #61303 has introduced userspace support for Xtensa architectures, which is a major improvement, alongside a complete re-implementation of the MMU layer for Xtensa.

Picolibc 1.8.5

The newly released Zephyr SDK, version 0.16.4, ships the latest version of Picolibc, 1.8.5.

As per PR #62882, this new version of Picolibc brings more flexibility in selecting a printf/scanf variant to support only the format specifiers that one really needs, i.e. not bloat your binary if you don’t care about printing floats, for example.

As a reminder, while using a pre-compiled version from Picolibc straight from the SDK will give you faster compilation times, there is always the possibility to enable Kconfig option CONFIG_PICOLIBC_USE_MODULE if you want to tweak Picolibc further.

Stay tuned for a Zephyr Tech Talk entirely dedicated to Picolibc C on Wednesday, Dec. 6!

IGMPv3 support

The Internet Group Management Protocol (IGMP) is a protocol primarily used for managing multicast group memberships on IPv4 networks. It enables a host to inform its local router about its desire to join or leave a multicast group, which can be useful when building e.g. sensor networks where you want to use network resources as efficiently as possible.

As of this week, IGMPv3 is now supported. (PR #65293)

Among other things, IGMPv3 allows source filtering, enabling a system to report interest in receiving packets only from specific source addresses, or from all but specific source addresses, sent to a particular multicast address.

Boards & SoCs

STM32U5A9J-DK development board


  • A new pwm-clock binding allows to add a clock control device for a PWM node, such that the PWM can be controlled using the clock control API.
pwmclock: pwmclock {
    status = "okay";
    compatible = "pwm-clock";
    #clock-cells = <1>;
    pwms = <&pwm_ccu40 2 PWM_HZ(1000000) PWM_POLARITY_NORMAL>;
  • New regulator driver for Smartbond DA1469X SoC. (PR #65226)


  • The Bluetooth Hearing Access (HAS) server now uses non-volatile settings to restore the client awareness of preset list entries exposed by the server. (PR #64164)
  • A lot of work went into cleaning up the documentation of the POSIX API available in Zephyr.
  • A new Kconfig option, CONFIG_SDL_DISPLAY_ZOOM_PCT allows to artificially tweak the scale of the main display when using a native simulation on your desktop.
    This can be really useful when testing, say, a 200x200px smartwatch GUI on your 32″ Retina display, without killing your eyes 🙂 (PR #65556)
  • New shell commands (that can be enabled using CONFIG_PLIC_SHELL) to display the hit count of each interrupt controller’s IRQ line. (PR #65533)
uart:~$ plic stats get interrupt-controller@c000000
   IRQ        Hits
    10         236

uart:~$ plic stats clear interrupt-controller@c000000
Cleared stats of interrupt-controller@c000000.

uart:~$ plic stats get interrupt-controller@c000000
   IRQ        Hits
    10          90

  • Various improvements and optimizations to the modem UART backend (PR #65194)

A big thank you to the 12 individuals who had their first pull request accepted this week, 💙 🙌: @ajarmouni-st, @lukas-fwdev, @adolfogc, @adleris, @arnaudmz, @adrienbruant, @wmrsouza, @falvia, @deveritec-rosc, @kamilrakoczy, @ndrs-pst, and @idruzhinin.

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: