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:

By Benjamin Cabé

Benjamin Cabé is a technology enthusiast with a passion for empowering developers to build innovative solutions. He has invented an award-winning open source and open hardware artificial nose that he likes to use as an educational platform for people interested in diving into the world of embedded development.
He is currently a Developer Advocate for the Zephyr Project at the Linux Foundation and lives near Toulouse, France, where he enjoys baking sourdough bread with the help of his artificial nose.

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: