IoT Zephyr

Zephyr Weekly Update – Hello M5Stack Core2, Picolibc, et al.

This week, I am using the recently added support for M5Stack Core2 (thank you, Martin!) as an excuse to show you some pretty cool Zephyr tricks that I’m confident many of you didn’t know about 🙂

Before jumping right in, I want to say a big thank you to everyone who tuned in to the first Zephyr Tech Talk earlier this week. It was a lot of fun, there were tons of questions, and Mike was the perfect guest for this first episode.

On Wednesday, September 27, I will be chatting with Bjarki Arge Andreasen about the newly introduced modem subsystem, and I highly encourage you to sign up already to make sure you don’t miss this!

M5Stack Core2 is now supported, and why I find it extra cool

M5Stack Core2
M5Stack Core2
Did I mention the M5Stack Core2 is *packed* with on-board peripherals?

I am really excited that the support for M5Stack Core2 finally got merged this week. This is yet another great contribution from Martin Kiepfer and, similarly to the M5StickC Plus, I particularly like how this device is packed with on-board peripherals that happen to just work out-of-the-box in Zephyr.

I might record a longer demo video in the next few days, but in the meantime let me just show you three examples of why having out-of-the-box and full-blown support for the on-board peripherals is really neat:

  • The M5Stack Core2 features a power-management IC (PMIC), an AXP192, which is one of the supported regulators in Zephyr. It controls, among other things, the voltage being sent to the LCD backlight.
    Not sure what would be an appropriate brightness level for the LCD in your application? Curious about how low you can get until things are not really readable for your end-users anymore?
    Well, just use the built-in shell commands to interact with the regulator, and voila! No need to write custom test code and—maybe more importantly—no risk to fry your device since the min/max limits for all the power outputs are configured separately in the Devicetree.
uart:~$ regulator vget DCDC3
2.800 V
uart:~$ regulator vset DCDC3 2.5V
uart:~$ regulator vset DCDC3 3.3V
Why, yes, being able to interact with voltage regulators through shell commands is super convenient.
  • There is a real-time clock on board of the device (BM8563), connected to the main ESP32 over I2C.
    It’s of course a pretty useful companion for many applications where you need the date and. Again, not only is this particular RTC chip supported (so you can interact with it using the standard RTC API), but similarly to the regulator shell before you can, for example, easil set the date and time interactively, without having to write a single line of code for that.
uart:~$ rtc get pfc8563@51
uart:~$ rtc set pfc8563@51 2022-12-22
uart:~$ rtc get pfc8563@51
  • Last and certainly not least, the Core2 has an LCD display and a touch panel.
    I’ve mentioned it many times before but LVGL is an awesome tool for building embedded GUIs, and the fact that this particular device also has a touch interface makes it even more interesting, since LVGL input device interfaces and Zephyr’s input subsystem can work hand-in-hand. And as it seems to be all about shell awesomeness this week, here’s one more trick for you: the LVGL shell!
    It can be enabled using CONFIG_LV_Z_SHELL and it adds a couple commands that can be particularly useful for testing/troubleshooting your GUI. We all know that UI testing can be tricky, and even more so on embedded systems, and one such command allows you to enable an LVGL monkey which can be a great alternative to basically stress-test your UI and catch potential bugs, memory leaks, etc. Also, it’s super fun to watch, just see below!
uart:~$ lvgl monkey create pointer
Someone is really messing up with that touchscreen, eh? 🐵


This one is a pretty significant change! Picolibc is now the default C library for Zephyr.

Picolibc is a library offering standard C library APIs that targets small embedded systems with limited RAM.

In a nutshell, Picolibc brings even more modularity and configurability, making it easier to fine tune the footprint/performance of the C library. It’s also meant to bring you the best of both worlds between Zephyr’s minimal libc (small, but lacking too many features), and newlib (too heavy for most applications).

But frankly, I think I need to invite Keith, Picolibc’s author, to tell us more about it during an upcoming Zephyr Tech Talk (Keith, if you’re reading this… 😊).

You can of course still use CONFIG_LIBC_IMPLEMENTATION Kconfig to use another C library implementation.

Other boards & SoCs

Other boards added this week:

  • ESP32C3 LuatOS. Pretty nice to see more RISC-V boards, it had been a while! (PR #61915)
  • Raytac MDBT53-DB-40 and MDBT53V-DB-40 (PR #58841)


This week has been insane on the drivers front. Apologies if the list below is maybe not diving as deep as I typically try to into the specifics of each sensor as I usually do, but there’s just too much to cover this week. Hopefully the list below is a good and useful summary nevertheless.

  • Add support for devices of the ADC family MAX11102-MAX11117. (PR #60328)
  • TI TAS6422 is a two-channel audio amplifier for automotive applications (PR #59678)
  • TI BQ27z746 fuel gauge. (PR #59382)
  • TSL2540 ambient light sensor, a sensor that has, according to its datasheet, near photopic responsiveness (and yes, you too probably learned a word today!). (PR #59330)
  • When using RTC on STM32, it’s now possible to use calibration features (set_calibration / get_calibration), thanks to PR #62304, which also brings other fixes/improvements.
  • CAN-FD support has been added to ISO-TP, and the ISO-TP code sample has been updated accordingly. (PR #60323)
  • LPDAC (Low-Power Digital-to-Analogue Converter) support has been added for NXP LPCXpresso55S36. (PR #61459)
  • Native SD card support added for Microchip SAM4E MCU series (using ATMEL HSMCI peripheral). (PR #58233)
  • TI TCAN4x5x series of CAN controllers now supported, alongside the dedicated evaluation board, TCAN4550EVM. (PR #62033)
TCAN4550EVM (Credit: Texas Instruments)¶
  • Current sense amplifier driver, providing an easy way to describe a current sensing circuit hooked to an ADC, using some Devicetree magic, just see below. (PR #59139)
test_current: current_amp {
	status = "okay";
	compatible = "current-sense-amplifier";
	io-channels = <&my_adc_3>;
	io-channel-names = "CURRENT_AMP";
	sense-resistor-micro-ohms = <10>;
	sense-gain-mult = <1>;
	sense-gain-div = <1>;
  • It’s now possible to use NXP’s MU (Messaging Unit) as an MBOX device for inter-process communication.
  • Added support for Raspberry Pi Pico timer. (PR #57134)
  • KSCAN driver for Microchip now supports low-power mode. (PR #60806)
  • Driver for SSD1306 display now supports connections over SPI and I2C simultaneously. (PR #56887)
  • Driver for the BMM150 magnetometer now supports trigger mode. (PR #57985)


  • In addition to Bash and zsh, you can setup autocompletion for your West commands in fish shell. (PR #62477)
  • Added architectural support for shared interrupts. (PR #61422)
    I invite you to read this to learn more.
  • More LVGL goodness! PR #62141 introduces support for encoders as input devices. This can make for cool user interactions where you can e.g. use an encoder to focus on next/previous widget in the UI.
  • Wi-Fi shell keeps improving with PR #62201.

A big thank you to the 12 individuals who had their first pull request accepted this week, 💙 🙌: @electrocnic, @chuangzhu, @tswaehn, @andy3469, @likongintel, @Albort12138, @JPHutchins, @yclistanford, @vg-sc, @VivekUppunda, @wkhadgar, and @Emplis.

As always, please feel free to jump in with your thoughts or questions in the comments below. See you next week!

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 – Charge me up!

Happy Friday! In case you missed it, yesterday I had the opportunity to join Robert and Michael from Arm (thanks again for the invitation, guys!) as part of their Innovation Coffee series. I forgot to actually bring some coffee, but we had a nice chat nevertheless, and you may want to catch up the recording.

Also on YouTube, and also live, don’t forget to join the first ever Zephyr Tech Talk next week next Wednesday, Sept. 13, at 1pm UTC.

And now for this week’s update…!

New battery charger subsystem

There’s been a lot happening recently in Zephyr around all things battery-powered, and this week a new subsystem has been introduced to help dealing with battery chargers.

Among other features, battery chargers play a crucial role in preventing your smartphone or other battery-powered devices from overheating and basically exploding during recharging. 🙂

They typically expose a range of properties that allow to get information about the battery (voltage, temperature, …), as well as settings that can be applied to e.g. limit the charging current (again, you don’t want that poor battery of your to explode!).

You can check out pull request #56666 for more context.

Boards & SoCs

  • Support has been added for Silicon Labs BRD4170A board. (PR #62145)
  • Texas Instruments SimpleLink CC13x2/CC26x2 family now support MCUboot out-of-the-box, as PR #62239 introduced the changes required to properly described the flash partitions it requires.
  • If you are a user of NXP RT1170, you can now use the LinkServer utility to flash your board. (PR #62229)


  • A driver has been added for the F75303 temperature sensor from Fintek. The sensor has three temperature channels in total: one local (on-chip), and two remote. (PR #60833)
    Something that’s pretty cool is that Pawel (a first-time contributor to Zephyr!) also added an emulator for the sensor! 🙌
  • The AD56xx series of DACs (Digital-to-Analogue Converters) from Analog Devices is now supported. (PR #60347)
  • New driver for Texas Instrument’s VIM (Vectored Interrupt Manager), which is an external interrupt controller used e.g. in Beaglebone AI64. (PR #60856)
  • PWM driver for STM32 now supports capturing on four channels. (PR #57607)
  • Power management support has been added to the very popular LM75 digital temperature sensor, so that reading from it properly fails when the sensor is not powered. (PR #61167)


  • Two significant improvements to I²C logging were introduced with PR #60301:

I²C log outputs are now better aligned to make them much easier to compare visually:

D: I2C msg: io_i2c_ctrl7_port0, addr=50
D:    W      len=01: 00
D:    R Sr P len=08:
D: contents:
D: 43 42 41 00 00 00 00 00 |CBA.....

You can now use the Devicetree to filter which subset of I²C communications you want to get logs for. Very smart and very cool!

/ {
    i2c {
        display0: some-display@a {
        sensor3: some-sensor@b {

    i2c-dump-allowlist {
        compatible = "zephyr,i2c-dump-allowlist";
        devices = < &display0 >, < &sensor3 >;
  • For maintainers and contributors, please be aware that a new extension to Zephyr’s documentation generation system (Sphinx) allows to document code samples more precisely, in particular by indicating which API they are a good sample for, so that they then show up nicely in the associated documentation. Of course, I encourage everyone to help with porting over existing code samples to the new system 🙂 (PR #62029)
.. zephyr:code-sample:: blinky
   :name: Blinky
   :relevant-api: gpio_interface

   Blink an LED forever using the GPIO API.
  • Sysbuild now allows to configure/build applications in a specific order. (PR #57884). Read more here.

A big thank you to the 11 individuals who had their first pull request accepted this week, 💙 🙌: @piotrnarajowski, @warrenb78, @chienhung-lin, @inteljiangwe1, @semihalf-anikiel-pawel, @semihalf-jakiela-albert, @RichardSWheatley, @rriveramcrus, @andrewmclachlanadi, @rtalbott-tmo, and @ihidchaos.

As always please feel free to jump in with your thoughts or questions in the comments below. See you next week!

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 – Introducing the new modem subsystem

The Zephyr community is back to pretty much full-speed as the summer break comes to an end, and this week’s Zephyr update features a new, highly-anticipated, modem subsystem.

In other news, and before announcing this more formally next week, we are launching a new series of YouTube live streams, the Zephyr Tech Talks, starting September 13, and I hope many of you will join us!

Our first guest will be Mike Szczys, and he will be telling us all about taking the continuous integration and testing of Zephyr-based projects to the next level using actual hardware. Just click that notification bell on YouTube to make sure you don’t miss it (or you’ll be able to catch up the replay, don’t worry)!

I am looking for folks from the community to join us on the show and chat about some cool Zephyr/embedded topics so feel free to submit your ideas here to participate in future sessions!

New modem subsystem

It’s not often that nearly 10,000 of lines of code get contributed, so I really hope to do justice to this awesome contribution coming from Bjarki Arge Andreasen! Without further ado, let me introduce the new modem subsystem (PR #56692)

You may know that Zephyr already provides drivers for a handful of modems (cellular, not RTC, despite the cheesy GIF above 😊). However, current modem support has been somehow constrained by Zephyr’s device driver model, as it lacks the flexibility that would allow to accommodate the wide-ranging features of modern modems.

The newly introduced modem subsystem implements concepts coming from the Linux world such as chat and pppd, and a CMUX module to make the whole stack more modular (indicating whether you talk to the modem over UART or, say, IPC should be as simple as changing KConfig, right?), easier to test, and overall more efficient.

  • chat allows to handily “script” interactions with modems, and to model how the typical request/responses for dial-up, hang-up, etc. sequence. This helps remove a lot of the boilerplate code typically associated with parsing AT commands. See for example the dial script for a standard GSM modem:
			      MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT+CGACT=0,1", allow_match),
			      MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match),
			      MODEM_CHAT_SCRIPT_CMD_RESP_NONE("ATD*99***1#", 0),);
  • pppd abstracts and isolates the lower-level tasks associated with managing a PPP (Point-to-Point Protocol) session (authentication, IP address negotiation, etc.)
  • CMUX provides a way to have multiple data channels on a single serial bus (i.e. the one used between the application processor and the modem). For example CMUX is what makes it possible for a modem to be able to receive SMS messages while having a voice or data channel active at the same time.

And if you’re only interested in all of this as an end-user, and not someone who might potentially need to write their own modem driver in the near future, then you’ll probably still be interested in hearing that this new architecture consumes about 30% less RAM (~12KB) than before 🙂

I highly encourage you to try out the newly added Cellular Modem code sample, which shows everything in action, and how well it integrates with existing Zephyr concepts:

  • Powering on the modem, using device power management API pm_device_action_run(modem, PM_DEVICE_ACTION_RESUME) ;
  • Bringing up the network interface, using network interface API (net_if_up(net_if_get_default())) and network management API ;
  • Talking to an Internet server over UDP using standard BSD sockets ;
  • Power-cycling the modem to demonstrate how the network management stack automatically re-establishes the connection to the network.

Boards & SoCs

  • Support for the STM32F765xx series of SoC has been introduced. (PR #62055)
  • A new QEMU board definition for Xtensa Diamond DC233 has been added, which is particularly useful for testing all things MMU on Xtensa. (PR #61864)


  • New driver for the Fujitsu MB85RC FRAM. In case you’re not familiar with FRAM (Ferroelectric RAM), it is a type of non-volatile memory that combines the fast read and write access of dynamic RAM (DRAM) with the ability to retain data when power is removed, similar to flash memory. (PR #61653)
  • You can now monitor on-die operational temperature for NXP SoCs with a Temperature Monitor Module (TEMPMON). (PR #61119)
  • The USART driver for STM32 now supports wide data, and you can now use a word length of 9 bits when CONFIG_UART_WIDE_DATA is set. (PR #54354)
  • Battery-backed RAM can now be accessed from user threads. (PR #61869)
  • Various bug fixes and enhancements in INA237 and INA230 drivers should make for a much better experience if you’re using these power monitors from TI in your Zephyr projects. (PR #60717)
  • New GPIO controller for TI DaVinci family of SoCs. (PR #61316)
  • Added PWM support for Nuvoton NuMaker series.(PR #61469)


  • The newly introduced CONFIG_NET_INTERFACE_NAME Kconfig option allows applications to give network interfaces a name in order to simplify network interface management. (PR #61876)
  • When using DTLS, you can now use CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID to enable the DTLS Connection ID (CID) extension in Mbed TLS. This allows to identify DTLS connections across changes that may occur in the underlying transport. (PR #61483)


Last week I mentioned the line-up of nice improvements currently being made or about to be made to LVGL support in Zephyr.

A nice addition this week are the new zephyr,input-button-lvgl and zephyr,input-pointer-lvgl bindings. What they mean for you is that you can now declare in your Devicetree that a given input device should also act as an LVGL input device. The most straightforward application would be to convert a touch event on a touchscreen into a proper LVGL input event, but this can also be useful to map input keys to “virtual” touch events.

  Example configuration:

  pointer {
          compatible = "zephyr,lvgl-button-input";
          input = <&buttons>;
          input-codes = <INPUT_KEY_0 INPUT_KEY_1>;
          coordinates = <120 220>, <150 250>;

  When the device receives an input_event with code INPUT_KEY_0
  a click event will be performed at (120,220).

In practice, the underlying driver the underlying driver takes care of capturing the input events (ex. a touch screen), and exposes the Zephyr input device as a standard LVGL input device. (PR #60867)


demo_tag [00:00:01.165,204] <err> [log_demo_thread_id] main: Error message example.
demo_tag [00:00:01.165,230] <wrn> [log_demo_thread_id] main: Warning message example.
demo_tag [00:00:01.165,258] <inf> [log_demo_thread_id] main: Info message example.
  • A couple of new POSIX functions have been added:
    • clock_nanosleep(), which allows the calling thread to sleep for an interval specified with nanosecond precision. (PR #61671)
    • pthread_condattr_*() functions, to properly handle the attributes object of a condition variable. (PR #61926)

A big thank you to the 11 individuals who had their first pull request accepted this week 💙 🙌: @ickochar, @rahul-arasikere, @mdwt-ot, @robertkowalewski, @TomFinet, @tbitcs, @n1zzo, @rghaddab, @Durchbruchswagen, @almir-okato, and @mariopaja.

As always please feel free to jump in with your thoughts or questions in the comments below. See you next week!

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: