Linux 设备树下的 platform 驱动示例
Linux 总线设备和驱动模式
2、platform_match函数
在drivers/base/platform.c的platform_match函数
/*** platform_match - bind platform device to platform driver.* @dev: device.* @drv: driver.** Platform device IDs are assumed to be encoded like this:* "<name><instance>", where <name> is a short description of the type of* device, like "pci" or "floppy", and <instance> is the enumerated* instance of the device, like '0' or '42'. Driver IDs are simply* "<name>". So, extract the <name> from the platform_device structure,* and compare it against the name of the driver. Return whether they match* or not.*/
static int platform_match(struct device *dev, struct device_driver *drv)
{struct platform_device *pdev = to_platform_device(dev);struct platform_driver *pdrv = to_platform_driver(drv);/* When driver_override is set, only bind to the matching driver */if (pdev->driver_override)return !strcmp(pdev->driver_override, drv->name);/* Attempt an OF style match first */if (of_driver_match_device(dev, drv))return 1;/* Then try ACPI style match */if (acpi_driver_match_device(dev, drv))return 1;/* Then try to match against the id table */if (pdrv->id_table)return platform_match_id(pdrv->id_table, pdev) != NULL;/* fall-back to driver name match */return (strcmp(pdev->name, drv->name) == 0);
}
可以看出驱动和设备的匹配有四种方法
of_driver_match_device(dev, drv)
第一种匹配方式, OF 类型的匹配,也就是设备树采用的匹配方式, of_driver_match_device 函数定义在文件include/linux/of_device.h 中。device_driver 结构体(表示设备驱动)中有个名为of_match_table的成员变量,此成员变量保存着驱动的compatible匹配表, 设备树中的每个设备节点的 compatible 属性会和 of_match_table 表中的所有成员比较,查看是否有相同的条目,如果有的话就表示设备和此驱动匹配,设备和驱动匹配成功以后 probe 函数就会执行。
acpi_driver_match_device(dev, drv)
if (pdrv->id_table)return platform_match_id(pdrv->id_table, pdev) != NULL;
return (strcmp(pdev->name, drv->name) == 0);
3、设备树下的platform驱动框架
#define GPIOLED_CNT 1
#define GPIOLED_NAME "dtsplatled"
#define LEDOFF 0
#define LEDON 1/* gpioled设备结构体 */
struct gpioled_dev
{dev_t devid;int major;int minor;struct cdev cdev;struct class *class;struct device *device;struct device_node *nd;int led_gpio;
};struct gpioled_dev gpioled; /* LED */static int led_open(struct inode *inode, struct file *filp)
{filp->private_data = &gpioled;return 0;
}static int led_release(struct inode *inode, struct file *filp)
{
struct gpioled_dev *dev = filp->private_data;return 0;
}static ssize_t led_write(struct file *filp, const char __user *buf,size_t count, loff_t *ppos)
{int ret;unsigned char databuf[1];struct gpioled_dev *dev = filp->private_data;return 0;
}/* 操作集 */
static const struct file_operations led_fops = {.owner = THIS_MODULE,.write = led_write,.open = led_open,.release = led_release,
};/*platform 驱动的 probe 函数,当驱动与设备匹配以后此函数就会执行*/
static int led_probe(struct platform_device *dev)
{printk("led driver and device was matched!\r\n");int ret = 0;/* 1.申请设备号 */...code.../* 2,初始化cdev */...code.../* 3,添加cdev */...code.../* 4、创建类 */...code.../* 5,创建设备 */...code.../* 1,获取设备节点 */gpioled.nd = dev->dev.of_node;/* 2, 获取LED所对应的GPIO */gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpios", 0);if (gpioled.led_gpio < 0){}/* 3,申请IO */ret = gpio_request(gpioled.led_gpio, "led-gpio");if (ret){}/* 4,使用IO,设置为输出 */ret = gpio_direction_output(gpioled.led_gpio, 1);if (ret){}/* 5,输出底电平,点亮LED灯*/gpio_set_value(gpioled.led_gpio, 0);return 0;}static int led_remove(struct platform_device *dev)
{printk("led remove\r\n");/* 关灯 */gpio_set_value(gpioled.led_gpio, 1);/* 注销字符设备驱动 */
...code.../* 释放IO */gpio_free(gpioled.led_gpio);return 0;
}struct of_device_id led_of_match[] = {{.compatible = "alientek,gpioled"},{/*Sentinel*/},};struct platform_driver led_driver = {.driver = {.name = "imx6ull-led", /*无设备树和设备进行匹配,驱动名字*/.of_match_table = led_of_match, /*设备树匹配表*/},.probe = led_probe,.remove = led_remove,
};/*驱动加载*/
static int __init leddriver_init(void)
{return platform_driver_register(&led_driver);
}/*驱动卸载*/
static void __exit leddriver_exit(void)
{platform_driver_unregister(&led_driver);
}module_init(leddriver_init);
module_exit(leddriver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("supersmart");
注意:所谓的 platform 驱动并不是独立于字符设备驱动、块设备驱动和网络设备驱动之外的其他种类的驱动。platform 只是为了驱动的分离与分层而提出来的一种框架,其驱动的具体实现还是需要字符设备驱动、块设备驱动或网络设备驱动。
Linux 设备树下的 platform 驱动示例相关推荐
- Linux 设备树下的 platform 驱动实验基于正点原子IMX6ULL开发板
1 设备树下的 platform 驱动简介 platform 驱动框架分为总线.设备和驱动,其中总线不需要我们这些驱动程序员去管理,这个是 Linux 内核提供的,我们在编写驱动的时候只要关注于设备和 ...
- 【正点原子MP157连载】第三十五章 设备树下的platform驱动编写-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...
- 设备树下的platform 驱动编写
目录 设备树下的platform 驱动简介 硬件原理图分析 实验程序编写 修改设备树文件 platform 驱动程序编写 编写测试APP 运行测试 编译驱动程序和测试APP 运行测试 上一章我们详细的 ...
- 设备树下的 platform 驱动开发框架
1. 设备树下的platform驱动开发 platform驱动框架分为总线.设备和驱动,其中总线是由Linux内核提供,在编写驱动时只要关注于设备和驱动的具体实现即可.Linux下的platform驱 ...
- 设备树下的platform驱动编写
文章目录 一.设备树下的platform驱动简介 1.在设备树中创建设备节点 2.编写 platform 驱动的时候要注意兼容属性 3.编写platform驱动 二.硬件原理图分析 三.实验程序编写 ...
- 设备树下的 platform 驱动
platform 设备驱动 Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的软件思路,在这个思路下诞生了我们将来最常打交道的platform 设备驱动,也叫做平台设备驱动. L ...
- 【正点原子Linux连载】第四十四章 设备树下的LED驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...
- 【正点原子MP157连载】第二十四章 设备树下的LED驱动实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...
- linux uart寄存器 代替 printk,Linux驱动学习之设备树(设备树下的LED驱动实验),...
Linux驱动学习之设备树(设备树下的LED驱动实验), 概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.相当于从驱动代码分离出来的配置文件,比如串口的波特率通过设 ...
最新文章
- JSP的7个动作include,forward,useBean。。。
- find your place
- mysql show processlist host_show processlist host 为 百分号(%)
- rabbitmq 同步策略_RabbitMQ高可用方案总结
- 安卓分辨率_免费的安卓群控1数字云免费安卓群控系统
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(四)example代码解析...
- zookeeper 学习笔记1(转)
- Collections.sort的两种用法
- 多网卡Iptables端口转发
- 祝刘冬冬十八周岁快乐
- Cadence、Pspice 软件相关汇总
- 普元EOS UTP自动化测试 关闭工作流
- iOS AVPlayer播放模式的实现(随机播放 列表循环 单曲循环)
- 用户故事 | 验收标准
- Error: The method ‘DioHttpHeaders.add‘ has fewer named arguments than those of overridden method
- 神仙项目,轻松上手了解前后端分离!
- <马哲>价值规律的内容、表现形式及其作用
- SUPERSCAN IIE接线图
- 从浏览器下载表格数据为Excel的两种实现方法
- linux网络编程学习笔记——epoll
热门文章
- [Vue warn]: Failed to mount component: template or render function not defined.解决方案
- Pytorch:利用迁移学习做图像分类
- 连接wifi推送广告
- 动态路由协议-OSPF原理与推举实验
- PDF与word互相转换
- 电脑小问题不求人--鼠标.软驱.打印机.硬盘.风扇.常见事故处理
- CF1520D Same Differences
- 《OOD启思录》目录—导读
- sublime 4 设置文件编码 GBK
- mysql5.7 密钥_mysql5.7密码登录的那些坑