基於平台匯流排的按鍵裝置驅動

2021-08-15 13:25:48 字數 3721 閱讀 9040

平台匯流排

將裝置和驅動分離開來,便於移植,提供裝置與驅動的匹配。

裝置模組的程式

#include

#include

#include

#include

#include

//定義key的控制暫存器

#define gpncon 0x7f008830

//定義資源

struct resource key_resource = ,

[1] = ,

};//定義乙個平台裝置

struct platform_device key_dev =;

int keydev_init()

void keydev_exit()

module_license("gpl");

module_author("caokaipeng");

module_description("platform_bus driver");

module_version("v1.0");

module_init(keydev_init);

module_exit(keydev_exit);

驅動模組程式

#include

#include

#include

#include

#include

#include

#include //kmalloc函式需要

#include //copy_to_user函式需要

#include

#include

//按鍵編號

unsigned

int key_num = 0;

//定義下半部工作

struct work_struct *work1;

//定義乙個定時器

struct timer_list key_timer;

//定義乙個等待佇列

wait_queue_head_t key_wait_queue;

//定義乙個resource_irq

struct resource *res_irq;

//定義乙個resource_mem

struct resource *res_mem;

//控制暫存器虛擬位址

unsigned

int *key_base;

//work1具體執行的函式

void work1_func()

//定時器的超時函式

void key_timer_func(unsigned

long data)

else

//check key2是否仍然按下

key2_val = readl(key_base+1)&0x02;

if(0 == key2_val)

else

//喚醒佇列中程序

wake_up(&key_wait_queue);

}//中斷處理函式

irqreturn_t key_interrupt(int irq, void *dev_id)

//硬體(key)初始化函式

void key_hw_init()

//open裝置操作

int key_open(struct inode *node, struct file *filp)

//read裝置操作

ssize_t key_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)

//定義並初始化file_operations

struct file_operations key_fops =

;//定義並初始化miscdevice結構體

struct miscdevice key_miscdev =

;//定義probe函式

int __devinit key_probe(struct platform_device *pdev)

//獲取中斷號

res_irq = platform_get_resource(pdev,ioresource_irq,0);

//註冊中斷->gpn0對應中斷號irq_eint(0)

request_irq(res_irq->start,key_interrupt,irqf_trigger_falling,"key",0);

//註冊中斷->gpn1對應中斷號irq_eint(1)

request_irq(res_irq->end,key_interrupt,irqf_trigger_falling,"key",0);

//獲取基位址

res_mem = platform_get_resource(pdev,ioresource_mem,0);

size = res_mem->end - res_mem->start +1;

key_base = ioremap(res_mem->start,size);

//硬體初始化

key_hw_init();

//建立工作1

work1 = kmalloc(sizeof(struct work_struct),gfp_kernel); //分配空間

init_work(work1,work1_func);

//初始化定時器

init_timer(&key_timer);

//設定超時函式

key_timer.function = key_timer_func;

//註冊定時器

add_timer(&key_timer);

//初始化等待佇列

init_waitqueue_head(&key_wait_queue);

return ret;

}//定義remove函式

int __devinit key_remove(struct platform_device *pdev)

//定義乙個平台驅動

struct platform_driver key_drv = ,

};static

int button_init()

static

void button_exit()

module_license("gpl");

module_author("caokaipeng");

module_description("key driver");

module_version("v1.0");

module_init(button_init);

module_exit(button_exit);

應用程式

#include

#include

int main()

//2.讀取裝置

read(fd,&key_num,4);

printf("key_num is %d.\n",key_num);

//3.關閉裝置

close(fd);}

執行結果

Linux平台匯流排驅動裝置模型

platform匯流排是一種虛擬的匯流排,相應的裝置則為platform device,而驅動則為platform driver。linux 2.6的裝置驅動模型中,把i2c rtc lcd等都歸納為platform device。匯流排將裝置和驅動繫結,在系統每註冊乙個裝置的時候,會尋找與之匹配的...

匯流排,裝置,驅動的裝置模型

kobject,kset是裝置模型的基本結構體,裝置模型使用這兩個結構體來完成裝置的層次關係,但在實際的裝置驅動編寫中,我們基本上用不到kobject,kset這些結構體,是因為這些結構體又被嵌入到更大的結構體中,原因在於kobject,kset結構體只能表徵裝置的層次關係,但是乙個裝置的驅動,並不...

輸入裝置驅動之按鍵裝置驅動

linux輸入子系統就是乙個基於分層模式的系統,其基本的層次分解如下圖所示。在圖中我們可以發現輸入子系統主要包括三個部分裝置驅動層 input driver 核心層 input core 和輸入事件驅動層。輸入子系統的劃分使得輸入裝置的驅動程式設計越來越簡單,但是其中的思想採用我們學習的重點和難點。...