转自:https://blog.csdn.net/jklinux/article/details/78575281

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jklinux/article/details/78575281
在设备树的dts文件里,带有compatible属性的节点就是表示一个platform_device.

在设备树里增加一个设备,则在内核里的dts文件里描述设备节点即可. 在H5方案里,则在arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts文件里。
如在dts文件里加入以下内容:

mynodes@77885566 { /* 则创建出来的platform_device的名为mynodes@77885566 */
compatible = "mynodes"; /* 设备节点的属性 */
autorepeat = <1>;

btn1 { /* 设备子节点 */
label = "btn1"; /* 设备子节点的属性 */
code = <0x11>;
};
btn2 {
label = "btn2";
code = <0x22>;
};
};

增加内容后,则重编设备树:

make dtbs ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

再把编译出来的sun50i-h5-nanopi-neo2.dtb替换板上所用的dtb文件,重启系统后,可以查看到内容:

^_^ / # ls /sys/bus/platform/devices/mynodes@77885566/
driver_override of_node/ subsystem/
modalias power/ uevent

^_^ / # ls /sys/bus/platform/devices/mynodes@77885566/of_node/
autorepeat btn1/ btn2/ compatible name

在dst设备树文件描述设备后就需要与platform_driver进行匹配和驱动了.
在设备驱动里获取设备树中的设备资源需要一套接口函数来实现:

#include <linux/property.h>

//用于获取设备节点的属性成员值函数, propname用于指定要获取值的属性名
bool device_property_present(struct device *dev, const char *propname);
int device_property_read_u8_array(struct device *dev, const char *propname,
u8 *val, size_t nval);
int device_property_read_u16_array(struct device *dev, const char *propname,
u16 *val, size_t nval);
int device_property_read_u32_array(struct device *dev, const char *propname,
u32 *val, size_t nval);
int device_property_read_u64_array(struct device *dev, const char *propname,
u64 *val, size_t nval);
int device_property_read_string_array(struct device *dev, const char *propname,
const char **val, size_t nval);
int device_property_read_string(struct device *dev, const char *propname,
const char **val);
int device_property_match_string(struct device *dev,
const char *propname, const char *string);

//用于获取设备子节点的属性值函数. fwnode是表示子节点的对象地址
bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname);
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
const char *propname, u8 *val,
size_t nval);
int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
const char *propname, u16 *val,
size_t nval);
int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
const char *propname, u32 *val,
size_t nval);
int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
const char *propname, u64 *val,
size_t nval);
int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
const char *propname, const char **val,
size_t nval);
int fwnode_property_read_string(struct fwnode_handle *fwnode,
const char *propname, const char **val);
int fwnode_property_match_string(struct fwnode_handle *fwnode,
const char *propname, const char *string);

struct fwnode_handle *device_get_next_child_node(struct device *dev,
struct fwnode_handle *child);

----------
unsigned int device_get_child_node_count(struct device *dev); //获取设备的子节点个数

//产生一个for循环用于检查所有的子节点
#define device_for_each_child_node(dev, child) \
for (child = device_get_next_child_node(dev, NULL); child; \
child = device_get_next_child_node(dev, child))

//注意函数以"device"开头表示读取设备的属性, 以"fwnode"开头表示读取子节点的属性.

用于获取mynodes设备资源的驱动源码:

/* mydrv.c */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>

int myprobe(struct platform_device *pdev)
{
struct fwnode_handle *fwhandle;
const char *str;
u32 val;

//获取设备子节点的个数
printk("child node count : %d\n", device_get_child_node_count(&pdev->dev));
//获取设备属性autorepeat的值
printk("%d\n", device_property_read_bool(&pdev->dev, "autorepeat"));

//遍历设备的每个子节点
device_for_each_child_node(&pdev->dev, fwhandle) {
//获取设备子节点的label属性值
fwnode_property_read_string(fwhandle, "label", &str);
printk("label = %s\n", str);
//获取设备子节点的code属性值
fwnode_property_read_u32(fwhandle, "code", &val);
printk("code = %x\n", val);
};

return 0;
}

int myremove(struct platform_device *pdev)
{
printk("in myremove ...\n");
return 0;
}

struct of_device_id ids[] = {
{.compatible = "mynodes"},
{},
};

struct platform_driver mydrv = {
.probe = myprobe,
.remove = myremove,

.driver = {
.owner = THIS_MODULE,
.name = "mydrv" ,

.of_match_table = ids,
},
};

module_platform_driver(mydrv);
MODULE_LICENSE("GPL");
1

编译驱动模块加载后的输出结果:

[ 419.424065] child node count : 2
[ 419.427429] 1
[ 419.429054] label = btn1
[ 419.431690] code = 11
[ 419.434000] label = btn2
[ 419.436623] code = 22
1

————————————————
版权声明:本文为CSDN博主「jklinux」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jklinux/article/details/78575281

08 在设备树里描述platform_device【转】的更多相关文章

  1. usb设备驱动描述,王明学learn

    usb设备驱动 本章主要内容包含以下:USB总线介绍,USB协议分析,USB系统架构 一.USB总线介绍 1.1USB发展史 USB(Universal Serial Bus)通用串行总线,是一种外部 ...

  2. USB系列之二:读取USB设备的描述符

    在前面的文章中,我们已经给出了USB协议的链接地址,从这篇文章起,我们会涉及到许多USB 1.1的内容,我们的指导思想是先从熟悉USB 1.1协议入手,先使用现成的HCD和USBD,直接面对客户端驱动 ...

  3. USB HID设备报告描述符详解(转)

    转自:http://group.ednchina.com/93/198.aspx. 参考:USB HID usage table 概述:   报告在这里意思是数据传输(data transfer),而 ...

  4. 最新内核3.4)Linux 设备树加载I2C client adapter 的流程(内核3.4 高通)【转】

    转自:https://blog.csdn.net/lsn946803746/article/details/52515225 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转 ...

  5. 设备树DTS 学习:2-设备树语法

    背景 通过上一讲了解完设备树DTS有关概念,我们这一讲就来基于设备树例程,学习设备树的语法规则. 参考:设备树详解dts.设备树语法详解.设备树使用总结 设备树框架 1个dts文件 + n个dtsi文 ...

  6. Linux设备树语法详解

    概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写.引入了设备树之后,驱动代 ...

  7. Linux中总线设备驱动模型及平台设备驱动实例

    本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...

  8. i2c总线,设备,驱动之间的关系

    ------ 总线上先添加好所有具体驱动,i2c.c遍历i2c_boardinfo链表,依次建立i2c_client, 并对每一个i2c_client与所有这个线上的驱动匹配,匹配上,就调用这个驱动的 ...

  9. Linux 驱动学习笔记05--字符驱动实例,实现一个共享内存设备的驱动

    断断续续学驱动,好不容易有空,做了段字符驱动的例子.主要还是跟书上学习在此记录下来,以后说不定能回过头来温故知新. 首先上驱动源码 gmem.c: /************************* ...

随机推荐

  1. Java学习笔记(7)---流(Stream),文件(File)

    1.Stream流 a.定义: Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类型.对象.本地化字符集 ...

  2. July 20th, 2019. Week 29th, Saturday

    If we just open the door a crack, the light comes pouring in. 只要把门开个小口,光就会倾泻而入. Don't be so disheart ...

  3. golang中的viper示例

    这是第二次实操viper了, 年纪大了就多练练,才能记住. http://go.coder55.com/article/6589 https://github.com/spf13/viper pack ...

  4. vue预览本地图片

    <template> <div> <a href="javascript:void(0);" @change="addImage" ...

  5. C++(OI竞赛入门)学习指南一

    #include<cstdio>   头文件#include包含  <头文件名称> #include<iostream>     需要头文件里面的功能    cst ...

  6. 微信小程序开发——websocket测试

    服务端 在windows下执行 node  server.js 也可参照我的前一篇部署https var httpServ = require('http') var WebSocketServer ...

  7. 机器学习模型| 监督学习| KNN | 决策树

    分类模型 K近邻 逻辑斯谛回归 决策树 K近邻(KNN) 最简单最初级的分类器,就是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类K近邻(k ...

  8. Repair Microsoft.VisualStudio.MinShell.Msi.Resources 2203 error And visual studio 2019 key

    1. Go to the properties of "My computer" 2. Go to advanced settings of the system 3. Go to ...

  9. react组件通信方式汇总

    父组件更新组件状态,通过props传递给子组件,子组件得到后进行更新.Timer 是倒计时子组件,集成在了OrderPay父组件里,父组件向子组件传订单数据参数order对象.如下代码: <Ti ...

  10. IntelliJ IDEA代码常用的快捷键(自查)

    IntelliJ IDEA代码常用的快捷键有: Alt+回车 导入包,自动修正 Ctrl+N   查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L  格式化代码 Ctrl+Alt+O ...