【1】、复习
1. 中断
request_irq
2. 中断底半部
1. 软中断
2. tasklet
3. 工作队列
3. 内核延时机制
1. 中断底半部
2. 定时器
3. 睡眠/延时函数
【2】、作业
1. 按键消抖
【一】、platform平台总线
总线 --->>> 通信
IIC SPI
platform平台总线 --->>> 虚拟总线
完成:设备与驱动分离
设备(device.c):提供设备信息
驱动(driver.c): 驱动硬件设备工作
---------------------------------------------------------------------------------
pltarform IIC SPI
设备
驱动
总线
================================================================================
<linux/pltarform_device.h>
设备端:
struct platform_device {
const char * name; //设备名
int id; //驱动设备 -1
struct device dev; //设备结构体
u32 num_resources; //资源个数
struct resource * resource; //资源结构体指针
};
struct resource {
resource_size_t start; //起始地址
resource_size_t end; //结束地址
const char *name; //名字
unsigned long flags; //资源类型 IORESOURCE_IO
IORESOURCE_MEM
IORESOURCE_IRQ
};
struct device {
struct bus_type *bus;
struct device_driver *driver;
void *platform_data;
struct device_node *of_node;
void (*release)(struct device *dev);
}
/**************************************************************
*功能:注册/注销设备
*参数:
* @pdev 设备结构体指针
*返回值: 成功返回0,失败返回错误码
*************************************************************/
int platform_device_register(struct platform_device *pdev);
void platform_device_unregister(struct platform_device *pdev);
设备注册过程:
platform_device_register(struct platform_device *pdev);
--->>> platform_device_add(pdev);
--->>> device_add(&pdev->dev);
--->>> bus_add_device(dev);
--->>> bus_probe_device(dev);
--->>> device_attach(dev)
--->>> bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
--->>> __device_attach
--->>> driver_match_device(drv, dev)
--->>> drv->bus->match ? drv->bus->match(dev, drv) : 1
--->>> driver_probe_device(drv, dev);
--->>> really_probe(dev, drv);
--->>> probe()
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);
/* 设备树匹配 */
if (of_driver_match_device(dev, drv))
return 1;
/* 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);
}
设备树匹配 > id_table表匹配 > name
驱动端:
struct platform_driver {
/* 探测函数指针 获取设备信息 */
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table; //platform id_table表
};
struct platform_device_id {
char name[PLATFORM_NAME_SIZE]; //设备名
kernel_ulong_t driver_data;
};
struct device_driver {
const char *name; //设备名
struct module *owner;
/*设备树的idtable表*/
const struct of_device_id *of_match_table;
};
struct of_device_id
{
char name[32];
char type[32];
char compatible[128];
#ifdef __KERNEL__
void *data;
#else
kernel_ulong_t data;
#endif
};
/**************************************************************
*功能:注册/注销驱动
*参数:
* @pdrv 驱动结构体指针
*返回值: 成功返回0,失败返回错误码
*************************************************************/
int platform_driver_register(struct platform_driver *pdrv);
void platform_driver_unregister(struct platform_driver *pdrv);
驱动的注册过程:
platform_driver_register
--->>>driver_register(&drv->driver)
--->>> bus_add_driver(drv);
--->>> driver_attach(drv);
--->>> bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
--->>> __driver_attach
--->>> driver_match_device(drv, dev)
--->>> driver_probe_device(drv, dev);
--->>> really_probe(dev, drv);
--->>> probe()
/***********************************************************************
*功能:获取设备信息
*参数:
* @dev platform_device指针
* @type 类型
* @num 编号
*返回值: 成功返回resource指针,失败返回NULL
**********************************************************************/
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)