03-03 platfrom
8.platform驱动分离
gitee代码
代码结构

1. 总线设备驱动模型
这一部分的主要内容可参考上述博客
1.1 platform dev和drv 匹配机制
-
首先匹配
device中的driver_override与drv中name是否匹配 -
第二匹配设备中
device中从设备树中解析的properties(即compatible) type name。存放在device存放在devicenode中,deriver存放在of_match_table中此项中匹配顺序为
compatible > type > name -
如果上述依然无法配到到对应的
device和driver,则接下来去匹配platform_device.name和platform_driver.id_table[i].name -
最后回去匹配
device的name与deriver的name
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);
}
当device与deriver匹配成功后调用deriver->probe。在probe中执行相关的初始化操作
2. 知识点扩展
2.1 ioremap/iounmap
将物理地址转化为linux能直接使用的虚拟地址
static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
返回地址为虚拟地址的首地址
注意:ioremap物理地址和虚拟地址的映射是整页整页的映射的。(一页为4096字节)
2.2 volatile
这里需要理解一点就是编译器的优化机制
int a;
a = 0;
a = 1;
如上所述,编译器可以直接优化为a=1,这对于操作硬件寄存器等操作来说是不能接受的
2.3 EXPORT_SYMBOL()
将一个函数以符号方式导出给其他模块使用
- 在调用该函数的另外一个模块中使用extern对其声明
- 需要注意模块的加载顺序,需要先加载定义该函数的模块,再加载调用此函数的模块

浙公网安备 33010602011771号