IoT Zephyr

Zephyr Weekly Update – Fixing the search experience

As a lot of folks are wrapping up for the holiday season, the Zephyr community hasn’t slowed down all that much last week and there were quite a few noteworthy additions that this blog post will be covering, including a pretty cool (albeit short!) demo video.

Improved documentation search experience

One of the top complaints I’ve heard ever since I became the documentation manager for the Zephyr Project is how it can sometimes be hard to find information in the project’s documentation. It’s certainly true that the search engine historically available on isn’t always giving the most helpful results.

As of last week, a new search experience is available with Google Programmable Search now being the default search engine when browsing the Zephyr documentation.

The new engine is faster, much more tolerant to typos, and allows you to write advanced search queries that are more than just a couple keywords (ex. you may use double-quotes to keep words together, exclude keywords by using the minus sign, etc.).

Meta-categories such as “Code Samples”, “API reference”, etc. are also available for you to narrow down the list of search results to only the category of results you care about (if you feel a category is missing, btw, let me know!). See for example the screenshot below, with top 3 results to the query “toggle a GPIO” — they are exactly what you’d expect them to be, but should you want more concrete examples of how to toggle a GPIO, clicking the “Samples” tab (or the green label in the search results) will give you just that!

Search results for “toggle a GPIO” using the new search experience in

💡 Pro Tip: Press / to quickly focus on the search box while navigating the documentation.

Capacitive touch sensor for ESP32

Capacitive touch sensors are a kind of specialized GPIO with dedicated circuitry that detects an approaching finger by measuring a variation in the capacitance of the circuit.

Espressif devices typically include support for capacitive touch, and PR #64931 just made it possible to access this feature in Zephyr! The new driver is a standard input driver and as such fits nicely in the now pretty rich input subsystem.

The dedicated Devicetree binding, espressif,esp32-touch exposes a variety of settings to adjust the sensitivity, configure the debouncing, etc.

Here is, for example, the full Devicetree overlay to enable touch detection on pin TCH8 of my M5Stack AtomS3:

#include <zephyr/dt-bindings/input/input-event-codes.h>
#include <zephyr/dt-bindings/input/esp32-touch-sensor-input.h>

&touch {
debounce-interval-ms = <30>;
href-microvolt = <2700000>;
lref-microvolt = <500000>;
href-atten-microvolt = <1000000>;
filter-mode = <ESP32_TOUCH_FILTER_MODE_IIR_16>;
filter-debounce-cnt = <1>;
filter-noise-thr = <ESP32_TOUCH_FILTER_NOISE_THR_4_8TH>;
filter-jitter-step = <4>;
filter-smooth-level = <ESP32_TOUCH_FILTER_SMOOTH_MODE_IIR_2>;

status = "okay";

touch_sensor_set: touch_sensor_0 {
channel-num = <8>;
channel-sens = <50>;
zephyr,code = <INPUT_KEY_0>;


And below is the code sample in action. If you’re not familiar with capacitive touch and a bit confused looking at the video, yes, this is indeed literally a single wire that’s being used as the input!

Funnily enough, it took me about 30 seconds to get the sample to work, and probably 10 times more to videotape it! 😝

Boards & SoCs

BeagleBoard BeagleV®-Fire
  • Beagleboard BeagleV-Fire is a single board computer (SBC) built around Microchip’s PolarFire MPFS025T SoC FPGA. In addition to providing an FPGA with 23K logic elements, it features a 5-core RISC-V 64-bit processor. (PR #66389)
  • nRF9151-DK, an upcoming developer kit from Nordic Semiconductor and targeting DECT NR+ and LTE-M/NB-IoT with GNSS, is already supported in Zephyr 🙃. (PR #66110)
  • The PAN1783A Evaluation Board from Panasonic is now supported. (PR #64259)
  • The Ambiq Apollo4P evaluation board is built around Ambiq’s ultra-low power Apollo4 Plus SoC, which is a Cortex M4F @ 192 MHz. (PR #66328)
  • ST Nucleo F722ZE is now supported. (PR #66050)


  • Expanding on the recently added modem subsystem, a new API has been added to interact with cellular modems in a consistent way across all available technologies (GSM, GPRS, LTE, etc.). Think retrieving signal strength information, for example.
    Check out the documentation here and how the new API is now used in the cellular modem code sample. (PR #65685)
  • Ultrachip UC8175 support has been added. (PR #61439)
  • The Charger API now includes a sbs_charger_charge_enable() standard API that can be use to initiate/terminate a charging cycle. (PR #66128)
  • STM32 MCUs can now use SMBus thanks to the newly added driver. (PR #66260)
  • New driver added for ST LIS2DU12 accelerometer. (PR #65734)


  • The Bluetooth Gaming Audio Profile aims at enabling configuration of low-level audio services and profiles specifically for gaming use cases (ex. bidirectional voice for online chat, high bitrate for HQ game audio, etc.).
    PR #57032 is the oldest pull request merged this week (dating back to April of this year) and it introduces support for the Bluetooth Gaming Audio Profile in Zephyr.
  • Initial support for USB Audio Class 2 has been added. The idea will be to allow developers to use the zephyr,uac2 binding to describe an USB Audio Class 2 device by utilizing the Devicetree vs. manually written code.
  • A new API allows to configure CoAP retransmission settings. (PR #66025)
  • Support for TCP Keep-Alive has been introduced and can be enabled using Kconfig option NET_TCP_KEEPALIVE. (PR #66316)
  • The unused and obsolete arm_core_tz.c Arm TrustZone driver has been removed. (PR #66224)
  • Improvements have been made to the Device Power Management framework to not unnecessarily resume/suspend in some situations. (PR #66246)
  • If you’ve started to look into the new keyboard matrix driver, you will likely find the new input kbd_matrix_state_dump shell command quite useful. As its name indicates, given the id of a keyboard matrix Devicetree node, it will dump the state of the keyboard matrix every time a key is pressed/released.
  • The documentation of the pytest plugin has been vastly improved, and so has the API reference for the Sockets API.

With the holiday season upon us, I will be back with the next update on January 5th. Hopefully I won’t be buried under thousands of pull requests to write about, but should that be the case I will do my best to highlight the most noteworthy ones!

A big thank you to the 12 individuals who had their first pull request accepted this week, 💙 🙌: @ryukoposting, @hellesvik-nordic, @sebastianschlupp, @kevinior, @aofrioWeifengLi, @VuDangBP, @BryanZhuAM, @AlessioLei94, @alelec13, @helen741, @Burt-Silverman, and @sateeshkotapati.

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 – 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: