https://github.com/sifive/pydevicetree
Python Library for Parsing Devicetree Source v1
https://github.com/sifive/pydevicetree
devicetree python python3
Last synced: about 1 year ago
JSON representation
Python Library for Parsing Devicetree Source v1
- Host: GitHub
- URL: https://github.com/sifive/pydevicetree
- Owner: sifive
- License: apache-2.0
- Created: 2019-11-06T21:40:46.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-06-19T14:47:01.000Z (about 2 years ago)
- Last Synced: 2025-03-27T02:08:06.780Z (over 1 year ago)
- Topics: devicetree, python, python3
- Language: Python
- Homepage: https://pypi.org/project/pydevicetree/
- Size: 159 KB
- Stars: 25
- Watchers: 50
- Forks: 8
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# pydevicetree
This is a Python 3 library for parsing, querying, and modifying Devicetree Source v1 files as
described in the [Devicetree Specification v0.2](https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.2).
## Install
pydevicetree supports Python >= 3.5 and can be installed with pip from the [Python Package Index](https://pypi.org/project/pydevicetree/).
`pip install pydevicetree`
## Tutorial
### The Devicetree
Let's say you have a file design.dts with the contents
```
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
compatible = "my,design";
aliases {
serial0 = "/soc/uart@10000000";
};
chosen {
stdout-path = "/soc/uart@10000000:115200";
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "sifive,rocket0", "riscv";
device_type = "cpu";
reg = <0>;
riscv,isa = "rv32imac";
status = "okay";
timebase-frequency = <1000000>;
sifive,dtim = <&dtim>;
interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "my,design-soc";
ranges;
dtim: dtim@20000000 {
compatible = "sifive,dtim0";
reg = <0x20000000 0x10000000>;
reg-names = "mem";
};
uart: uart@10000000 {
compatible = "sifive,uart0";
reg = <0x10000000 0x1000>;
reg-names = "control";
};
};
};
```
### Parsing the Tree
Parsing the tree is as easy as 1, 2...
```
>>> from pydevicetree import Devicetree
>>> tree = Devicetree.parseFile("design.dts")
>>> tree
```
### Querying the Tree
#### By `compatible` string
```
>>> tree.match("sifive,rocket0")
[]
```
#### By path
```
>>> tree.get_by_path("/soc/dtim")
```
Devicetree aliases are allowed in paths
```
>>> tree.get_by_path("serial0")
```
#### Getting `Node` properties
The value (or first value of a list/array) of a property can be retrieved with `Node.get_field()`
```
>>> tree.match("sifive,rocket0")[0].get_field("timebase-frequency")
1000000
```
The list or array of values assigned to a property can be retrieved with `Node.get_fields()`
```
>>> tree.match("sifive,rocket0")[0].get_fields("compatible")
```
There are helper methods `Node.get_reg()` and `Node.get_ranges()` for the `reg` and `ranges`
Devicetree properties.
```
>>> tree.get_by_path("/soc/dtim").get_reg()
>>> tree.get_by_path("/soc/dtim").get_reg().get_by_name("mem")
(536870912, 268435456)
>>> "0x%x" % tree.get_by_path("/soc/dtim").get_reg().get_by_name("mem")[0]
'0x20000000'
```
#### Getting `chosen` properties
`Devicetree.chosen()` provides quick access to the properties of the `chosen` node
```
>>> tree.chosen("stdout-path")
```
### Converting back to Devicetree
Any tree or subtree can be converted back to Devicetree by calling `Node.to_dts()` or simply
by `print`ing it:
```
>>> print(tree.match("sifive,rocket0")[0])
cpu@0 {
#size-cells = <0>;
compatible = "sifive,rocket0", "riscv";
device_type = "cpu";
reg = <0x0>;
riscv,isa = "rv32imac";
status = "okay";
timebase-frequency = <1000000>;
sifive,dtim = <&dtim>;
interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
```