1. 程式人生 > >Linux平臺驅動設備總線模型

Linux平臺驅動設備總線模型

gist linux 分開 圖片 color ase const code 而且

Linux中的Platform總線是虛擬總線,它把驅動和設備的註冊都分開來,對於他們的牽紅線(匹配)過程,提供了“總線-設備-驅動”模型。

它的結構如下圖所示:

技術分享圖片

  • 為什麽要這麽做?

試想,如果設備和驅動不分開,那麽不同設備將會產生大量驅動(代碼冗余),而且維護起來工作量很大。

Platform模型則把穩定不變的部分放在driver,把盡量可變需要設置的部分放到device端,並且兩邊分別註冊管理。

這樣做有如下好處:

  1. 平臺設備都掛在一條Platform總線上
  2. 設備和驅動代碼隔離,可移植性和擴展性強
  • 適用範圍

適用於可選的平臺資源,例如燈、按鍵、LCD等

  • 常用API

註冊設備

int platform_device_register(struct platform_device *pdev);

註銷設備

void platform_device_unregister(struct platform_device *pdev);

註冊驅動

int platform_driver_register(struct platform_driver *drv);

註銷驅動

void platform_driver_unregister(struct platform_driver *drv);

獲取平臺資源

struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
int platform_get_irq(struct platform_device *dev, unsigned int num);
struct resource *platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name);
int platform_get_irq_byname(struct platform_device *dev, const char *name);
  • 基本使用

設備端註冊

 1 /************************ arch/xxx/xxx_platform.c ************************/
 2 static void device_release(struct device *dev)
 3 {
 4 }
 5 
 6 static struct resource xxx_res[]={
 7     [0]={
 8         .start = 11,
 9         .end   = 22,
10         .flags = IORESOURCE_MEM,
11     },
12     [1]={
13         .start = 33,
14         .end   = 44,
15         .flags = IORESOURCE_IRQ,
16     },
17 };
18 
19 struct platform_device xxx_device = {
20     .id = -1,
21     .name = "xxx_device"
22     .resource = xxx_res,
23     .num_resources = ARRAY_SIZE(xxx_res);
24     .dev = {
25         .release = device_release,    /* 一般要有改函數,否則驅動卸載會異常 */
26     },
27 };
28 
29 static int __init xxx_platform_init(void)
30 {
31     return platform_device_register(&xxx_device);
32 }
33 
34 static void __exit xxx_platform_exit(void)
35 {
36     platform_device_unregister(&xxx_device);
37 }
38 
39 module_init(xxx_platform_init);
40 module_exit(xxx_platform_exit);

驅動註冊

 1 /************************ driver/xxx/xxx_driver.c ************************/
 2 static int driver_probe(struct platform_device *dev)
 3 {
 4     struct resource * res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 5     ...
 6     res=platform_get_resource(dev,IORESOURCE_IRQ,0);
 7     ...
 8     return 0;
 9 }
10 
11 static int driver_remove(struct platform_device *dev)
12 {
13     return 0;
14 }
15 
16 static sturct platform_driver xxx_driver = {
17     .probe = driver_probe,
18     .remove = driver_remove,
19     .driver = {
20         .name = "xxx_device"
21     },
22 };
23 
24 static int __init xxx_driver_init(void)
25 {
26     return platform_driver_register(&xxx_driver);
27 }
28 
29 static void __exit xxx_driver_exit(void)
30 {
31     platform_driver_unregister(&xxx_driver);
32 }
33 
34 module_init(xxx_driver_init);
35 module_exit(xxx_driver_exit);

  • 實現原理

TBD

Linux平臺驅動設備總線模型