Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Linux Kernel 2.6.38内核驱动globalmem--添加中断机制和udev机制

  1. //这个驱动网上有例子,但是很多机制在新的内核里面已经过时了,所以我重写了一下,尽量使用了一些最近内核里面的机制。   
  2. //创建设备节点,使用的udev机制;   
  3. //注册中断向量的时候使用了新的接口函数,包括了ISR的接口的改变。   
  4.   
  5.   
  6.   
  7. #include <linux/module.h>   
  8. #include <linux/types.h>   
  9. #include <linux/fs.h>   
  10. #include <linux/errno.h>   
  11. #include <linux/mm.h>   
  12. #include <linux/sched.h>   
  13. #include <linux/init.h>   
  14. #include <linux/cdev.h>   
  15. #include <linux/device.h>   
  16.   
  17. //使用中断机制添加头文件   
  18. #include <linux/sched.h>   
  19. #include <asm/signal.h>   
  20. #include <linux/interrupt.h>   
  21.   
  22. //使用udev机制添加的头文件   
  23. #include <linux/slab.h>   
  24.   
  25. #ifdef CONFIG_SLUB   
  26. #include <linux/slub_def.h>   
  27. #elif defined CONFIG_SLOB   
  28. #include <linux/slob_def.h>   
  29. #else   
  30. #include <linux/slab_def.h>   
  31. #endif   
  32.   
  33.   
  34. #include <asm/io.h>   
  35. #include <asm/system.h>   
  36. #include <asm/uaccess.h>   
  37.   
  38. //swliao:memory size 4K.   
  39. #define MEMS_SIZE 0x1000    
  40.   
  41. //#define MEMS_CLEAR 0x1   
  42.   
  43.   
  44. #define MEMS_MAJOR 300   
  45.   
  46. static struct class *my_class;  
  47.   
  48. static int mems_major = MEMS_MAJOR;  
  49. static unsigned int mems_irq = 1;  
  50. static char* interface = "mems-test";  
  51.   
  52. //module_param()添加模块支持参数,每行设置一个参数   
  53. module_param(mems_irq,int,S_IRUGO);  
  54. module_param(interface,charp,S_IRUGO);  
  55.   
  56.   
  57. //声明设备结构体   
  58. struct mems_dev  
  59. {  
  60.     struct cdev cdev;  
  61.     unsigned char mems[MEMS_SIZE];  
  62. };  
  63.   
  64. struct mems_dev *mems_devp;  
  65.   
  66.   
  67. //对应的中断向量的ISR   
  68. static irqreturn_t mems_irq_handler(int irq,void *dev_id)  
  69. {  
  70.     printk(KERN_INFO "Interrupt handler...............................%d ",irq);  
  71.     return IRQ_HANDLED;  
  72. }  
  73.   
  74. //swliao:open function in file_operation.   
  75. int mems_open(struct inode *inode,struct file *filp)  
  76. {  
  77.     filp->private_data = mems_devp;  
  78.     return 0;  
  79. }  
  80.   
  81. //close()   
  82. int mems_release(struct inode *inode,struct file *filp)  
  83. {  
  84.     return 0;  
  85. }  
  86.   
  87.   
  88.   
  89. //swliao:read() function in file_operations.   
  90. static ssize_t mems_read(struct file *filp,char __user *buf,size_t size,loff_t *ppos)  
  91. {  
  92.     unsigned long p =*ppos;  
  93.     unsigned int count = size;  
  94.     int ret = 0;  
  95.   
  96.     struct mems_dev *dev = filp->private_data;  
  97.   
  98.     if(p >= MEMS_SIZE)  
  99.         return count ? -ENXIO : 0;  
  100.     if(count > MEMS_SIZE-p)  
  101.         count = MEMS_SIZE - p;  
  102.   
  103.     if(copy_to_user(buf,(void *)(dev->mems + p),count))  
  104.     {  
  105.         ret = -EFAULT;  
  106.     }  
  107.     else  
  108.     {  
  109.         *ppos += count;  
  110.         ret = count;  
  111.   
  112.         printk(KERN_INFO "Liaosw read %d bytes. ",count);  
  113.     }  
  114.   
  115.     return ret;  
  116. }  
  117.   
  118. static ssize_t mems_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos)  
  119. {  
  120.     unsigned long p = *ppos;  
  121.     unsigned int count = size;  
  122.     int ret = 0;  
  123.     struct mems_dev *dev = filp->private_data;  
  124.   
  125.     if(p >= MEMS_SIZE)  
  126.         return count ? -ENXIO : 0;  
  127.     if(count > MEMS_SIZE -p)  
  128.         count = MEMS_SIZE - p;  
  129.   
  130.     if(copy_from_user(dev->mems+p,buf,count))  
  131.     {  
  132.         ret = -EFAULT;  
  133.     }  
  134.     else  
  135.     {  
  136.         *ppos += count;  
  137.         ret = count;  
  138.   
  139.         printk(KERN_INFO "Liaosw written %d bytes. ",count);  
  140.     }  
  141.   
  142.     return ret;  
  143. }  
  144.   
  145.   
  146.   
  147. //swliao:very important file_operations structure.   
  148. //字符驱动的主体实现部分:对应设备文件的file_operations结构体   
  149. static const struct file_operations mems_fops =   
  150. {  
  151.     .owner = THIS_MODULE,  
  152.     .read = mems_read,  
  153.     .write = mems_write,  
  154.     .open = mems_open,  
  155.     .release = mems_release,  
  156. };  
  157.   
  158. static void mems_setup_cdev(struct mems_dev *dev,int index)  
  159. {  
  160.     int devno = MKDEV(mems_major,index);  
  161.   
  162.     cdev_init(&dev->cdev,&mems_fops);  
  163.     dev->cdev.owner = THIS_MODULE;  
  164.     dev->cdev.ops = &mems_fops;  
  165.       
  166.     int err = cdev_add(&dev->cdev,devno,1);  
  167.     if(err)  
  168.         printk(KERN_NOTICE "Error %d addint cdev %d. ",err,index);  
  169. }  
  170.   
  171.   
  172.   
  173. //内核模块的入口函数   
  174. //字符设备驱动程序三步:创建分配,初始化,安装注册   
  175. int mems_init()  
  176. {  
  177.   
  178.     printk(KERN_INFO "Install the driver to kernel space. ");  
  179.   
  180.     int result = 0;  
  181.     dev_t devno = MKDEV(mems_major,0);  
  182.   
  183.     if(mems_major)  
  184.         result = register_chrdev_region(devno,1,"mem-test");  
  185.     else  
  186.     {  
  187.         result = alloc_chrdev_region(&devno,0,1,"mem-test");  
  188.         mems_major = MAJOR(devno);  
  189.     }  
  190.       
  191.     if(result < 0)  
  192.         return result;  
  193.   
  194.     mems_devp = kmalloc(sizeofstruct mems_dev),GFP_KERNEL);  
  195.     if(!mems_devp)  
  196.     {  
  197.         result = -ENOMEM;  
  198.         goto fail_malloc;  
  199.     }  
  200.   
  201.     memset(mems_devp,0,sizeofstruct mems_dev));  
  202.   
  203.     mems_setup_cdev(mems_devp,0);  
  204.   
  205.     my_class = class_create(THIS_MODULE,"my_class");  
  206.     if(IS_ERR(my_class))  
  207.     {  
  208.         printk("Err:failed in creating class. ");  
  209.         return -1;  
  210.     }  
  211.     device_create(my_class,NULL,MKDEV(mems_major,0),NULL,"mem-test",0);  
  212.   
  213.     //register interrupt.   
  214.         //请求分配中断向量   
  215.         int flagnum;     
  216.     if(!(flagnum = request_irq(mems_irq,&mems_irq_handler,IRQF_SHARED,interface,mems_devp)))  
  217.     {  
  218.         printk(KERN_INFO "Register interrupt correctly.. ");  
  219.         goto fail_malloc;  
  220.     }  
  221.     else  
  222.         printk(KERN_INFO "Error was happened here...%d ",flagnum);  
  223.   
  224.     return 0;  
  225.   
  226. fail_malloc:  
  227.     unregister_chrdev_region(devno,1);  
  228.     return result;  
  229. }  
  230.   
  231. void mems_exit()  
  232. {  
  233.     cdev_del(&mems_devp->cdev);  
  234.   
  235.         //udev的退出清理   
  236.     device_destroy(my_class,MKDEV(mems_major,0));  
  237.     class_destroy(my_class);  
  238.   
  239.     kfree(mems_devp);  
  240.   
  241.         //释放设备号和中断向量   
  242.     free_irq(mems_irq,mems_devp);  
  243.     unregister_chrdev_region(MKDEV(mems_major,0),1);  
  244.     printk(KERN_INFO "Test module quit kernel space. ");  
  245. }  
  246.   
  247.   
  248. MODULE_AUTHOR("LiaoSW");  
  249. MODULE_LICENSE("GPL");  
  250.   
  251. module_init(mems_init);  
  252. module_exit(mems_exit);  
  253.   
  254.   
  255.   
  256.   
  257.   
  258. 希望对大家有帮助,转载请注明出处,谢谢。