|
Linux驅(qū)動學(xué)習(xí)記錄 閱讀(12) 評論(1) 發(fā)表時間:2008年08月21日 21:13 本文地址:http://qzone.qq.com/blog/61096542-1219324420
2.4內(nèi)核注冊驅(qū)動要用: int register_chrdev (unsigned int major, const char *name, struct file_operations *fops); 2.4內(nèi)核注銷驅(qū)動要用: int unregister_chrdev( unsigned int major, const char *name ); 2.4內(nèi)核驅(qū)動注冊完后,要用以下代碼創(chuàng)建設(shè)備文件 static devfs_handle_t devfs_handle; devfs_handle = devfs_register( NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, BUTTON_MAJOR,&sbc2410_buttons_fops, NULL); 2.4內(nèi)核驅(qū)動要用以下代碼移除設(shè)備文件: devfs_unregister( devfs_handle); ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- 2.6驅(qū)動i注冊設(shè)備號要用: (1)如果主設(shè)備號事先知道,要用: int register_chrdev_region( dev_t first, unsigned int count, char *name ); (2)如果主設(shè)備號為0,則要用動態(tài)分配: int alloc_chrdev_region( dev_t *dev, unsigned int firstminor, unsigned int count, char *name ); 2.6釋放設(shè)備號要用: void unregister_chrdev_region( dev_t first, unsigned int count ); 2.6內(nèi)核字符設(shè)備驅(qū)動注冊要用: struct cdev *my_cdev = cdev_alloc(); my_cdev->ops = &chr_fops; void cdev_init( struct cdev *cdev, struct file_operations *fops); int cdev_add( struct cdev *dev, dev_t num, unsigned int count); 2.6內(nèi)核字符設(shè)備驅(qū)動移除要用: void cdev_del( struct cdev *dev ); 2.6內(nèi)核驅(qū)動注冊完后,要用以下代碼創(chuàng)建設(shè)備文件 devfs_mk_cdev( MKDEV(LED_MAJOR, LED_MINOR), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME); 2.6內(nèi)核驅(qū)動要用以下代碼移除設(shè)備文件: devfs_remove(DEVICE_NAME); ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- 以上也可以用命令創(chuàng)建設(shè)備文件: mknod /dev/設(shè)備文件名 字符設(shè)備(c是字符設(shè)備,b是塊設(shè)備) 主設(shè)備號 次設(shè)備號 例如:mknod /dev/testChar c 100 0 刪除設(shè)備入口: rm /dev/testChar ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- 2.4驅(qū)動總體編寫框架: static int __init my_init(void) { //注冊設(shè)備驅(qū)動 register_chrdev (unsigned int major, const char *name, struct file_operations *fops); //創(chuàng)建設(shè)備文件 static devfs_handle_t devfs_handle; devfs_handle = devfs_register( NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, BUTTON_MAJOR,&sbc2410_buttons_fops, NULL); } static int __exit my_exit(void) { //移除設(shè)備文件 devfs_unregister( devfs_handle); //注銷設(shè)備驅(qū)動 unregister_chrdev( unsigned int major, const char *name ); } module_init( my_init ); module_exit( my_exit ); ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- 2.6驅(qū)動總體編寫框架: static int __init my_init(void) { //分配設(shè)備編號 if(主設(shè)備號) { sbc2440_leds_dev = MKDEV (LED_MAJOR, LED_MINOR); result = register_chrdev_region (sbc2440_leds_dev, count, DEVICE_NAME); } else { result = alloc_chrdev_region (&sbc2440_leds_dev, LED_MINOR, count, DEVICE_NAME); LED_MAJOR = MAJOR (sbc2440_leds_dev); } //注冊字符設(shè)備驅(qū)動 sbc2440_leds_cdev = cdev_alloc(); if (sbc2440_leds_cdev != NULL) { cdev_init (sbc2440_leds_cdev, &sbc2440_leds_fops); sbc2440_leds_cdev->ops = &sbc2440_leds_fops; sbc2440_leds_cdev->owner = THIS_MODULE; if (cdev_add (sbc2440_leds_cdev, sbc2440_leds_dev, count) ) printk (KERN_NOTICE "Someting wrong when adding sbc2440_leds_cdev!\n"); else printk ("Success adding sbc2440_leds_cdev!\n"); }
//創(chuàng)建設(shè)備文件 devfs_handle = devfs_register( NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, BUTTON_MAJOR,&sbc2410_buttons_fops, NULL); } static int __exit my_exit(void) { //移除設(shè)備文件 devfs_remove(DEVICE_NAME); //注銷字符設(shè)備 cdev_del (sbc2440_leds_cdev); //釋放設(shè)備編號: unregister_chrdev_region (sbc2440_leds_dev, count); } module_init( my_init ); module_exit( my_exit ); ------------------------
驅(qū)動程序的編譯: 驅(qū)動程序在編譯之前,所使用的內(nèi)核必須要經(jīng)過編譯,否則驅(qū)動程序不能編譯。 驅(qū)動有用函數(shù) set_irq_type函數(shù) 在set_irq_type(irq,type)中的type如下: #define IRQT_NOEDGE (0) #define IRQT_RISING (__IRQT_RISEDGE) 上升沿有效 #define IRQT_FALLING (__IRQT_FALEDGE) 下升沿有效 #define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE) 雙邊沿有效 #define IRQT_LOW (__IRQT_LOWLVL) 低電平有效 #define IRQT_HIGH (__IRQT_HIGHLVL) 高電平有效 #define IRQT_PROBE (1 << 4) 按鍵驅(qū)動總結(jié): set_gpio_mode_user(k->gpio_port, GPIO_MODE_IN ); up = read_gpio_bit(k->gpio_port); s3c2410_gpio_cfgpin(k->gpio_port, k->gpio_set); set_irq_type( k->irq_no, IRQT_RISING ); 以上這段代碼的功能是: 第一條是設(shè)置GPIO端口的使用模式,在此為輸入模式,總共有4種模式,分別為: 1,GPIO_MODE_IN(輸入模式) 2,GPIO_MODE_OUT(輸出模式) 3,GPIO_MODE_ALT0(第三功能) 4,GPIO_MODE_ALT1(第四功能) 第二條是讀取gpio端口的信號。 第三條是初始化端口 第四條是設(shè)置中斷觸發(fā)方式。 實現(xiàn)了從io口讀取信號,在此為上升沿讀取有效。 在申請中斷之前,必須對端口進行初始化,否則端口不能使用。在中斷處理程序的最后,還要對端口進行復(fù)位,即恢復(fù)到申請中斷前初始化時的狀態(tài)。 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP S_IRUSR Permits(允許) the file's owner to read it. S_IWUSR Permits the file's owner to write to it. S_IRGRP Permits the file's group to read it. S_IWGRP Permits the file's group to write to it.
本文來自CSDN博客,轉(zhuǎn)載請標明出處:http://blog.csdn.net/unbutun/archive/2009/01/08/3732343.aspx
|