
Abstract
The relationships between devices are various forms of derived inheritance, tracing back to a common origin. This article discusses the concept of “device framework” or “device tree” in embedded systems, analyzing its design intent, core design philosophy, implementation principles, etc., using the device framework of the RT-Thread system as an example.

Concept of Device Framework
In embedded systems, the device driver framework or device tree is an important mechanism for managing system hardware resources, improving code reusability, and simplifying the driver development process. This functionality is supported in various embedded systems such as Linux, RT-Thread, VxWorks, and Zephyr.
So, what is a device framework? Consider this: why do various types of mice work immediately when plugged into a computer? This is because manufacturers design the software interface for mice according to the same set of standards, allowing the operating system to manage the mice according to this interface to achieve the expected results.
In embedded systems, the device framework is a structured method and tool designed to manage hardware devices, facilitating their management, organization, and interaction. It constructs an abstraction layer between applications and actual devices, isolating applications from hardware, simplifying hardware management, and providing developers with a unified interface to access and control hardware resources. This allows applications to be independent of specific hardware details, reducing coupling and improving reliability.
Core Design Philosophy
To achieve the desired functionality of the device framework, efforts should be directed towards the following aspects:
- Unified Device Model: Starting from the need for a unified interface call from the application layer downwards, all devices must be represented in a unified model within the device framework, enabling unified management at the application layer.
- Device Identification: Although the calling interfaces are the same, devices must have fields that identify differences between individual devices to allow the upper layer to locate and use them correctly.
- Compatibility with Various Devices: The device framework should be able to organize and manage various devices. How to resolve the contradiction between a unified device framework and support for various devices? By constructing it in an object-oriented manner, abstracting upwards to summarize the common attributes and methods of various devices, and concretizing downwards to exhibit the differences of various devices.
- Hardware Platform Interface: To ultimately implement device driver programs, the framework needs to include attributes and methods related to the hardware platform, such as pin numbers, interrupt numbers, DMA configurations, etc.
- Inheritance and Derivation: How to connect the upward abstraction and downward concretization in the device framework? By using inheritance and derivation methods in object-oriented programming, layer by layer analyzing and connecting the upper abstract and lower concrete frameworks.
- Device Lifecycle Management: Supporting operations such as device registration, lookup, initialization, and removal.
- Resource Protection: The device framework should support the protection of shared resources within devices to ensure the safety of multi-threaded access.
Framework Layering
To achieve the above features, the device framework is implemented in three layers: IO device management layer, device driver framework layer, and device driver layer.

IO Device Management Layer
This layer serves as a barrier between the application layer and the underlying devices, abstracting various hardware devices (UART, SPI, IIC, etc.) into a unified form for description, facilitating upper layers to manage these devices according to a unified interface. It shields the upper layer from the impacts of underlying device upgrades and replacements, allowing independent development of upper application and lower device code, reducing coupling and improving reliability. The differences in attributes and methods of devices like UART and SPI are implemented in the next layer.
Device Driver Framework Layer
This layer implements the generic parts of a certain type of device driver that are independent of the hardware platform. Based on the previous layer, it extends the unique attributes of a certain type of device, extracting and encapsulating the common parts of attributes and methods for the same type of devices, while the remaining parts that differ due to the hardware platform are implemented in the next device driver layer.
Device Driver Layer
This layer is responsible for creating the final device entity, containing information related to specific hardware dependencies, implementing the programs that directly drive the hardware, and completing the registration of the device in the system.
Unified Device Model
The device framework is designed in three layers, and the corresponding unified model of the device is also encapsulated and implemented in three layers. The class relationships related to the unified device model are shown in the following diagram:

The specific members and their approximate functions of each class are shown in the following diagram:

This unified device model is designed according to object-oriented principles, continuously abstracting from the bottom up, shielding different details below, and abstracting the common parts to the upper layer; it is also designed according to interface-oriented principles, using the inheritance relationship between parent and child classes to connect layers of abstraction, where subclasses are constrained by the interfaces of parent classes and implement the interfaces of the parent class. The relationships between different devices are various forms of derived inheritance, tracing back to a common origin.
rt_object (object.c)
This represents and manages the foundation of various kernel objects in the system. Almost all kernel objects (threads, semaphores, devices) inherit from rt_object. Functions:
- Provides a unified kernel object management interface, facilitating common operations such as creation, deletion, and lookup of objects.
- Uses the name field for object lookup, aiding in debugging and usage.
- Object type identifiers indicate the unique state of specific objects.
- Combines linked lists and object containers (rt_object_container) to organize and manage different objects. The core function of device registration is to link and manage device objects using this linked list.

rt_device (device.c)
rt_device is the base class for all devices in RT-Thread, abstracting various hardware devices (UART, SPI, IIC, etc.) and virtual devices (virtual serial ports, etc.) into rt_device, allowing the upper layer to manage these devices according to a unified interface. The specific attributes and methods of devices like UART and SPI are implemented in the next layer.
rt_serial_device (serial.c)
Based on rt_device, it extends the unique characteristics of a certain type of device, extracting and encapsulating the common parts of attributes and methods for the same type of devices, while the remaining different parts are implemented in the next device driver layer.
stm32_uart (drv_uart.c)
Based on rt_serial_device, it extends the attributes and methods of this type of device on specific hardware.
Registration Process Description
The registration process is essentially the initialization process for various serial port objects. With so many members in the class, which layer should initialize these members? The principles are (first 1 then 2):
- Priority 1 Principle: Whoever understands should configure. For example, interfaces that directly operate on hardware are implemented in the device driver layer, which needs to register such interfaces to the device driver framework layer.
- Priority 2 Principle: Whoever uses should configure. For example, the device management layer needs to clear the identifier indicating how many threads are using this device. The sequence diagram for device registration is shown in the figure, with complex devices having an additional device driver framework layer.

- Bonus: Flowchart of the registration process
