博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
总线设备驱动模型之platform
阅读量:4286 次
发布时间:2019-05-27

本文共 5893 字,大约阅读时间需要 19 分钟。

platform 设备

  • 匹配
drivers/base/platform.c platform_match 函数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);1. 前提目前我们都用设备树,并解析设备树并创建设备贺电,这样子得到的 pdev->name 为设备节点名pdev->driver_override 为 NULL2. 5种匹配方式	2.1    pdev->driver_override // 对于这一种,为NULL,肯定是不进入的    2.2    OF // 匹配内容 为 compatible 和 .driver.of_match_table[0].compatible 这种匹配方式为多多(两方都可以写多个字符串)匹配,只要有一个匹配上就算成功    2.3    ACPI // 貌似被淘汰了,只是兼容    2.4    pdrv->id_table // id_table->name 和 pdev->name 匹配, 为单单匹配,且匹配的只能为 节点名.        platform_match_id(pdrv->id_table, pdev)            2.5    (strcmp(pdev->name, drv->name) // pdev->name, drv->name 匹配 ,单单匹配,且只能是节点名        2.2 举例// 驱动端static const struct of_device_id ids[] = {
{
.compatible = "chip-name"}, {
.compatible = "chip-name2"}, {
}, // 一定要有 }; struct platform_driver pdr = {
.driver= {
.name = "somethingSUIBIAN_BUT_MUST_HAVE", .of_match_table = ids, // 匹配关键 } .id_table = &p_id_table, .probe = pdr_probe, .remove = pdr_remove, }platform_driver_register(&pdr);// 设备端node-platform-node {
compatible = "vendor-name", "chip-name", "chip-name2","chip-name3";// 匹配关键}2.4 举例// 驱动端static const struct platform_device_id p_id_table = {
.name = "node-platform-node", //匹配关键};struct platform_driver pdr = {
.driver= {
.name = "somethingSUIBIAN_BUT_MUST_HAVE", } .id_table = &p_id_table, .probe = pdr_probe, .remove = pdr_remove, }platform_driver_register(&pdr);// 设备端node-platform-node {
// 匹配关键 compatible = "somethingSUIBIAN_BUT_MUST_HAVE";}2.5 举例// 驱动端static const struct platform_device_id p_id_table = {
.name = "node-platform-node", //匹配关键 };struct platform_driver pdr = {
.driver= {
.name = "node-platform-node", // 匹配关键 } .probe = pdr_probe, .remove = pdr_remove, }platform_driver_register(&pdr);// 设备端node-platform-node {
// 匹配关键 compatible = "somethingSUIBIAN_BUT_MUST_HAVE";}
  • 命令行传参
//传参处chosen {
bootargs = "node-platform-file.num=100" };//定义处node-platform-file.c 文件中static int num=10; // 初始化为10,在启动过程中被修改为100module_param(num,int,S_IRUGO);// 修改处kernel/params.c parse_one params[i].ops->set(val, &params[i]); // 修改num为 100
  • sys 节点
driver 目录/sys/bus/platform/drivers/xxx //xxx 为 pdr.driver.name/sys/devices/platform/yyy // yyy 为 设备节点名sysfs_create_group(&pdev->dev.kobj, &sysfs_demo_attr_group) // 在 /sys/devices/platform/yyy
  • 相互获取
从pdev 到 其他int pdr_probe(struct platform_device * pdev);获取 dev :pdev->dev获取 设备树节点 : pdev->dev.of_node获取驱动 : pdev->dev->driver从 dev 到其他struct platform_device *pdev = to_platform_device(dev);从 drv 到其他struct platform_driver *pdrv = to_platform_driver(drv);
  • pdev 结构体变量
int pdr_probe(struct platform_device * pdev);name:node-platform-nodeid:-1id_auto:0num_resources:1resources:9f59f240id_entry:  (null) // %p为  (null)// 前面有两个空格driver_override:  (null)
  • driver sys 目录
/sys/bus/platform/drivers/xxx # --w-------    1 0        0             4096 Apr 20 10:30 bind // 用来加载驱动 // /sys/devices/platform 下面的文件夹的名字 ,如果加载之后,没有显示出yyy,表示没有匹配到设备lrwxrwxrwx    1 0        0                0 Apr 20 10:30 yyy -> ../../../../devices/platform/yyy  // 匹配的设备名及设备目录 //如果没有此文件,代表该驱动没有匹配到设备--w-------    1 0        0             4096 Apr 20 10:30 uevent // 传入 add ,用来执行 udevd 规则--w-------    1 0        0             4096 Apr 20 10:30 unbind // 用来卸载驱动 写入设备名(当前目录下的yyy)
  • device sys 目录
/sys/devices/platform/yyy/:total 0lrwxrwxrwx    1 0        0                0 Apr 20 10:30 driver -> ../../../bus/platform/drivers/xxx // 已经匹配到驱动,驱动目录-rw-r--r--    1 0        0             4096 Apr 20 10:30 driver_override // pdev->driver_override 为  (null)-r--r--r--    1 0        0             4096 Apr 20 10:30 modalias // of:Nnode-platform-nodeT
Cvendor-nameCchip-nameCchip-name2Cchip-name3 // 设备节点名及 compatible 属性值-rw-r--r-- 1 0 0 4096 Apr 20 10:30 node_one // sysfs_create_group 节点-r--r--r-- 1 0 0 4096 Apr 20 10:30 node_two // sysfs_create_group 节点drwxr-xr-x 2 0 0 0 Apr 20 10:30 power // power 目录,power 相关lrwxrwxrwx 1 0 0 0 Apr 20 10:30 subsystem -> ../../../bus/platform // 隶属总线-rw-r--r-- 1 0 0 4096 Apr 20 10:30 uevent // 设备下面的这个uevent 属性是干什么的 drivers/base/core.c 中的 uevent_store // 估计也是用来测试 udevd 规则的 //# cat uevent //DRIVER=noneed_to_fill_in//OF_NAME=node-platform-node//OF_FULLNAME=/node-platform-node//OF_COMPATIBLE_0=vendor-name//OF_COMPATIBLE_1=chip-name//OF_COMPATIBLE_2=chip-name2//OF_COMPATIBLE_3=chip-name3//OF_COMPATIBLE_N=4//MODALIAS=of:Nnode-platform-nodeT
Cvendor-nameCchip-nameCchip-name2Cchip-name3/sys/devices/platform/yyy/power:total 0-rw-r--r-- 1 0 0 4096 Apr 20 10:31 autosuspend_delay_ms-rw-r--r-- 1 0 0 4096 Apr 20 10:31 control-r--r--r-- 1 0 0 4096 Apr 20 10:31 runtime_active_time-r--r--r-- 1 0 0 4096 Apr 20 10:31 runtime_status-r--r--r-- 1 0 0 4096 Apr 20 10:31 runtime_suspended_time
  • 去初始化测试
/sys/bus/platform/drivers/xxx 下面有 bind  yyy unbind 表示已经匹配成功可以通过 echo yyy > unbind 来卸载驱动然后再 echo yyy > bind 来加载驱动如果没有什么问题(不会有错误堆栈打出来,不会死机),基本上去初始化是ok的
  • 私有数据的存放
// 设置 s2mps11_clks 的数据指向s2mps11_clks->pdev = pdev;// 从 s2mps11_clks get 到 pdevstruct platform_device * pdev = s2mps11_clks->pdev---// 设置 pdev 的私有数据platform_set_drvdata(pdev, s2mps11_clks);// 拿 pdev 的私有数据struct s2mps11_clk *s2mps11_clks = platform_get_drvdata(pdev);

转载地址:http://ioigi.baihongyu.com/

你可能感兴趣的文章
[轉載]6個超強網站讓你查到最道地的英文
查看>>
HUB 與 Switch 差別
查看>>
linux產生 core dump文件方法及設置
查看>>
How to pass macro definition from “makefile” command line arguments to C source code?
查看>>
英文句型
查看>>
mtd and /dev/mtd*相關資料
查看>>
cp: cannot create symbolic link to fat format of usb: Operation not permitted
查看>>
MTD bad Block issue
查看>>
How to change network interface name
查看>>
ubifs and ubi and mtd
查看>>
shell script set 用法
查看>>
英文序數寫法與唸法 Ordinal Numbers(轉載)
查看>>
DVB-S info
查看>>
绿盟扫描操作指导
查看>>
理解链路本地址与站点本地地址
查看>>
/proc/mtd 各个参数含义 -- linux内核
查看>>
linux nand flash常用命令
查看>>
NESSUS扫描操作指导
查看>>
C语言读取文件大小,载入文件全部内容
查看>>
C语言 static静态变量的作用
查看>>