餐饮技术支持东莞网站建设,登陆插件wordpress,推广平台有哪些适用于广告,厦门专业网站建设团队platform 设备驱动
在设备驱动模型中#xff0c; 引入总线的概念可以对驱动代码和设备信息进行分离。但是驱动中总线的概念是软件层面的一种抽象#xff0c;与我们SOC中物理总线的概念并不严格相等#xff1a;
物理总线#xff1a;芯片与各个功能外设之间传送信息的公共通…platform 设备驱动
在设备驱动模型中 引入总线的概念可以对驱动代码和设备信息进行分离。但是驱动中总线的概念是软件层面的一种抽象与我们SOC中物理总线的概念并不严格相等
物理总线芯片与各个功能外设之间传送信息的公共通信干线其中又包括数据总线、地址总线和控制总线以此来传输各种通信时序。驱动总线负责管理设备和驱动。制定设备和驱动的匹配规则一旦总线上注册了新的设备或者是新的驱动总线将尝试为它们进行配对。一般对于I2C、SPI、USB这些常见类型的物理总线来说Linux内核会自动创建与之相应的驱动总线因此I2C设备、SPI设备、 USB设备自然是注册挂载在相应的总线上。但是实际项目开发中还有很多结构简单的设备对它们进行控制并不需要特殊的时序。 它们也就没有相应的物理总线比如led、rtc时钟、蜂鸣器、按键等等Linux内核将不会为它们创建相应的驱动总线。
为了使这部分设备的驱动开发也能够遵循设备驱动模型Linux内核引入了一种虚拟的总线——平台总线platform bus)。 平台总线用于管理、挂载那些没有相应物理总线的设备这些设备被称为平台设备对应的设备驱动则被称为平台驱动。 平台设备驱动的核心依然是Linux设备驱动模型平台设备使用platform_device结构体来进行表示其继承了设备驱动模型中的device结构体。 而平台驱动使用platform_driver结构体来进行表示其则是继承了设备驱动模型中的device_driver结构体。
platfrom_device结构体
内核使用platform_device结构体来描述平台设备结构体原型如下 platform_device结构体在内核源码/include/linux/platform_device.h中
struct platform_device {const char *name;int id;struct device dev;u32 num_resources;struct resource *resource;const struct platform_device_id *id_entry;/* 省略部分成员 */};name 设备名称总线进行匹配时会比较设备和驱动的名称是否一致 id 指定设备的编号Linux支持同名的设备而同名设备之间则是通过该编号进行区分 devLinux设备模型中的device结构体linux内核大量使用了面向对象思想platform_device通过继承该结构体可复用它的相关代码方便内核管理平台设备 num_resources 记录资源的个数当结构体成员resource存放的是数组时需要记录resource数组的个数内核提供了宏
platform_driver结构体
内核中使用platform_driver结构体来描述平台驱动结构体原型如下所示 platform_driver结构体在内核源码/include/platform_device.h中
struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table;};
probe函数指针驱动开发人员需要在驱动程序中初始化该函数指针当总线为设备和驱动匹配上之后会回调执行该函数。我们一般通过该函数对设备进行一系列的初始化。 remove函数指针驱动开发人员需要在驱动程序中初始化该函数指针当我们移除某个平台设备时会回调执行该函数指针该函数实现的操作通常是probe函数实现操作的逆过程。 driverLinux设备模型中用于抽象驱动的device_driver结构体platform_driver继承该结构体也就获取了设备模型驱动对象的特性 id_table表示该驱动能够兼容的设备类型。
现在如果写platform驱动第一反应应该是先写设备树就不要想着platform_device了就当它被设备树替代了吧。
简介
在代码中添加of_device_id类型结构体数组。
platform驱动是如何被加载的。就是通过.compatible匹配完成的。如下所示
static const struct of_device_id my_of_ids[] {{.compatible my_platform},{},
};
MODULE_DEVICE_TABLE(of,my_of_ids);##注意两点:
1.这个MODULE_DEVICE_TABLE宏一定不能忘记。不写不会报错。但是匹配不到。
2.my_of_id是一个数组且最后一项必须空值。否则一定出错。
修改设备树
在根节点下添加这个东西简单就是美呀。 hehe{compatible my_platform;};MODULE_DEVICE_TABLEmy_of_ids注册到一个总线设备表中如果设备树中有与它的compatible一致的节点就是两个字符串相同就匹配成功。platform_driver的probe就会被调用。没有匹配成功platform_driver的probe就不会被调用。我们这里都是my_platform字符串所以肯定匹配成功。源码 在代码里我故意将driver的name(hello pd)和设备树的节点(hehe)写的不一样主要是说明以下几点。1.这两个东西可以不同。
2.根据后面的测试结果可知sys目录出现的是driver的name属性值而不是设备树的hehe。
3.driver的name值和设备树的compatible的值也没有关系。
#include linux/init.h
#include linux/module.h
#include linux/printk.h
#include linux/time.h
#include linux/types.h
#include linux/fs.h
#include linux/device.h
#include linux/cdev.h
#include linux/miscdevice.h
#include linux/platform_device.hstatic const struct of_device_id my_of_ids[] {{.compatible my_platform},{},
};MODULE_DEVICE_TABLE(of,my_of_ids);
static int my_probe(struct platform_device *device)
{printk(probe\n);return 0;
}
static int my_remove(struct platform_device *device)
{printk(remove\n);return 0;
}
static struct platform_driver my_platform_driver {.probe my_probe,.remove my_remove,.driver {.name hello pd,.of_match_table my_of_ids,.owner THIS_MODULE,},
};module_platform_driver(my_platform_driver);MODULE_LICENSE(GPL);测试
roothost:/server# insmod helloworld.ko
[ 301.880475] probe
roothost:/server# 匹配成功probe函数执行。
那么.driver的name属性是干什么的这是容易混淆的地方看看下面这个name属性是sys目录下的驱动的名字。位于/sys/bus/platform/drivers下。
roothost:/sys/bus/platform/drivers# ls -ls0 drwxr-xr-x 2 root root 0 Jan 1 05:41 hello pd
/*略*/从下面可以看出name 字符串中间有空格是很不好的习惯。加了也没错。
roothost:/sys/bus/platform/drivers# ls hello\ pd/
bind hehe module uevent unbind
roothost:/sys/bus/platform/drivers#从这里的结果可知hehe作为hello pd的子文件夹出现
遍历hehe文件夹
roothost:/sys/bus/platform/drivers/hello pd# ls hehe
driver modalias power uevent
driver_override of_node subsystem再看of_node文件夹
roothost:/sys/devices/platform/hehe# ls -ls
total 00 lrwxrwxrwx 1 root root 0 Jan 1 06:13 driver - ../../../bus/platform/drivers/hello pd0 -rw-r--r-- 1 root root 4096 Jan 1 05:36 driver_override0 -r--r--r-- 1 root root 4096 Jan 1 05:36 modalias0 lrwxrwxrwx 1 root root 0 Jan 1 05:36 of_node - ../../../firmware/devicetree/base/hehe0 drwxr-xr-x 2 root root 0 Jan 1 05:36 power0 lrwxrwxrwx 1 root root 0 Jan 1 05:36 subsystem - ../../../bus/platform0 -rw-r--r-- 1 root root 4096 Jan 1 05:36 uevent
roothost:/sys/devices/platform/hehe#of_node被链接到了…/…/…/firmware/devicetree/base/hehe也就是/sys/firmware/devicetree/base/hehe目录从这里得到一个信息/sys/firmware/devicetree里面是设备树。在目录只有一个base目录
在该base目录下有如下内容他们都是设备树的根节点的子节点。如果想知道设备树里有什么就来这里找。
roothost:/sys/firmware/devicetree/base# ls
#address-cells model
#size-cells myled
aliases name
chosen pxp_v4l2
clocks regulators
compatible reserved-memory
cpus sii902x-reset
hehe soc
interrupt-controller00a01000 spi4
leds wsinput
memory wskey
roothost:/sys/firmware/devicetree/base#