树状显示dts设备树文件之间的包含关系(设备树树状图显示)(图形化显示设备树)

本文介绍了一个名为DeviceTreeMap.py的Python脚本,该脚本用于解析设备树(dts/dtsi)文件,并生成设备树的结构图。通过递归方式读取.dts或.dtsi文件中的内容,提取出被包含的所有子文件,最终展示整个设备树的层级结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果

新版效果图(python3)

help信息

help信息

效果展示

效果展示

-m参数介绍

显示更多信息的效果图

旧版效果图,已废弃(python2)
dts

使用步骤

# 查看帮助信息
python3 ~/DeviceTreeMap.py -h
    Usage:
        DeviceTreeMap.py -f [dts/dtsi]

        -h or --help:显示帮助信息
        -v or --version:显示版本
        -f or --file:指定dts/dtsi文件
        -p or --path:添加额外搜索路径
                             如果-f参数对应文件的目录下找不到dts/dtsi文件,在-p参数的路径下再尝试找一下
        -m or --more_info: 打印更多信息(显示.h)

# 例子:
## 一般使用-f参数指定dts文件即可
$ python3 DeviceTreeMap.py -f xxxx.dts
## 使用-m参数打印更多信息
$ python3 DeviceTreeMap.py -f xxxx.dts -m
## 如有些场景下,设备树显示不全,打印了warning信息,使用-p参数补齐补充路径(如MTK平台)
$ python3 DeviceTreeMap.py -f xxxx.dts -p ~/work/project/vnd/kernel-5.15/arch/arm64/boot/dts
## 打印更多信息
$ python3 DeviceTreeMap.py -f xxxx.dts -p ~/work/project/vnd/kernel-5.15/arch/arm64/boot/dts -m

注意:

  1. .dts是所有.dtsi的根,想要看项目中完整的设备树结构,必须要通过-f参数传入.dts文件路径
  2. 如果只是想查看部分树状结构,则需通过-f参数传入对应的.dtsi即可
  3. 需要使用Python3

DeviceTreeMap.py源码

#!/usr/bin/env python
# -*- coding=utf8 -*-
"""
# Author: wanghan
# Created Time : Sun 07 Jan 2018 06:27:32 PM CST
# File Name: DeviceTreeMap.py
# Description: Get Devices Tree Map
"""

import sys
import os
import re
import getopt

g_dt_file = ""
g_dt_path = []
g_more_info = False
g_devicetreemap_version = "2.2.0"

def usage():
    print(
"""
    Usage:
        DeviceTreeMap.py -f [dts/dtsi]

        -h or --help:显示帮助信息
        -v or --version:显示版本
        -f or --file:指定dts/dtsi文件
        -p or --path:添加额外搜索路径
                             如果-f参数对应文件的目录下找不到dts/dtsi文件,在-p参数的路径下再尝试找一下
        -m or --more_info: 打印更多信息(显示.h)
""")

class DeviceTreeMap(object):
    def __init__(self, filepath, parent = None, level = 0):
        self.name = os.path.basename(filepath)
        self.dir = os.path.dirname(os.path.abspath(filepath))
        self.filepath = os.path.abspath(filepath)
        self.level = level
        self.parent = parent
        self.child = []

    def printChild(self):
        n = 0
        if not self.level == 0:
            if self.level > 1:
                while self.level > n:
                    if len(self.parent.parent.child) > self.parent.parent.child.index(self.parent)+1:
                        if self.level != n+1 :
                            print("\t", end=' ')
                    else:
                        if self.level != n+1 :
                            print("\t", end=' ')
                    n = n + 1
            print("\t" + self.name)
        else:
            print(self.name)
        n = 0
        while len(self.child) > n:
            self.child[n].printChild()
            n = n + 1

    def printMap(self):
        print("")
        print("-----------------------------------")
        print("")
        self.printChild()
        print("")
        print("-----------------------------------")
        print("")

    def createTreeMap(self):
        theChild = None
        try:
            if g_more_info: # 打印遍历过程中的详细情况
                if self.filepath == g_dt_file:
                    print(self.filepath)
                else:
                    print("\t" * (self.level + 1) + self.filepath)
            for line in open(self.filepath):
                #if line.startswith("#include"):
                res = re.match('^\t*?\#include', line) # 按正则表达式,逐行遍历dts/dtsi文件
                if (res != None):
                    # print(line) # 打印符合正则表达式的行
                    if (re.match('.*<.*>.*', line) != None):
                        dtsiName = line.split()[1].strip('<') # 获取include关键字后面的文件名
                        dtsiName = dtsiName.split()[0].strip('>') # 获取include关键字后面的文件名
                    else:
                        dtsiName = line.split()[1].strip('\"') # 获取include关键字后面的文件名
                    if not dtsiName.endswith(".h"):
                        childFilepath = os.path.join(self.dir, dtsiName)
                        if not os.path.isfile(childFilepath):
                            for p in g_dt_path:
                                childFilepath = os.path.join(p, dtsiName)
                                if os.path.isdir(p) and os.path.isfile(childFilepath):
                                    break
                                else:
                                    childFilepath = os.path.join(self.dir, dtsiName)
                        theChild = DeviceTreeMap(childFilepath, self, self.level+1)
                        self.child.append(theChild)
                        theChild.createTreeMap()
                    else:
                        if g_more_info: # 打印遍历过程中的详细情况
                            print("\t" * (self.level + 1) + "[c header]: " + dtsiName)
                    pass
                pass
            pass
        except FileNotFoundError:
            print("Warning : Not Fount %s !" %self.filepath)

if __name__ == '__main__':

    if len(sys.argv)  == 1:
        usage()
        sys.exit(-1)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hvf:p:m", ["help", "version", "file=", "path=", "more_info"])   # sys.argv[1:] 过滤掉第一个参数(它是脚本名称,不是参数的一部分)
    except getopt.GetoptError:
        print("argv error,please input")

    for cmd, arg in opts:  # 使用一个循环,每次从opts中取出一个两元组,赋给两个变量。cmd保存选项参数,arg为附加参数。接着对取出的选项参数进行处理。
        if cmd in ("-h", "--help"):
            usage()
            sys.exit()
        elif cmd in ("-v", "--version"):
            print("Version : %s"  % g_devicetreemap_version)
            sys.exit()
        elif cmd in ("-f", "--file"):
            g_dt_file = os.path.abspath(arg)
        elif cmd in ("-p", "--path"):
            g_dt_path.append(os.path.abspath(arg))
        elif cmd in ("-m", "--more_info"):
            g_more_info = True

    if g_dt_file == "" or not os.path.isfile(g_dt_file):
        print("g_dt_file:" + g_dt_file)
        print("Error : Not found (.dts or .dtsi) file!")
        sys.exit(-1)

    rootDeviceTree = DeviceTreeMap(g_dt_file)
    #print("name    :" + rootDeviceTree.name)
    #print("filepath:" + rootDeviceTree.filepath)
    rootDeviceTree.createTreeMap()
    rootDeviceTree.printMap()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值