linux驱动入门-设备树

这阵子我会先更新一些linux驱动比较通用的基础知识–设备树

设备树

以树形结构描述板级设备节点

设备树编译命令
  1. 设备树源文件扩展名: .dts
  2. 设备树文件扩展名: .dtb
  3. 将设备树源文件编译成设备树文件: make dtbs
  4. 将指定xxx.dts编译为设备树文件: make xxx.dtb
  5. 设备树支持头文件引用,头文件扩展名为.dtsi,同样支持.h .dts文件的引用
设备树中的设备节点
  1. 根节点:/ 每个设备树文件只能有一个根节点,dts和dtsi中的根节点会合并为同一个根节点
  2. 节点命名格式label:node-name@unit-address
    label(可有可无):节点标签,可用&label引用节点
    node-name:节点名称
    unit-address:设备地址或者寄存器首地址
  3. 设备树中数据格式:
    数据类型表达式
    字符串“string”
    字符串列表“string1”,“string2”
    32位无符号整数<0>
    数组<0 0x2412 1>

设备树标准属性

compatible(兼容性属性)

compatible属性值格式compatible = "manufacture1,model1","manufacture2,model2"...
manufacture: 厂商名称
model: 模块对应的驱动名称

注1:驱动程序中的.of_match_table表储存驱动匹配的compatible值,驱动中的compatible属性与设备节点的compatible属性匹配成功后执行probe函数~

注2:根节点下的compatible属性用于内核判断是否支持当前设备~

model (设备属性)

model属性值格式model="alpha_led"

字符串用于描述设备信息,比如名字、型号~

status(状态属性)

status属性值格式status="string"
string表示设备状态

string值描述
okay设备可操作
disabled非使能状态,不可操作
fail设备错误,不可操作
fail-sss同fail,sss为错误信息
#address-cells 和 #size-cells

可用于任何拥有子节点的设备树节点中,用于描述子节点地址信息
属性值格式#address-cells=<1> #size-cells=<0>

  1. #address-cells:描述子节点中reg属性中地址信息占用的字长
  2. #size-cells:描述子节点reg属性中长度信息占用的字长
reg (设备地址空间资源属性)

reg属性值格式reg=<address length>
address: 空间首地址
length: 空间长度

ranges (地址映射表,可以为空)

ranges属性值格式ranges=<child-bus-address parent-bus-address length>
child-bus-address:子总线起始地址
parent-bus-address:父总线起始地址
length:长度

查找节点属性的of操作函数

包含头文件:<linux/of.h>

查找节点函数
  • 使用结构体struct device_node 表示设备节点
  1. struct device_node *of_find_node_by_name(struct device_node *from, const char *name)
    from:起始节点,为NULL时从根节点开始查找
    name:需要查找的节点名称
    返回值:找到的节点指针,如果为NULL表示查找失败

  2. struct device_node *of_find_node_by_type(struct device_node *from, const char *type)
    from:起始节点,为NULL时从根节点开始查找
    type:需要查找的节点类型
    返回值:找到的节点指针,如果为NULL表示查找失败

  3. struct device_node *of_find_compatible_node(struct device_node *from, const char *type, const char *compatible)
    from:起始节点,为NULL时从根节点开始查找
    type:需要查找的节点类型
    compatible:节点兼容性属性
    返回值:找到的节点指针,如果为NULL表示查找失败

  4. struct device_node *of_find_node_by_path(consy char *path)
    path:带有全路径的节点名
    返回值:找到的节点指针,如果为NULL表示查找失败
查找父节点和子节点函数
  1. struct device_node *of_get_parent(const struct device_node *node)
    node:子节点指针
    返回值:找到的父节点指针,如果为NULL表示查找失败

  2. struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev)
    node:父节点指针
    prev:前一个子节点,也就是设置从哪个子节点开始迭代查找,如果设置为NULL,表示从第一个子节点开始
提取节点属性值函数

使用结构体struct property表示节点属性
property原型

struct property
{
    char *name;   //属性名字
    int length;   //属性长度
    void *value;  //属性值
    struct property *next;  //下一个属性指针
    unsigned long _flags;
    unsigned int unique_id;
    struct bin_attrbiute attr;
}
  1. 查找指定属性
    struct property *of_find_property(const struct device_node *np, const char *name, int *lenp)
    np:设备节点
    name:需要查找的属性名字
    lenp:属性值的字节数
    返回值:查找到的属性,NULL表示失败

  2. 获取属性中元素数量
    int of_property_cunt_elems_of_size(const struct device_node *np, const char *propname, int elemsize)
    np:设备节点
    propname:属性名字
    elemsize:元素长度
    返回值:元素个数

  3. 读u32数组元素值
    int of_property_read_u32_index(const struct device_node *np, const char *propname, u32 index, u32 *outv_alue)
    np:设备节点
    propname:属性名称
    index:要读取的u32类型数据下标
    out_value:读取到的值存入此地址
    返回值:0-成功 负值-失败

  4. 读属性中的数组数据

    • int of_property_read_u8_arry (struct device_node *np,const char *propname,u8 *out_values,size_t sz)
    • int of_property_read_u16_arry (struct device_node *np,const char *propname,u16 *out_values,size_t sz)
    • int of_property_read_u32_arry (struct device_node *np,const char *propname,u32 *out_values,size_t sz)
    • int of_property_read_u64_arry (struct device_node *np,const char *propname,u64 *out_values,size_t sz)
      np:设备节点
      propname:属性名
      out_values:读取到的数组值存储位置的首地址
      sz:要读取的数组元素的数量

  5. 读取数组中的整型值(属性只有一个整型值)

    • int of_property_read_u8(struct device_node *nd, const char * propname,u8 *outvalue)
    • int of_property_read_u16(struct device_node *nd, const char * propname,u16 *outvalue)
    • int of_property_read_u32(struct device_node *nd, const char * propname,u32 *outvalue)
    • int of_property_read_u64(struct device_node *nd, const char * propname,u64 *outvalue)
      nd:设备节点
      propname:属性名称
      outvalue: 值存储到此地址
      返回值:0-成功 负值-失败
  6. 读取属性中的字符串
    int of_property_read_string(struct device_node *np, const char *propname, char **out_string);
    nd:设备节点
    propname:属性名称
    outvalue: 字符串储存地址
    返回值:0-成功 负值-失败

  7. 读取#address-cells值
    int of_n_addr_cells(struct device_node *np)
    np:设备节点
    返回值:addr-cell的值

  8. 读取#size-cells值
    int of_n_size_cells(struct device_node *np)
    np:设备节点
    返回值:size-cell的值

其他常用of函数
  1. 检查设备节点兼容性
    int of_device_is_compatible(struct device_node *np, const char *compat)
    np:设备节点
    compat:要检查的兼容性字符串
    返回值:0-compatible属性中不包含此字符串
    1-compatible属性中包含此字符串

  2. 获取地址相关属性
    const __be32 *of_get_address(struct device_node *np,int index, u64 *size, unsigned int *flags)
    np:设备节点
    index: 要读取的地址标号
    size:地址长度
    flags:参数 IORESOURCE_IOIORESOURCE_MEM 等
    返回值:读到的地址数据首地址,为NULL表示读取失败

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值