linux设备树相关

1,设备树

设备树(Device Tree)是一套用来描述硬件属性的规则。在 2011年3月17日的ARM Linux 邮件列表中进行了推动,因此从linux3.x开始,linux内核引入了设备树。内核中关于设备树的文档位于kernel/Documentation/devicetree/目录。

1)当注册硬件设备发生变化或改动时,需要重新编译内核。

2)内核版本升级时,需要重新移植自定义的已注册设备代码。

这导致了设备树注册设备的方式,最终替代了编写代码注册设备的方式

inux-3.x及之后

在/proc/device-tree/下能够看到设备树的完整形态

3种编译的镜像

在init_boot镜像中,主要包含了init进程的第一阶段实现

vendor_boot镜像中,主要包含了厂商提供的内核驱动文件、fstab文件、内核加载地址、ramdisk加载地址、randisk size、dtb加载地址、dtb size等信息

merge DTB需要使用到工具,在MTK的lk和高通的ABL里面都有源码实现。下面提取了这些实现,编写一个一个dtbmerge工具。

使用 dtc 编译 .dts 时,您必须添加选项 -@ 以在生成的 .dtbo 中添加 __symbols__ 节点。__symbols__ 节点包含所有带标签节点的列表,DTO 库可使用这个列表作为参考

设备树是支持在dts文件中,include .h文件,也支持部分C语言的语法。

#include "son.dtsi"

#include "cfg.h"

#ifdef ENABLE //在cfg.h中定义

        adi,internal-ref-microvolt = <0x3e8000>;

#else

        adi,internal-ref-microvolt = <2500000>;

#endif

设备树的overlay

overlay机制,只能支持增加、修改节点,不支持删除node

/delete-node/和/delete-prop/指令仅由dtc编译器在单个编译中使用。

设备树blob格式中没有任何内容来表示删除属性或节点的概念

设备树的常用配置参数

属性操作的接口函数

操作提取设备树函数

static inline bool device_property_read_bool(struct device *dev, const char *propname)

static inline int device_property_read_u8(struct device *dev, const char *propname, u8 *val)

。。。

static inline int device_property_read_u64(struct device *dev, const char *propname, u64 *val)

int device_property_read_u8_array(struct device *dev, const char *propname, u8 *val, size_t nval)

获取数组长度:static inline int device_property_count_u8(struct device *dev, const char *propname)

字符串:int device_property_read_string(struct device *dev, const char *propname, const char **val)

int device_property_read_string_array(struct device *dev, const char *propname, const char **val, size_t nval)

总线(bus)

Linux设备驱动模型,由总线(bus)、设备(device)、驱动(driver)三部分组成;总线是处理器与设备之间的通道,在设备模型中,所有的设备都通过总线相连;总线作为Linux设备驱动模型的核心架构,系统中的设备和驱动都挂接在相应的总线上,来完成各自的工作

总线、设备、驱动示意图

总线注册,是将一种总线类型注册到内核能够管理的总线集合中

内核启动时,kernel将设备树根目录下的设备树进行解析,将dtb blom转换为device node。将符合条件的device node注册为platform device

全局链表,存储了完整的device node

start kernel

  1. 翻译dtb

什么节点会被注册成platform device

除上述设备转换外,根据一级子节点的情况,代码驱动里面会对部分二级节点进行转换,此时不一定是转换成platform device。例如SPI节点下的二级设备会被转换成spi device;I2C节点下的二级节点设备会被转换成i2C device

device node注册为device

ads1015并不是被注册成了platform device,而是被注册成I2C device。这也证明了设备树的二级子目录被注册成什么device,一般由父目录的驱动来决定

qemu虚拟环境

设备树实战

linux最小化的分区一般包括uboot、dtb、kernel、rootfs四个部分,qemu作为一个虚拟环境,可以单独访问内核和文件系统,不需要使用uboot。

root节点下增加一个device node。按照内核设计原则,当前device node会被注册成platform device

主设备树中arch/arm/boot/dts/  这个路径下的disi文件好多   可能有各家厂商的   比如高通的

新编写一个platform driver,与设备树中的device进行匹。读取device node下的配置参数

驱动源码:

// node count

printk("\n\n");

dev_warn(dev, "child node count: %d\n", device_get_child_node_count(dev));

驱动配置

make CROSS_COMPILE=arm-none-linux-gnueabihf- ARCH=arm menuconfig

编译内核

make CROSS_COMPILE=arm-none-linux-gnueabihf- ARCH=arm -j8

代码来源

硬件电路设计选择一款实现特定功能的芯片,一般比较成熟的量产芯片:

  • linux内核里面已经有了对芯片的支持,使能内核配置支持即可。

  • 芯片厂家会提供驱动文件,有保密要求的需要向供货厂家索取,如果是非保密的一般可以在官网下载。

  • 网络上自行搜索下载芯片驱动。

  • 定制化芯片一般是参考内核中已有的类似驱动,自行完成开发工作

TI的ads1015为例

可以将当前驱动(ti-ads1015.c)配置项目设置成y编译进内核进行测试(或者直接修改defconfig配置文件)

make CROSS_COMPILE=arm-none-linux-gnueabihf- ARCH=arm menuconfig

在设备树中添加设备节点。一般常用的芯片内核中都有使用说明。在设备树中,参考内核说明,在I2C下添加一个device node。修改:arch/arm/boot/dts/vexpress-v2m.dtsi

ads1015并不是被注册成了platform device,而是被注册成I2C device。这也证明了设备树的二级子目录被注册成什么device,一般由父目录的驱动来决定

[root@farmer /sys/bus/i2c/drivers/ads1015]$ ls

0-0048 bind uevent unbind

/kernel_platform/msm-kernel/drivers/of/fdt.c

  • populate_properties()函数为节点的各个属性分配空间,赋值;在设备树中,属性的描述是key = value,struct property结构体中name和value分别对应设备树中的key和value

设备树dts文件中子节点都将转化为一个对应的device_node结构,但并不是所有device_node都会转换为platform_device结构

  kernel_platform/msm_kernel/init/main.c

  start_kernel

    setup_arch

    rest_init      kernel_init        kernel_init_freeable          do_basic_setup            do_initcalls

              ...

              do_initcall_level

                ...

                of_platformm_default_populate

属性(property)value定义

  • 字符串string/字符串数组string-list,compatible = "xxxxxxxx,xxxxxxxx"

  • 32bit unsigned integers,整形用<>表示,reg = <0x...... 0x.......>

  • binary data,十六进制用[]表示,local-mac-address = [xx xx xx xx]

  • 空,empty_property

i2c总线

650/kernel_platform/msm-kernel/drivers/i2c/busses/i2c-msm-geni.c

参考链接

用buildroot编译整个系统,用qemu仿真vexpressa9 - 简书

使用Buildroot + QEMU构建和运行Linux_qemu buildroot-CSDN博客

AD7949 数据手册和产品信息 | 亚德诺(ADI)半导体

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值