一、compatible匹配

1、dts 中写法

compatible = “aaa,bbb”

当一个驱动支持多个设备的时候,在每个设备的dts中,都会配置各自的compatible,当与driver中的compatible匹配后,会取各自的data。在 __of_match_node中有match++。

2、example

static const struct of_device_id plat_drv_match[] = {{ .compatible = "aaa,bbb", .data = &bbb_hw_data},{ .compatible = "aaa,ccc", .data = &ccc_hw_data},{}
};data = of_device_get_match_data(dev);

在bbb.dts中,匹配到第1条,data就用第1条
在ccc.dts中,匹配到第2条,data就用第2条

3、源码

以下函数位于 //kernel4.14/drivers/of/device.c

const void *of_device_get_match_data(const struct device *dev)
{const struct of_device_id *match;match = of_match_device(dev->driver->of_match_table, dev);if (!match)return NULL;return match->data;
}
EXPORT_SYMBOL(of_device_get_match_data);

判断dts中的compatible属性是否包含driver中指定的compatible,
实际上返回的是dev->driver->of_match_table->data。
data是void *类型,自己如果想取到data里的值,就可以自己定义类型,里面可以放一些自己需要的参数。

二、根据dts中的reg-names得到dts中配置的reg

1、dts 中写法

reg的参数:第一个是地址,第二个是映射长度。
如果是32位,reg = <0x80000000 0x1000>;
如果是64位,reg = <0 0x80000000 0 0x1000>;
reg-names = “bbb”;

2、example

resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bbb");
addr = resource->start; //为reg中的起始地址
size = resource_size(resource); //为reg中的内存大小
virt_addr = devm_ioremap_nocache(&pdev->dev, addr, size); //物理地址和虚拟地址的映射

3、源码

以下函数位于 //kernel4.14/drivers/base/platform.c

/*** platform_get_resource_byname - get a resource for a device by name* @dev: platform device* @type: resource type* @name: resource name*/
struct resource *platform_get_resource_byname(struct platform_device *dev,unsigned int type,const char *name)
{u32 i;for (i = 0; i < dev->num_resources; i++) {struct resource *r = &dev->resource[i];if (unlikely(!r->name))continue;if (type == resource_type(r) && !strcmp(r->name, name))return r;}return NULL;
}
EXPORT_SYMBOL_GPL(platform_get_resource_byname);

因为linux 会通过dts进行设备(platform_device)的注册和初始化信息。其中就会有将dts中的reg,reg-names匹配到dev->resource等参数,struct resource结构体里就定义了设备的资源信息:所占内存的起始地址和结束地址,flag 是IORESOURCE_MEM还是IORESOURCE_IRQ等。所以这里通过这个函数platform_get_resource_byname就可以得到所占内存空间的物理地址resource->start。

以下函数位于 //kernel4.14/lib/devres.c

/*** devm_ioremap_nocache - Managed ioremap_nocache()* @dev: Generic device to remap IO address for* @offset: Resource address to map* @size: Size of map** Managed ioremap_nocache().  Map is automatically unmapped on driver* detach.*/
void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,resource_size_t size)
{void __iomem **ptr, *addr;ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);if (!ptr)return NULL;addr = ioremap_nocache(offset, size);if (addr) {*ptr = addr;devres_add(dev, ptr);} elsedevres_free(ptr);return addr;
}
EXPORT_SYMBOL(devm_ioremap_nocache);

将物理地址映射到虚拟地址,不过cache,DMA可以和cpu直接交互。

三、通过dts中irq的name得到irq_num中断号

1、dts 中写法

interrupts = <GIC_SPI 12 IRQ_TYPE>;
interrupt-names = “irq_name”;
解释:
GIC_SPI:共享中断;GIC_PPI:每个处理器拥有独立中断
12 硬件中断号
IRQ_TYPE:电平触发还是上下沿触发(IRQ_TYPE_LEVEL_HIGH…)

2、example

irq_num = platform_get_irq_byname(dev, "irq_name");

得到的irq_num 就是中断号

3、源码

以下函数位于 //kernel4.14/drivers/base/platform.c

/*** platform_get_irq_byname - get an IRQ for a device by name* @dev: platform device* @name: IRQ name*/
int platform_get_irq_byname(struct platform_device *dev, const char *name)
{struct resource *r;if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {int ret; ret = of_irq_get_byname(dev->dev.of_node, name);if (ret > 0 || ret == -EPROBE_DEFER)return ret; }r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);return r ? r->start : -ENXIO;
}
EXPORT_SYMBOL_GPL(platform_get_irq_byname);

of_irq_get_byname:在interrupt-names这个属性中查找name这个名字。如果成功会返回linux irq number。

四、通过syscon(system control)中name得到配置的regmap

syscon这个属性自我理解是:对这个外设系统的一些控制。
regmap这个机制只要目的是减少慢速I/O驱动上的重复逻辑,提供一种通用的接口来操作底层硬件上的寄存器。regmap 除了能做到统一的I/O接口,还可以在驱动和硬件IC之间做一层缓存,从而减少底层I/O的操作次数。

1、dts 中写法

syscons = <&aaa_regs0x8000000000x1>
syscon-names = "thatsok";

解释:&代表引用节点,说明aaa_regs在其他地方有定义

2、example

syscon_regmap_lookup_by_name(dev.of_node, "thatsok");
syscon_get_args_by_name(dev.of_node, "thatsok", 2, reg_info);

3、源码

以下函数位于 //kernel4.14/drivers/mfd/syscon.c

struct regmap *syscon_regmap_lookup_by_name(struct device_node *np,const char *name)
{struct device_node *syscon_np;struct of_phandle_args args;struct regmap *regmap;int index = 0;int rc; if (name)index = of_property_match_string(np, "syscon-names", name);if (index < 0)return ERR_PTR(-EINVAL);rc = of_parse_phandle_with_args(np, "syscons", "#syscon-cells", index,&args);if (rc)return ERR_PTR(rc);syscon_np = args.np;if (!syscon_np)return ERR_PTR(-ENODEV);regmap = syscon_node_to_regmap(syscon_np);of_node_put(syscon_np);return regmap;
}
EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_name);

在syscon-names这个属性中找到name这个名字,找到regmap,也就是dts中的第一个参数aaa_regs对应的regmap

int syscon_get_args_by_name(struct device_node *np,const char *name,int arg_count,unsigned int *out_args)
{struct of_phandle_args args;int index = 0;int rc;if (name)index = of_property_match_string(np, "syscon-names", name);if (index < 0)return -EINVAL;rc = of_parse_phandle_with_args(np, "syscons", "#syscon-cells", index,&args);if (rc)return rc;if (arg_count > args.args_count)arg_count = args.args_count;for (index = 0; index < arg_count; index++)out_args[index] = args.args[index];of_node_put(args.np);return arg_count;
}
EXPORT_SYMBOL_GPL(syscon_get_args_by_name);

在syscon-names这个属性中找到name这个名字,找到arg_count个参数,分别放在out_args中,即dts中的reg_info[0], reg_info[1]…

五、of相关函数

主要介绍常用函数 位于kernel4.14/include/linux/of.h 会调用到kernel4.14/drivers/of/property.c中

1、解析字节

dts中写法:
bbb-property = <1>;

example :

u32 num;
of_property_read_u32(np, "bbb-property", &num);

找到bbb-property这个属性,取出里面的值放到num中去

static inline int of_property_read_u32(const struct device_node *np,const char *propname,u32 *out_value)

2、解析数组

dts中写法 :bbb-property = <1, 2, 3, 4>
也可以写 bbb-property = <1, 2>, < 3, 4>
of_property_read_u32_array

example

u32 *buf_info;
of_property_read_u32_array(np, "bbb-property", buf_info, 4);

在dts中查找"bbb-property"这个属性,读出4个数据,依次放在buf[0]…buf[3]中.

int of_property_read_u32_array(const struct device_node *np,const char *propname,u32 *out_values, size_t sz)

3、解析字符串list

dts中写法:

bbb-names = "aaa", "bbb", "ccc", "ddd"

example

int count;
char *name;
count = of_property_count_strings(dev.of_node, "bbb-names");
for (i = 0; i < count; i++)of_property_read_string_index(np, "bbb-names", i, &name);

通过在dts中找到bbb-names这个属性,调用of_property_count_strings,得到有count个字符串
通过i作为index索引,取出每个字符串,这里要注意,每次取出来的都是放在首地址处的,用数组来表示的话,每一个索引,都是放在name[0]处。

static inline int of_property_read_string_index(const struct device_node *np,const char *propname,int index, const char **output)

linux kernel --- dts的相关操作函数相关推荐

  1. linux skb 结构和相关操作函数分析

    sk_buff是Linux网络中最核心的结构体,它用来管理和控制接收或发送数据包的信息.各层协议都依赖于sk_buff而存在.内核中sk_buff结构体在各层协议之间传输不是用拷贝sk_buff结构体 ...

  2. skb结构和相关操作函数

    skb是linux kernel中收发数据包用到的控制结构体,有些字段指向分配的内存用于存放数据包, 向协议栈传送时,通过移动指针来获取到以太头,网络头,传输头等信息. skb结构和相关操作函数 a. ...

  3. linux修改定时后如何保存文件夹,linux定时任务的一些相关操作汇总

    本人搜罗各大网站并测试了相关定时任务的操作方便大家进行查阅和操作. 1.cron介绍 我们经常使用的是 crontab 命令是cron table的简写,它是cron的配置文件,也可以叫它作业列表,我 ...

  4. linux下git的相关操作指令

    linux下git的相关操作指令 git版本管理工具 1.克隆仓库git clone "url" 2.上传2.1标记:告诉git工具需要管理那些文件了git add [filena ...

  5. uCOS-II消息邮箱的相关操作函数

    定位到uCOS-II/Source/os_mbox.c,该文件是消息邮箱管理的相关操作函数.   任务与任务之间需要数据传递,那么为了适应传递的数据的不同类型,可以建立一个缓冲区(void*类型可以接 ...

  6. SystemV 信号量(一) —— SystemV信号量的相关操作函数(semget / semop /semctl)

    SystemV IPC 方案的相关内容都是通过 "房间密码"来创建房间,获取到房间的ID,后面其他进程也可以根据这个房间密码来拿到同一个房间的ID.这是理解下面这些操作函数的关键. ...

  7. Linux下environ环境变量操作函数

    #include <stdio.h>int main(int argc,char *argv[],char **envptr) {int i=0;for(i=0; envptr[i]!=N ...

  8. linux kernel dts分析

    一.DTS的来源 在linux内核源码的3.1版本之前,linux内核都是通过大量的platfrom-device文件来描述板级配置信息,这使得内核人员维护很困难,因此设备树(Device Tree) ...

  9. 封装进程内存相关操作函数

    //ProcessMemory.h:进程内存操作封装 #pragma once #include <windows.h> #include <TLHELP32.H>class ...

最新文章

  1. hbase源码系列(一)Balancer 负载均衡
  2. Zynq linux的I2C驱动学习笔记
  3. Laravel event 事件的简单使用
  4. python的for循环累加_在python中将6 for循环累计和矢量化
  5. 作为一名SAP从业人员,需要专门学习数学么
  6. React-router总结
  7. 浅谈ButterKnife对Android性能的影响
  8. 红橙Darren视频笔记 Activity启动流程(API28)
  9. Particle Filter Tutorial 粒子滤波:从推导到应用(三)
  10. XCode 编辑器的shortcuts
  11. 大学生如何自学PR剪辑以及PS教程?
  12. 通过网络数据采集系统快速获得优质销售线索
  13. java面试问项目中遇到的问题,涨知识
  14. 找到弹窗广告所在的程序文件位置
  15. FusionCharts学习总结
  16. Fedora分区扩容以及如何修复引导
  17. 区块链大戏上演!陈伟星VS朱啸虎公开互怼数个回合 | 区块链日报
  18. 计算机领域十大世界难题,世界四大科学难题是什么,什么是四大科学难题
  19. 小程序获取用户头像大图 小程序获取用户头像模糊的问题 小程序自定义转发头像模糊 小程序自定义转发分享大图...
  20. python 爬取整部漫画(简单的图片爬取)

热门文章

  1. 面向未来的跨界开发技术(下)
  2. react-native TextInput组件在模拟器Simulator上鼠标聚焦后键盘不弹出
  3. 视觉媒体通信作业记录(一) 简易yuv420视频播放器
  4. 知乎周源微信_每周源代码18-深度缩放(Seadragon)Silverlight 2 MultiScaleImage鼠标滚轮缩放和平移版...
  5. 炫影创意街头玩具TIY玩法多样,EW刺激过瘾!EW
  6. android+锁屏代码+下载,安卓客户端开发的锁屏源码demo下载,可直接应用到APP中
  7. S5PV210基本介绍
  8. 设计师必备的效果图制作工具,一秒get
  9. python必须用电脑吗_Python 初学者请注意!别这样直接运行 Python 命令,否则电脑等于“裸奔”...
  10. 一起作业网刘畅:千万用户背后的艰辛创业路