?【實(shí)例】如何編寫嵌入式Linux設(shè)備驅(qū)動(dòng)程序?
關(guān)注、星標(biāo)公眾號(hào),直達(dá)精彩內(nèi)容
來源:技術(shù)讓夢(mèng)想更偉大
整理:李肖遙
struct file_operations {int (*seek) (struct inode * ,struct file *, off_t ,int);int (*read) (struct inode * ,struct file *, char ,int);int (*write) (struct inode * ,struct file *, off_t ,int);int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);int (*select) (struct inode * ,struct file *, int ,select_table *);int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long);int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);int (*open) (struct inode * ,struct file *);int (*release) (struct inode * ,struct file *);int (*fsync) (struct inode * ,struct file *);int (*fasync) (struct inode * ,struct file *,int);int (*check_media_change) (struct inode * ,struct file *);int (*revalidate) (dev_t dev);}
這個(gè)結(jié)構(gòu)的每一個(gè)成員的名字都對(duì)應(yīng)著一個(gè)系統(tǒng)調(diào)用。用戶進(jìn)程利用系統(tǒng)調(diào)用在對(duì)設(shè)備文件進(jìn)行諸如read/write操作時(shí),系統(tǒng)調(diào)用通過設(shè)備文件的主設(shè)備號(hào)找到相應(yīng)的設(shè)備驅(qū)動(dòng)程序,然后讀取這個(gè)數(shù)據(jù)結(jié)構(gòu)相應(yīng)的函數(shù)指針,接著把控制權(quán)交給該函數(shù)。這是linux的設(shè)備驅(qū)動(dòng)程序工作的基本原理。既然是這樣,則編寫設(shè)備驅(qū)動(dòng)程序的主要工作就是編寫子函數(shù),并填充file_operations的各個(gè)域。
unsigned int test_major = 0;static int read_test(struct inode *inode,struct file *file,char *buf,int count){int left; 用戶空間和內(nèi)核空間if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )return -EFAULT;for(left = count ; left > 0 ; left--){__put_user(1,buf,1);buf++;}return count;}
static int write_test(struct inode *inode,struct file *file,const char *buf,int count){return count;}static int open_test(struct inode *inode,struct file *file ){MOD_INC_USE_COUNT; 模塊計(jì)數(shù)加以,表示當(dāng)前內(nèi)核有個(gè)設(shè)備加載內(nèi)核當(dāng)中去return 0;}static void release_test(struct inode *inode,struct file *file ){MOD_DEC_USE_COUNT;}
struct file_operations test_fops = {?read_test,write_test,open_test,release_test,};
int init_module(void){int result;result = register_chrdev(0, "test", &test_fops); 對(duì)設(shè)備操作的整個(gè)接口if (result < 0) {printk(KERN_INFO "test: can't get major number\n");return result;}if (test_major == 0) test_major = result; /* dynamic */return 0;}
void cleanup_module(void){unregister_chrdev(test_major,"test");}
main(){int testdev;int i;char buf[10];testdev = open("/dev/test",O_RDWR);if ( testdev == -1 ){printf("Cann't open file \n");exit(0);}read(testdev,buf,10);for (i = 0; i < 10;i++)printf("%d\n",buf[i]);close(testdev);}
編譯運(yùn)行,看看是不是打印出全1 ?
掃描下方微信,加作者微信進(jìn)技術(shù)交流群,請(qǐng)先自我介紹喔。
嵌入式編程專輯 Linux 學(xué)習(xí)專輯 C/C++編程專輯 Qt進(jìn)階學(xué)習(xí)專輯 關(guān)注微信公眾號(hào)『技術(shù)讓夢(mèng)想更偉大』,后臺(tái)回復(fù)“m”查看更多內(nèi)容。 長按前往圖中包含的公眾號(hào)關(guān)注
評(píng)論
圖片
表情
