EmbeddedRelated.com
The 2026 Embedded Online Conference

Getting Started With Zephyr: DTS vs DTSI vs Overlays

Mohammed BillooMohammed Billoo October 3, 2025

Devicetrees can be daunting for traditional embedded software engineers that are new to Zephyr. In this blog post, I address these fears and show how navigating Devicetrees can be much easier if you understand that they represent the layered structure of the underlying hardware.


Getting Started With Zephyr: Using GDB To Fix a Driver Bug

Mohammed BillooMohammed Billoo August 8, 2025

In this blog post, I show how to use GDB to debug an issue encountered with a TSL2591 light sensor driver in Zephyr. The fix was submitted and successfully incorporated into The Zephyr Project.


Zephyr: West Manifest For Application Development

Mohammed BillooMohammed Billoo November 25, 2024

In this blog post, I show a simpler way to create custom West manifest files. This technique eliminates the need to duplicate the complex West manifest from upstream Zephyr. I also show how we can use the West manifest to include out-of-tree board and SoC definitions, and include our own out-of-tree drivers.


ANCS and HID: Controlling Your iPhone From Zephyr

Mohammed BillooMohammed Billoo June 11, 2024

In this blog post, we see how certain BLE services can be used to control an iPhone from a Nordic nRF52840 using The Zephyr Project. Specifically, we see how to control certain multimedia functionality using the HID service. Finally, we learn how to use the ANCS client library provided by Nordic in The Zephyr Project to accept or decline an incoming call.


Getting Started With CUDA C on an Nvidia Jetson: A Meaningful Algorithm

Mohammed BillooMohammed Billoo May 11, 2024

In this blog post, I demonstrate a use case and corresponding GPU implementation where meaningful performance gains are realized and observed. Specifically, I implement a "blurring" algorithm on a large 1000x1000 pixel image. I show that the GPU-based implementation is 1000x faster than the CPU-based implementation.


Getting Started With CUDA C on an Nvidia Jetson: GPU Architecture

Mohammed BillooMohammed Billoo March 28, 2024

In the previous blog post (Getting Started With CUDA C on Jetson Nvidia: Hello CUDA World!) I showed how to develop applications targeted at a GPU on a Nvidia Jetson Nano. As we observed in that blog post, performing a calculation on a 1-D array on a GPU had no performance benefit compared to a traditional CPU implementation, even on an array with many elements. In this blog post, we will learn about the GPU architecture to better explain the behavior and to understand the applications where a GPU shines (hint: it has to do with graphics).


Getting Started With CUDA C on an Nvidia Jetson: Hello CUDA World!

Mohammed BillooMohammed Billoo March 13, 2024

In this blog post, I introduce CUDA, which is a framework designed to allow developers to take advantage of Nvidia's GPU hardware acceleration to efficiently implement certain type of applications. I demonstrate an implementation to perform vector addition using CUDA C and compare it against the traditional implementation in "regular" C.


Getting Started With Zephyr: Bluetooth Low Energy

Mohammed BillooMohammed Billoo January 29, 2024

In this blog post, I show how to enable BLE support in a Zephyr application. First, I show the necessary configuration options in Kconfig. Then, I show how to use the Zephyr functions and macros to create a custom service and characteristic for a contrived application.


Getting Started With Zephyr: Writing Data to EEPROM

Mohammed BillooMohammed Billoo December 6, 20235 comments

In this blog post, I show how to implement a Zephyr application to interact with EEPROM. I show how the Zephyr device driver model allows application writers to be free of the underlying implementation details. Unfortunately, the application didn't work as expected, and I'm still troubleshooting the cause.


Getting Started With Zephyr: Saving Data To Files

Mohammed BillooMohammed Billoo October 31, 20231 comment

In this blog post, I show how to implement a Zephyr application to mount a microSD card, create a new file on the microSD card, and write data to it. The lessons learned from such an application can be helpful for devices out in the field that need to write data to off-board memory periodically, especially in cases where Internet access may be sporadic.


Getting Started With Zephyr: West Manifest Customization

Mohammed BillooMohammed Billoo April 4, 2023

Create a reproducible Zephyr development baseline by customizing a West manifest, so your team avoids surprises from upstream changes. This post walks through forking Zephyr and MCUBoot when you need local changes, adapting Nordic Semiconductor's west.yml as a template, and updating remotes and defaults to point at your forks. Finish by running west init -m --mr to fetch exact revisions.


Libgpiod - Toggling GPIOs The Right Way In Embedded Linux

Mohammed BillooMohammed Billoo January 24, 2023

Accessing GPIOs through sysfs is simple but fragile, causing race conditions when multiple userspace processes touch the same line. This post explains libgpiod, introduced in Linux 4.8, and shows concise Python examples on a Toradex Verdin iMX8M Plus for requesting lines, tagging the consumer, using active_low flags, and reading or driving values. Learn why libgpiod provides safer, atomic GPIO handling.


Getting Started With Zephyr: Devicetree Overlays

Mohammed BillooMohammed Billoo September 25, 2023

In this blog post, I show how the Devicetree overlay is a valuable construct in The Zephyr Project RTOS. Overlays allow embedded software engineers to override the default pin configuration specified in Zephyr for a particular board. In this blog post, I use I2C as an example. Specifically, I showed the default I2C pins used for the nRF52840 development kit in the nominal Zephyr Devicetree. Then, I demonstrated how an overlay can be used to override this pin configuration and the final result.


Getting Started With Zephyr: Saving Data To Files

Mohammed BillooMohammed Billoo October 31, 20231 comment

In this blog post, I show how to implement a Zephyr application to mount a microSD card, create a new file on the microSD card, and write data to it. The lessons learned from such an application can be helpful for devices out in the field that need to write data to off-board memory periodically, especially in cases where Internet access may be sporadic.


Getting Started With Zephyr: Kconfig

Mohammed BillooMohammed Billoo June 22, 2023

In this blog post, we briefly look at Kconfig, one of the core pieces of the Zephyr infrastructure. Kconfig allows embedded software developers to turn specific subsystems on or off within Zephyr efficiently and control their behavior. We also learn how we can practically use Kconfig to control the features of our application using the two most common mechanisms.


Getting Started With Zephyr: Devicetrees

Mohammed BillooMohammed Billoo July 18, 20232 comments

This blog post provides an introduction to the "Devicetree", another unique concept in The Zephyr Project. We learn about the basic syntax of a device tree and how its structure and hierarchy mirror hardware, from the SoC to the final board. We also see how hardware described in a devicetree can be referenced and controlled in the source code of a Zephyr-based application.


Getting Started With Zephyr: Writing Data to EEPROM

Mohammed BillooMohammed Billoo December 6, 20235 comments

In this blog post, I show how to implement a Zephyr application to interact with EEPROM. I show how the Zephyr device driver model allows application writers to be free of the underlying implementation details. Unfortunately, the application didn't work as expected, and I'm still troubleshooting the cause.


Peripheral Interaction Without a Linux Device Driver Using Spidev

Mohammed BillooMohammed Billoo November 20, 2022

Kernel-space drivers are not always necessary; many SPI peripherals can be handled from userspace using spidev. This post shows how to expose an SPI device through the device tree and kernel, wire a Bosch BMP388 to a Toradex Apalis iMX8 Ixora board, and implement a C userspace app that uses ioctl to read the chip ID. Practical tips on SPI settings and logic-analyzer validation are included.


Getting Started With Zephyr: Bluetooth Low Energy

Mohammed BillooMohammed Billoo January 29, 2024

In this blog post, I show how to enable BLE support in a Zephyr application. First, I show the necessary configuration options in Kconfig. Then, I show how to use the Zephyr functions and macros to create a custom service and characteristic for a contrived application.


Getting Started With Embedded Linux - From Nothing To A Login Prompt

Mohammed BillooMohammed Billoo September 28, 2022

This hands-on guide shows how to go from a blank board to a bootable embedded Linux system using Yocto and Docker. Follow the steps to build a reproducible Yocto environment, fetch Toradex manifests, set MACHINE to verdin-imx8mm, run bitbake, and produce the .wic.bmap image ready to flash. Ideal for engineers wanting a concise bringup path for a Verdin iMX8M Mini on a Dahlia carrier.


The 2026 Embedded Online Conference