linux核心中常見的的匯流排有i2c匯流排,pci匯流排,串列埠匯流排,spi匯流排,pci匯流排,can匯流排,單匯流排等,所以有些裝置和驅動就可以掛在這些匯流排上,然後通過匯流排上的match進行裝置和驅動的匹配。但是有的裝置並不屬於這些常見匯流排,所以我們引入了一種虛擬匯流排,也就是platform匯流排的概念,對應的裝置叫做platform裝置,對應的驅動叫做platform驅動。當然引入platform的概念,可以做的與板子相關的**和驅動的**分離,使得驅動有更好的可擴充套件性和跨平台性。
匯流排上的每個device和driver都有乙個name,他們的匹配就是通過name實現的
1.1 主要資料結構
struct platform_device ;
struct resource ;
//flags標號有ioresource_io、ioresource_mem、ioresource_irq、ioresource_dma四種選擇,常用的是申請記憶體(ioresource_mem)和申請中斷號(ioresource_irq)
platform_device和platform_driver都定義在include\linux\platform_device.hstruct platform_driver ;
struct device_driver ;
1.2 主要方法
//註冊platform device到platform_bus
int platform_device_register(struct platform_device *pdev)
引數:填充好的platform_device
返回值:成功返回0.
//登出platform device
void platform_device_unregister(struct platform_device *pdev)
1.3 資源的讀取//註冊platform driver到platform_bus
int platform_driver_register(struct platform_driver *drv)
引數drv:填充好的platform_driver
//登出platform driver
void platform_driver_unregister(struct platform_driver *drv)
//裝置驅動端獲取platform device
struct resource *platform_get_resource(struct platform_device *dev, unsigned
int type, unsigned
int num)
引數dev: 核心傳過來platform_device的指標
引數type:資源型別,與device的flag對應
引數unm: 同類資源序號
對於資源中的儲存空間的資源讀取,首先讀取資源,然後申請空間,最後完成由虛擬位址到實體地址的對映。具體函式如下
struct resource *res = platform_get_resource(pdev, ioresource_mem, 0);
struct resource *buttons_mem = request_mem_region(res->start, res->end-res->start+1, pdev->name);
void __iomem *buttons_base = ioremap(res->start, res->end - res->start + 1);
對於中斷資源的讀取,只要一步如下操作即可。
struct resource *buttons_irq1 = platform_get_resource(pdev, ioresource_irq, 0);
device.c
driver.c#include
#include
#include
#include
#include
#include
#include
#include
#include
//宣告資源
struct resource demo_resource =
};//一些登出操作
static
void platform_demo_release(struct device *dev)
struct platform_device device_demo =
};static
int __init my_device_init(void)
return
0;out:
return ret;
}static
void __exit my_device_exit(void)
module_init(my_device_init);
module_exit(my_device_exit);
module_license("dual bsd/gpl");
makefile#include
#include
#include
#include
#include
#include
#include
#include
#define demo_debug
#ifdef demo_debug
#define dem_dbg(fmt, arg...) printk(kern_warning fmt, ##arg)
#else
#define dem_dbg(fmt, arg...) printk(kern_debug fmt, ##arg)
#endif
static
int demo_open (struct inode *pnode, struct file *filp)
static ssize_t demo_read (struct file *filp, char __user *buf, size_t count, loff_t *offp)
return len;
cp_err:
return retval;
}static
int demo_release (struct inode *pnode, struct file *filp)
static
struct file_operations fops = ;
static
struct miscdevice demo_misc = ;
//2 匹配裝置成功
static
int demo_probe(struct platform_device *pdev)
//得到資源後做具體的初始化操作
//4 註冊驅動
retval = misc_register(&demo_misc);
if(retval < 0)
return
0;misc_err:
return retval;
}//6 具體的登出操作
static
int demo_remove(struct platform_device *dev)
static
struct platform_driver demo_driver = ,
};static
int __init my_driver_init(void)
static
void __exit my_driver_exit(void)
module_init(my_driver_init);
module_exit(my_driver_exit);
module_license("dual bsd/gpl");
ifneq ($(kernelrelease),)
obj-m +=driver.o
obj-m +=device.o
else
kerneldir = /home/ms/itop4412_kernel_3.0
#記錄當前工程目錄
pwd := $(shell pwd)
default:
$(make) -c $(kerneldir) m=$(pwd) modules
@rm -rf *.o
.t* .m* .*.cmd *.mod
.c *.order *.symvers
endif
clean:
rm -rf *.ko *.o
.t* .m* .*.cmd *.mod
.c *.order *.symvers
linux驅動之platform匯流排
第一部分 裝置驅動模型 1 匯流排 bus type結構體,關鍵函式是match函式和uevent函式 匯流排將裝置和驅動繫結,在系統每註冊乙個裝置的時候,會尋找與之匹配的驅動,相反,在系統每註冊乙個驅動的時候,會尋找與之匹配的裝置,而匹配由匯流排完成。2 裝置 struct device結構體,硬...
驅動 11 3 platform匯流排
1.匯流排 driver base platform.c bus register platform bus type 2.裝置 struct platform device int platform device register struct platform device 註冊 void pl...
3 0 35 platform 匯流排 裝置與驅動
在該核心的裝置驅動模型中,關心匯流排 裝置和驅動這三個實體。在系統每註冊乙個裝置的時候,由匯流排尋找與之匹配的驅動 在系統每註冊乙個驅動的時候,會由匯流排尋找與之匹配的裝置。乙個現實的linux裝置和驅動通常都需要掛載在一種匯流排上,對於本身依附於pci,usb,i2c,spi等的裝置而言,這不是問...