代码改变世界

linux设备驱动初学(二)

2012-05-04 10:43  至上  阅读(347)  评论(0编辑  收藏  举报
  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/types.h>
  5. #include <linux/fs.h>
  6. #include <linux/mm.h>
  7. #include <linux/errno.h>
  8. #include <asm/segment.h>
  9. #include <linux/module.h>
  10. #include <linux/sched.h>
  11. #include <linux/cdev.h>
  12. MODULE_LICENSE("Dual BSD/GPL");
  13. unsigned int test_major=0;
  14. static char *book_name = "dissecting Linux Device Drviver";
  15. static int num = 4000;
  16. static int global_major = 0;
  17. struct cc_dev_t
  18. {
  19.   struct cdev cdev;
  20. } cc_dev;
  21. static int cc_read(struct inode *inode,struct file *file,char *buf,int count)
  22. {
  23.     printk(KERN_INFO "*******cc_read********\n");
  24.     return 0;
  25. }
  26. static int cc_write(struct inode *inode,struct file *file,const char *buf,int count)
  27. {
  28.   printk(KERN_INFO "*******cc_write*******\n");
  29.   return 0;
  30. }
  31. static int cc_open(struct inode *inode,struct file *file)
  32. {
  33.   printk(KERN_INFO "********cc_open*******\n");
  34.   return 0;
  35. }
  36. static void cc_release(struct inode *inode,struct file *file)
  37. {
  38.   printk(KERN_INFO "*******cc_release*****\n");
  39. }
  40. struct file_operations cc_fops={
  41.  .owner = THIS_MODULE,
  42.  .read = cc_read,
  43.  .write = cc_write,
  44.  .open = cc_open,
  45.  .release = cc_release,
  46. };
  47. static int __init cc_init(void)
  48. {
  49.   int result,err;
  50.   dev_t devno = MKDEV(0,0);
  51.   result = alloc_chrdev_region(&devno,0,1,"cc");
  52.   global_major = MAJOR(devno);
  53.   if(result < 0)
  54.   {
  55.     return result;
  56.   }
  57.   cdev_init(&cc_dev.cdev,&cc_fops);
  58.   err = cdev_add(&cc_dev.cdev,devno,1);
  59.   if(err)
  60.     printk(KERN_NOTICE "Error");
  61.   return 0;
  62. }
  63. void cc_exit(void)
  64. {
  65.   cdev_del(&cc_dev.cdev);
  66.   unregister_chrdev_region(MKDEV(global_major,0),1);
  67. }
  68. module_init(cc_init);
  69. module_exit(cc_exit);
  70. module_param(num,int,S_IRUGO);
  71. module_param(book_name,charp,S_IRUGO);
  72. MODULE_AUTHOR("xyl");
  73. MODULE_DESCRIPTION("A simple Hello world Moudle");
  74. MODULE_ALIAS("a simplest moudle");

写完驱动部分 make一下 在/proc/devices下面就会有对应的主设备号了

makefile文件

  1.     PWD = $(shell pwd)
  2.     CC=gcc
  3.     KERNEL_SRC = /usr/src/linux-source-2.6.38/
  4.     obj-m := cc.o
  5.     module-objs := cc.o
  6. all:   
  7.     $(MAKE) -C $(KERNEL_SRC)  M=$(PWD) modules
  8. clean:
  9.     rm *.ko
  10.     rm *.o

之后在/dev下面创建设备节点  cat /proc/devices获得主设备号  mknod /dev/cc c major minor

在/dev下面就会有对应的设备节点了  如果想要删除的话直接rm掉

下面是test.c

  1. #include<stdio.h>
  2. #include<fcntl.h>
  3. int main()
  4. {
  5.   int myfile;
  6.   char buffer[100];
  7.   int retval;
  8.   myfile = open("/dev/cc",O_RDWR);
  9.   if(myfile < 0)
  10.     printf("Open filed /n");
  11.   write(myfile,"hello_world",sizeof("hello_world"));
  12.   retval = read(myfile,buffer,100);
  13.   buffer[retval] = 1;
  14.   printf("redponse:%s/n",buffer);
  15.   close(myfile);
  16. }

其中close对应驱动中的release.上面的 write read 内容就随便写啦,因为我驱动中并没有实现。

编译一下执行,看内核输出信息dmesg 如下

[ 5096.422497] ********cc_open*******
[ 5096.422512] *******cc_write*******
[ 5096.422519] *******cc_read********
[ 5096.422572] *******cc_release*****
这样就说明调用成功了