linux平台总线模型
什么是平台总线模型: 是linux系统假造出来的总线, 没有对应的硬件接口平台总线模型将一个驱动分成了两个部分
device.c: 描述硬件资源代码, 描述寄存器的地点, 中断号
driver.c: 控制硬件的驱动代码, 操作寄存器, 处理中断
这两个部分通过相同的name进行匹配
为什么要使用平台总线, 平台总线的优点
差异的处理器的相同功能的寄存器不在一个位置, 但是使用驱动可以是同一套
[*]减少编写的重复代码, 提高服从
[*]提高代码的使用率
注册平台设备
device.c描述的硬件资源是
硬件的寄存器的地点, 中断号, 和其他硬件资源
使用下面的结构体描述
struct platform_device {
// 名字, 和driver匹配, 可以在sys目录下看到
const char *name;
// 区分不同的设备, sys目录下的设备文件的后缀(-1无后缀)
int id;
bool id_auto; // 自动设置id, 一般不用
// 设备的通用属性部分, 必须实现里面的release函数
struct device dev;
u64 platform_dma_mask;
struct device_dma_parameters dma_parms;
// 存储资源的个数
u32 num_resources;
// 存放硬件资源的结构体
struct resource *resource;
const struct platform_device_id *id_entry;
const char *driver_override;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};描述硬件资源的结构体
// linux-master/include/linux/ioport.h
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
unsigned long desc;
struct resource *parent, *sibling, *child;
};
[*]start/end: 资源的起始信息和终止信息, 比如寄存器的起始地点和终止地点
[*]flags: 硬件资源信息的范例, 在include/linux/ioport.h路径下列举
硬件资源举例
static struct resource my_device_resources[] = {
= {
.start = 0xFDD60000,
.end = 0xFDD60004,
.flags = IORESOURCE_MEM, // 内存类型或寄存器
},
= {
.start = 13,
.end = 13,
.flags= IORESOURCE_IRQ, // 中断类型
},
};platform设备加卸载函数: 把设备加载到总线上
int platform_device_register(struct platform_device *pdev)
void platform_device_unregister(struct platform_device *pdev)注册平台驱动
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
bool prevent_deferred_probe;
bool driver_managed_dma;
};
[*]probe: 必须实现, 当设备和驱动匹配乐成之后, 自动执行
[*]remove: 移出一个设备的时候执行
[*]shutdown: 电源管理, 关掉设备时执行
[*]suspend: 电源管理, 挂起时执行
[*]resume: 电源管理, 恢复时执行
[*]driver: 设备共用的一些属性
[*]id_table: 设备的ID表
platform驱动加卸载函数
const struct platform_device_id mydriver_id_table = {
.name = "mydevice",
};
struct platform driver platform driver test ={
.probe = mydriver_probe,
.remove =mydriver_remove,
.driver = {
.name ="mydevice",
.owner = THIS_MODULE,
}
// id_table的优先级大于drive中的name
.id_table = &mydriver_id_table,
}
int platform_driver_register(struct platform_driver *drv, struct module *owner)
void platform_driver_unregister(struct platform_driver *drv);设备和驱动的匹配方法
平台设备和驱动的匹配方法
[*]先通过platform_driver中的id_table
[*]假如id_table不存在,则只是简单的比较设备中的name字段和驱动中的name字段是否相同
static int platform_match(struct device *dev, struct device_driver *drv)
{
...
/* 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);
}获取设备资源
获取设备资源的函数
platform_get_resource: 返回设备指定范例的第num个资源
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)
{
u32 i;
for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource;
if (type == resource_type(r) && num-- == 0)
return r;
}
return NULL;
}用户程序通过平台总线访问设备寄存器的例子
https://img2024.cnblogs.com/blog/3591076/202501/3591076-20250111165813396-1117421623.jpg
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]