1.重要な思想
分離に:分離デバイスとドライバ、その管理。一致させるために、最後までバスに追加しました。
2.プラットフォーム・バスとは何ですか?
物理バス用などのUSB、PCI、I2C、SPI、に関しては、バスは、仮想プラットフォームは、抽象バスは、実際にはそのようなバスがないです。なぜ必要プラットフォーム・バスそれ?バスのうち団結と仮想デバイスドライバを維持するために実際には、Linuxデバイスドライバモデル。USBデバイス、I2Cデバイス、PCIデバイス、SPI機器等のために、彼らはCPUと通信するので、直接私たちのCPUとのデータの相互作用の後、それぞれのバスにリンクされているが、ここで我々は、システムに埋め込まれていませんこれらのデバイスの全ては、共通バスに属することが可能である、組み込みシステム、システム統合SoCの独立した周辺コントローラた、接続されている周辺機器のSoCメモリ空間は、バスに接続されていません。完全のために、Linuxのドライバモデルので、これらのデバイスは、バス上のいくつかのデバイスは、ハングアップするバス上の他のデバイスが存在しないようではありません仮想バス(プラットフォーム・バス)、上掛けられています。
プラットフォーム・バス関連のコードは宣言しています。Linux / platform_device.hファイル
図3に示すように、二つの重要な構造platform_deviceのplatform_driverプラットフォームバスと
からなるLinuxデバイス・ドライバ・モデルのいずれかによって二つの部分のバスに:デバイス関連の構成について説明し、駆動構造の説明はplatform_deviceでプラットフォーム・バスに関連していますそしてplatform_driver、各要素は、次の2つの構造を分析したある:
構造(1)platform_device構造と分析
struct platform_device {
const char * name; //平台设备的名字
int id; //ID区分设备名字,如果一个驱动对应一个设备,传-1
struct device dev; //描述设备信息device结构体
u32 num_resources; //资源结构体数量,资源信息结构体数组的大小
struct resource * resource; //资源结构体,一般定义一个数组
};
struct device {
struct device_driver *driver; //设备驱动的结构体指针
struct device_node *of_node; //设备树节点
u32 id;
void (*release)(struct device *dev); //设备端卸载的时候,须调用的函数
};
struct resource {
resource_size_t start; //起始地址
resource_size_t end; //结束地址
const char *name; //资源名字
unsigned long flags; //标志 IORESOURCE_IO IORESOURCE_MEM
//IORESOURCE_IRQ
};
デバイス側呼番号
int platform_device_register(struct platform_device *pdev);
功能:platfrom平台总线设备注册
参数:
@pdev platform平台总线设备端结构体指针
返回值:成功返回0,失败返回负数错误码
void platform_device_unregister(struct platform_device *);
功能:platfrom平台总线设备卸载
参数:
@pdev platform平台总线设备端结构体指针
返回值:成功返回0,失败返回负数错误码
(2)構造platform_driver構造および分析
struct platform_driver {
int (*probe)(struct platform_device *); //获取设备信息,在匹配成功调用
int (*remove)(struct platform_device *); //在移除的时候调用
struct device_driver driver;
const struct platform_device_id *id_table; //id_table表
};
struct device_driver {
const char *name; //名字 匹配
struct bus_type *bus; //总线信息结构体
struct module *owner; //THIS_MODULE
const struct of_device_id *of_match_table; //设备树的相关信息
};
struct platform_device_id {
char name[PLATFORM_NAME_SIZE]; //名字
kernel_ulong_t driver_dat;
};
ドライバー側呼番号
int platform_driver_register(struct platform_driver *pdrv);
功能:platform平台总线驱动端注册函数
参数:
@pdrv platform平台总线驱动端结构体指针
返回值:成功返回0,失败返回负数错误码
void platform_driver_unregister(struct platform_driver *);
功能:platform平台总线驱动端卸载函数
参数:
@pdrv platform平台总线驱动端结构体指针
返回值:成功返回0,失败返回负数错误码
キー:
.platformドライブ登録プロセス:
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)
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;
/* 和名字进行匹配*/
return (strcmp(pdev->name, drv->name) == 0);
}
二.platformデバイス側登録:
platform_device_register
--->>>platform_device_add(pdev);
--->>>device_add(&pdev->dev);
--->>>bus_probe_device(dev);
--->>>device_attach(dev);
--->>>bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
最後の呼び出し上:
**driver_probe_device**
概要:プラットフォームのプラットフォームのバス、デバイスおよび登録プロセス中にドライバー、他の一致がある場合、それはプローブ検出機能ドライバは、デバイス情報を取得する呼び出す、一致があるかどうかを見つけるために、リンクリストを横断します。