• 嵌入式Linux开发---设备树


    起因:简单重复的板级硬件信息内容都写在linux内核中十分冗余臃肿,将他们抽离出来单独用一种文件描述,这种文件就是dtb
    设备树组成:1个dts文件+多个dtsi文件,编译成dtb文件就是真正的设备树
    兼容C语言特性,可以使用include包含其他dtsi和.h文件
    树形结构

    语法

    根节点标记 /

    /{
             根节点里面 可以 包含 子节点和 属性
    ...
    ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    子节点标记

    格式:

    node-name@unit-address
    {
    子节点可以包含其他后辈节点  以及  属性
    ...
    ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    node-name是节点名字:“uart1”表示这个节点是UART1外设
    unit-address:一般表示设备的地址或者寄存器的首地址。因为不是每个设备都有地址,如CPU和Intrrupt-Controller,没有地址就不写

    label 标签

    标签主要方便引用:
    格式:

    label: node-name@unit-address
    
    • 1

    就是用label:标记一下上面子节点的格式
    实例:

    cpu0: cpu@0
    
    • 1

    这里的label就是cpu0,实际引用时通过 &cpu0来引用,不需要输入完整的节点名字

    属性

    属性都是键值对
    值有四种情况:

    1. 字符串
    2. 32位无符号整数(列表)
    3. 字符串列表
    4. 空 也就是不写

    标准属性

    属性有自己定义的属性,自由书写,有点像写python变量的意思,标准属性是已经定义了的属性。
    不同的设备需要的属性不同,用户可以自定义属性。除了用户自定义属性,有很多属性是标准属性,Linux 下的很多外设驱动都会使用这些标准属性,几个常用的标准属性:

    1. compatible 值为字符串或字符串列表,兼容性,用于设备和驱动之间匹配的签名,可以是多个,优先级从前到后递减
    2. model 值为字符串 描述设备型号信息 等
    3. status 值为字符串 描述设备状态信息 可用值:“okey" “disable” “fail” “fail-sss” (sss为检测到的错误内容)
    4. address-cells 无符号 32 位 用于有子节点的设备,描述子节点的reg属性中地址信息所占用的字长 由几个32位组成
    5. size-cells 无符号32位 用于有子节点的设备,描述子节点的reg属性中长度信息的所占用的字长 由几个32位组成
    6. reg 表示与地址有关的空间资源信息,和地址相关的信息有两种:起始地址和地址长度
    7. rangers 一个地址转换表 每个项目由子地址 父地址和 空间长度 三部分组成
    8. name 已被弃用 不必了解
    9. device_type 描述设备的FCode,只能用于部分CPU和Memory节点

    特殊节点

    aliase:
    用于给一个节点起别名,功能上和label重复了,&label的方式去引用一个节点也是不错的

    chosen:
    主要为了向uboot和linux内核传递数据,如bootargs参数的值

    OF函数列举-内核中用于从设备树中获取信息的函数接口

    可以从该网站阅读Linux内核代码
    获取节点信息:

    of_find_node_by_name // - Find a node by its "name" property
    of_find_node_by_type // - Find a node by its "device_type" property
    of_find_compatible_node  //- Find a node based on type and one of the tokens in its "compatible" property
    of_find_matching_node_and_match // - Find a node based on an of_device_id match table.
    of_find_node_by_path //
    
    • 1
    • 2
    • 3
    • 4
    • 5

    查找节点的父/子节点:

    of_get_parent 
    of_get_next_child 
    
    • 1
    • 2

    或者节点属性值的接口:

    of_find_property 函数
    of_property_count_elems_of_size 函数
    of_property_read_u32_index 函数
    of_property_read_u8_array 函数
    of_property_read_u16_array 函数
    of_property_read_u32_array 函数
    of_property_read_u64_array 函数
    
    of_property_read_u8 函数
    of_property_read_u16 函数
    of_property_read_u32 函数
    of_property_read_u64 函数
    of_property_read_string 函数
    of_n_addr_cells 函数
    of_n_size_cells 函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这些都是基础知识,一些用法看这篇:

    https://blog.csdn.net/qq_28992301/article/details/53321610

  • 相关阅读:
    视频监控管理平台EasyCVR自动注销后,页面还存留播放窗口是什么原因?解决办法是什么?
    关于 Eclipse 的一场 “三角关系”
    基于Spring Boot 3 + Spring Security6 + JWT + Redis实现登录、token身份认证
    Unity的碰撞检测(三)
    Linux系统下的定时任务Crontab
    【CMake】第2篇 CMake构建.h与.cpp文件
    PostgreSQL 如果想知道表中某个条件查询条件在索引中效率 ?
    安卓版微信8.0.31内测版出炉:安装包变小,功能变多!
    如何基于 Apache Doris 构建新一代日志分析平台
    2023年亚太杯数学建模思路 - 案例:ID3-决策树分类算法
  • 原文地址:https://blog.csdn.net/weixin_43604927/article/details/126165623