一、简介

之前没用设备树的时候,是分别编写并注册platform_device和platform_driver来表示设备和驱动,如果使用设备树,设备的描述就放在设备树中,因此只需要实现platform_driver就可以了,具体如下:

1.1、创建节点

因为platform总线需要通过设备节点的compatible属性值来匹配驱动,所以创建节点的重点是设置好compatible属性值。比如:

1.2、兼容属性

在使用设备树的时候,platform驱动会通过of_match_table来保存兼容属性值,也就表明此驱动兼容哪些设备,可以按照如下设置:

static const struct of_device_id led_of_match[] = {{ .compatible = "atkmini-gpioled"},{}
};MODULE_DEVICE_TABLE(of, led_of_match);/*
*platform平台驱动结构体
*/
static struct platform_driver led_platform_driver = {.driver = {.name = "imx6ul-led",.of_match_table = led_of_match,},.probe = leddev_probe,.remove = leddev_remove,
};

of_device_id是驱动的兼容表,一个驱动可以跟多个设备匹配,这里仅匹配了一个。compatible值跟设备树中的值一致,匹配成功后,对应的probe函数就会执行。

二、驱动编写

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/platform_device.h>#define LEDDEV_CNT     1
#define LEDDEV_NAME    "dtsplatled"#define    LED_ON      1
#define LED_OFF     0//设备结构体
struct leddev_dev{dev_t devid;struct cdev cdev;struct class *class;struct device *device;int major;int minor;struct device_node *nd;        //设备节点int led_gpio;             //led所使用的GPIO编号
};struct leddev_dev leddev;  static void led_switch(uint8_t sta)
{if (sta == LED_ON){gpio_set_value(leddev.led_gpio, 0);} else if (sta == LED_OFF) {gpio_set_value(leddev.led_gpio, 1);}
}static int leddev_open(struct inode *inode, struct file *filp)
{filp->private_data = &leddev;printk("leddev open!\n");return 0;
}static ssize_t leddev_read(struct file *filp, __user char *buf, size_t count, loff_t *ppos)
{   printk("leddev read\n");return 0;
}static ssize_t leddev_write(struct file *filp, const char __user *buf, size_t count, loff_t *oppos)
{int ret;uint8_t data_buf[1];ret = copy_from_user(data_buf, buf, count);if (ret < 0){printk("write data fail\n");return -EFAULT;}led_switch(data_buf[0]);return 0;
}static int leddev_release(struct inode *inode, struct file *filp)
{printk("led release\n");return 0;
}static const struct file_operations leddev_fops = {.owner = THIS_MODULE,.open  = leddev_open,.read  = leddev_read,.write = leddev_write,.release = leddev_release,
};/*
*platform驱动的probe函数
*驱动与设备匹配成功以后此函数就会执行
*/static int leddev_probe(struct platform_device *dev)
{int ret = 0;printk("led driver and device has match\r\n");//通过节点名字查找节点leddev.nd = of_find_node_by_name(NULL, "gpioled");if (leddev.nd == NULL){printk("find %s fail\r\n", "gpioled");return -EINVAL;}//获取GPIO编号leddev.led_gpio = of_get_named_gpio(leddev.nd, "gpio", 0);if (leddev.led_gpio < 0){printk("get gpio fail\r\n");return -EINVAL;}else{printk("led_gpio value is %d", leddev.led_gpio);}//设置led状态ret = gpio_direction_output(leddev.led_gpio, 0);if (ret < 0){printk("set led status fail\r\n");return -EINVAL;}//分配设备号if (leddev.major) {leddev.devid = MKDEV(leddev.major, 0);register_chrdev_region(leddev.devid, LEDDEV_CNT, LEDDEV_NAME);} else {alloc_chrdev_region(&leddev.devid, 0, LEDDEV_CNT, LEDDEV_NAME);leddev.major = MAJOR(leddev.devid);leddev.minor = MINOR(leddev.devid);}printk("leddev major=%d, minor= %d\r\n", leddev.major, leddev.minor);//初始化cdevleddev.cdev.owner = THIS_MODULE;cdev_init(&leddev.cdev, &leddev_fops);//添加cdevcdev_add(&leddev.cdev, leddev.devid, LEDDEV_CNT);//创建类leddev.class = class_create(THIS_MODULE, LEDDEV_NAME);//创建设备leddev.device = device_create(leddev.class, NULL, leddev.devid, NULL, LEDDEV_NAME);return 0;
}static int leddev_remove(struct platform_device *dev)
{led_switch(LED_OFF);//删除设备的类device_destroy(leddev.class, leddev.devid);//删除类class_destroy(leddev.class);//删除设备cdev_del(&leddev.cdev);//注销设备号unregister_chrdev_region(leddev.devid, LEDDEV_CNT);
}static const struct of_device_id led_of_match[] = {{ .compatible = "atkmini-gpioled"},{}
};/*
*platform平台驱动结构体
*/
static struct platform_driver led_driver = {.driver = {.name = "imx6ul-led",.of_match_table = led_of_match,},.probe = leddev_probe,.remove = leddev_remove,
};static int __init leddriver_init(void)
{return platform_driver_register(&led_driver);
}static void __exit leddriver_exit(void)
{platform_driver_unregister(&led_driver);printk("newchrdev exit\n");
}module_init(leddriver_init);
module_exit(leddriver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("ZK");

一、linux驱动开发-8.2-设备树下platform驱动相关推荐

  1. Linux驱动_设备树下LED驱动

    前言 学习完设备树基础知识后,完成设备树下LED驱动实验 一.修改设备树文件 在设备书根/节点下添加子节点led信息: alphaled {status = "okay";comp ...

  2. Linux 有/无设备树下 platform_driver 驱动框架

    文章目录 platform 驱动框架 platform 设备框架 有设备树下驱动开发注意事项 宏___一行代码创建 platform_driver platform 驱动框架 首先,定义一个 plat ...

  3. 驱动开发基础知识——设备树

    BSP开发工程师[原来BSP就是那些被指臃肿的文件啊 BSP的出生 Linux经过不断的发展,原先嵌入式系统的三层结构逐步演化成为一种四层结构. 这个新增加的中间层次位于操作系统和硬件之间,包含了系统 ...

  4. Linux dts设备树和platform驱动详解

    概念 小麦大叔 2019-05-06 22:56:31 12603 收藏 135 什么是设备树 dts(device tree)? 设备树(Device Tree)是描述计算机的特定硬件设备信息的数据 ...

  5. Linux驱动开发中与设备树相关的6种debug方法

    整理出了6种驱动开发时与设备注册.设备树相关的调试方法,彼此间没有优先级之分,每种方法不一定是最优解,但可以作为一种debug查找问题的手段,快速定位问题原因.例如在芯片验证时,不同时钟频率下系统启动 ...

  6. linux驱动开发学习2 设备树

    设备树 dtb板级信息文件,大势所趋,一定要学  如何确定要编译哪个DTS文件:查看linux下的arch/arm/boot/dts/Makefile  DTS语言有属于自己的语法:以树形来描述设备信 ...

  7. 驱动程序开发:无设备树和有设备树的platform驱动

    1.Linux 驱动的分离与分层   对与对IO进行最简单的读写操作,无需考虑太多的怎么使它重用性强,而像I2C. SPI.LCD 等这些复杂外设的驱动,Linux 系统要考虑到驱动的可重用性,因此提 ...

  8. Linux驱动学习记录-6.设备树的LED驱动

    这一章使用第五章的设备树知识来写led驱动 1.修改设备树 在根节点下面添加子节点 alphaled {#address-cells = <1>;#size-cells = <1&g ...

  9. Linux——Linux驱动之设备树下platform总线驱动编写实战(手把手教你设备树下platform总线利用GPIO控制蜂鸣器完整实现过程)

    [系列专栏]:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! <QT开发实战> <嵌入式通用开发实战>

最新文章

  1. 判断exception类型_C++核心准则T.44:使用函数模板推断类模板参数类型(如果可能)...
  2. 算法题解:对于输入数字串,给出另一种数字排列,使得字典序增加尽可能小...
  3. 产品经理 需求 项目经理 选择_产品经理和项目经理的区别
  4. 故障排错-解决迅雷播放器在Windows 10中长时间停止响应
  5. MobileNetV3
  6. vim全局搜索并跳转
  7. 重置linux桌面,Ubuntu 18.04小贴士:重置Gnome桌面与使用隐藏的屏幕录像工具
  8. Python的几种主动结束程序方式
  9. UNIX环境高级编程8.9竞争条件
  10. hibernate 环境搭建测试
  11. jzoj1293,P2933-气象牛(气象测量)【dp】
  12. 【转】selenium之 定位以及切换frame
  13. 7-2 数列循环右移 (10 分)
  14. sap后台配置原因代码_SAP FI后台配置清单
  15. b85主板装服务器系统,华硕b85主板装不上win7怎么办
  16. Python常见问题与解决方案
  17. word文档中在文字的右上角加标注快捷键
  18. [原创][爬虫学习·一]爬取天天基金网的基金收益排行信息
  19. layui 图片剪切/截取
  20. mac brew的安装方法

热门文章

  1. 电脑重启后,eclipse可能会出现项目丢失情况
  2. 查询使用计算机的处理器型号是,计算机CPU信息如何查看
  3. 《贪心算法》— NYOJ 1309 冰法斗神龙
  4. PayPal防冻结攻略
  5. mysql命令行 进入库_MySQL命令行操作数据库
  6. Qualifier注解
  7. jsp编程中处理红头文件保存及使用
  8. 【三分/贪心/数学】装备合成
  9. java泛型 初始化_Java泛型详解
  10. SQL SERVER数据库面试题