How to Write Device Drivers for Zephyr RTOS

In embedded system development, developing device drivers is a crucial task. As a bridge connecting hardware and software, the quality of device drivers directly impacts the correctness of system functionality and operational stability. In the rapidly evolving open-source ecosystem, Zephyr RTOS is favored by developers for its lightweight, modular, and highly scalable nature. However, in contrast to its widespread application, there is relatively little detailed information and tutorials on developing device drivers for Zephyr RTOS, which poses significant challenges for many developers in their actual work.

To address this issue, the Key Laboratory of Embedded Computing Technology Research and Development Center will take the development of device drivers for Zephyr RTOS as an example, starting from basic knowledge and gradually delving into practical operations, guiding everyone through a complete process of writing a driver program. Through this article, you will not only understand the driver development mechanism of Zephyr RTOS, but also master the core skills from theory to practice, helping you to develop high-quality device drivers with ease in actual projects.

1. What is a Device Driver? Why Do We Need Device Drivers?

A device driver is a “translator” between the operating system and hardware devices. By abstracting the complexity of hardware, drivers allow the operating system to interact with devices in a unified manner. Using drivers enables developers to use device functionalities without worrying about hardware details; they just need to call standard interfaces.

In Zephyr, the composition of device drivers mainly includes device tree files, driver model files, and driver code (Figure 1). The device tree file is used to define device information (such as address and clock), the driver model file standardizes the driver interface (such as i2c.h), while the driver code is the core implementation logic of the driver.

How to Write Device Drivers for Zephyr RTOSFigure 1: General Composition of Zephyr Drivers

2. Steps to Write a Device Driver for Zephyr RTOS

Step 1: Familiarize Yourself with Device Functions and Features

The first step in driver development is to understand the target device. Only by understanding the functions and features of the hardware can the correct driver be written. During this process, it is necessary to understand the device usage, device composition, and device functionality. It is recommended to read the chip manual to understand the definitions and functional descriptions of device registers. For example, with the RK 3568, you can refer to the chip manual of RK3568 (Figure 2) to understand the register definitions of the driver you are going to write; you can also check blogs, videos, and other online resources to quickly grasp the working principles of the device.

How to Write Device Drivers for Zephyr RTOS

Figure 2: Functional Description of I2C in the RK3568 Chip Manual

Step 2: Familiarize Yourself with the Driver Framework of Zephyr RTOS

After familiarizing yourself with the device functions and features, the next step is to study how to control the device through software. The key focus at this stage is to understand the driver framework of Zephyr RTOS, which can be referenced from the official Zephyr documentation and driver examples as well as corresponding Linux drivers. The official documentation of Zephyr provides a unified driver interface and clear driver logic, following its specifications can enhance the reusability of drivers while strengthening the understanding of device functionalities. For example, the I2C driver model (include/zephyr/drivers/i2c.h) provides standard API interfaces for i2c device drivers; while the logic of Linux drivers, although complex, is quite complete and can serve as a reference for driver design, learning the logic of board drivers.

Step 3: Set Up the Driver Framework (Taking PWM Driver Development as an Example)

Writing driver code first requires setting up the framework. Once the framework is completed, the operating system will be able to recognize the device. The framework setup process includes two stages:

(1) Configure the Device Tree File. Write the device’s .yaml binding file to define node contents, add device node information in the .dtsi or .dts files, and allocate node space in mmu_region.c (Figure 3).

How to Write Device Drivers for Zephyr RTOSFigure 3: Process of Configuring the Device Tree File

(2) Register the Driver. Create the corresponding source code file in the driver folder, and register the driver in CMakeLists.txt and Kconfig to ensure that the driver you wrote can be correctly linked to the program (Figure 4).

How to Write Device Drivers for Zephyr RTOS

Figure 4: Process of Registering the Driver

Step 4: Write the Specific Driver Program (Taking PWM Driver Development as an Example)

After completing the framework setup, you will enter the specific driver program writing phase to implement the device functionalities. Based on the register descriptions in the device manual, implement the specific functional logic. Before officially writing, we need to clarify the overall logic of the driver, which can be organized and converted into Uboot, using the mw command to write values to registers and check if the device responds, or use the md command to read register values to verify if the configuration is effective.

After validating the driver logic, you can start writting the specific driver code, including defining the device initialization function, completing the basic configuration of the driver based on the device tree content, and registering it to Zephyr RTOS. After that, configure the registers to their default state, provide device operation interfaces (such as read and write functions), and implement other advanced functionalities as needed. Note that one of the core tasks of writing a driver program is to operate hardware registers. The essence of driver development is to provide an abstraction layer for hardware, interacting with the underlying hardware through reading and writing registers. At this step, the logical clarity and standardization of the driver are very important. It is recommended to implement the code in modules for easier maintenance and debugging.

How to Write Device Drivers for Zephyr RTOS

Figure 5: Writing the Specific Driver Code

Step 5: Testing and Debugging

After writing the driver, you need to ensure the functionality is correct through compilation and actual testing. During testing, first compile the code, using the toolchain provided by Zephyr, and check for syntax and logical errors based on the compilation information; then perform hardware testing, burn the code onto the hardware, and use an oscilloscope or logic analyzer to verify functionality. If any issues are found, you can gradually locate errors using logs and hardware tools.

2. Precautions: CRU and SYSCON Configuration Issues

In general device driver development, there will be corresponding CRU (focused on clock and reset signal management) and SYSCON (providing global control for the system) settings (unless the devices require default states (Figure 6)), but the manuals and Linux drivers generally do not mention the need to configure CRU and SYSCON, which often leads to forgetting to configure them, resulting in devices not functioning properly.

Note that SYSCON does not need manual initialization, and in CRU, most devices are clocks that also use a 24M crystal clock, which does not require manual initialization. You only need to select the corresponding function in the corresponding registers.

How to Write Device Drivers for Zephyr RTOSFigure 6: Initialization Settings for CRU and SYSCON

3. Summary:

Driver development is the intersection of software and hardware. Mastering the writing of Zephyr RTOS drivers not only significantly enhances development skills but also provides important assurance for efficiently utilizing hardware resources. Through the above steps, from analyzing device characteristics, setting up the framework, to implementing functionalities and testing, we have completed a comprehensive Zephyr RTOS driver development process. Each step is crucial, requiring both a deep understanding of hardware and familiarity with the Zephyr driver framework and practical experience.

I hope this article provides you with clear ideas and practical guidance to help you start writing high-quality Zephyr RTOS drivers from scratch. If you encounter any issues during the development process, feel free to leave a message in the comment section, and we will discuss and share experiences together!

How to Write Device Drivers for Zephyr RTOS
ZVM: Next-Generation Type 1.5 RTOS Virtualization Solution

https://gitee.com/openeuler/zvm

Long press to identify the QR code, join the ZVM technology exchange group

Leave a Comment