Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6643172
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: LINUX

2011-06-06 12:23:13

驱动程序:

  1. /*chardev.c*/
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>                   /*for file-f_op*/
  4. #include <linux/module.h>
  5. #include <asm/uaccess.h>                /*for copy_to_user()*/
  6. #include <linux/cdev.h>                 /*for cdev ,cdev_init,cdev_add....*/
  7. MODULE_LICENSE("GPL");
  8. MODULE_AUTHOR("Helight");
  9. #define DP_MAJOR 250                    /*the major number of the chardev*/
  10. #define DP_MINOR 0                      /*the minor number of the chardev*/
  11. static int char_read(struct file *filp,char __user *buffer,size_t,loff_t *);         /*the read operation of the chardev----read the data from kernel*/
  12. static int char_open(struct inode *,struct file *);                                      /*open the chardev*/
  13. static int char_write(struct file *filp,const char __user *buffer,size_t ,loff_t*); /*write data to kernel*/
  14. static int char_release(struct inode *,struct file *);                                   /*release the chardev*/
  15. static int chropen;                     /*the chardev open or not*/
  16. struct cdev *chardev;                   /*define a char device*/
  17. static int len;
  18. static const struct file_operations char_ops = {
  19. .read = char_read,
  20. .write = char_write,
  21. .open = char_open,
  22. .release = char_release,
  23. };
  24. static int __init char_init(void)
  25. {
  26. dev_t dev;
  27. printk(KERN_ALERT"Initing......\n");
  28. dev=MKDEV(DP_MAJOR,DP_MINOR);
  29. chardev = cdev_alloc( );
  30. if(chardev==NULL){
  31. return -1;
  32. }
  33. if(register_chrdev_region(dev,10,"chardev")){
  34. printk(KERN_ALERT"Register char dev error\n");
  35. return -1;
  36. }
  37. chropen=0;
  38. len=0;
  39. cdev_init(chardev,&char_ops);
  40. if(cdev_add(chardev,dev,1))
  41. {
  42. printk(KERN_ALERT"Add char dev error\n");
  43. }
  44. return 0;
  45. }
  46. static int char_open(struct inode *inode,struct file *file)
  47. {
  48. if(chropen==0)
  49. chropen++;
  50. else{
  51. printk(KERN_ALERT"Another process open the char device\n");
  52. return -1;
  53. }
  54. try_module_get(THIS_MODULE);
  55. return 0;
  56. }
  57. static int char_release(struct inode *inode,struct file *file)
  58. {
  59. chropen--;
  60. module_put(THIS_MODULE);
  61. return 0;
  62. }
  63. static int char_read(struct file *filp,char __user *buffer,size_t length,loff_t *offset)
  64. {
  65. if(length<12)
  66. if(!copy_to_user(buffer,"hello world!",length))
  67. {
  68. return 0;
  69. }
  70. }else
  71. {
  72. if(!copy_to_user(buffer,"hello world!",strlen("hello world!")))
  73. {
  74. return 0;
  75. }
  76. }
  77. return -1;
  78. }
  79. static int char_write(struct file *filp,const char __user  *buffer,size_t length,loff_t *offset)
  80. {
  81. return 0;
  82. }
  83. static void __exit module_close(void)
  84. {
  85. len=0;
  86. printk(KERN_ALERT"Unloading..........\n");
  87. unregister_chrdev_region(MKDEV(DP_MAJOR,DP_MINOR),10);
  88. cdev_del(chardev);
  89. }
  90. module_init(char_init);
  91. module_exit(module_close);

用户测试程序:

  1. /*main.c*/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <string.h>
  9. int main(void)
  10. {
  11. int testdev;
  12. int i,rf=0;
  13. char buf[15];
  14. memset(buf, 0, sizeof(buf));
  15. testdev = open("/dev/chardev0",O_RDWR);
  16. if ( testdev == -1 )
  17. {
  18. perror("open\n");
  19. exit(0);
  20. }
  21. rf=read(testdev,buf,12);
  22. if(rf<0)
  23. perror("read error\n");
  24. printf("R:%s\n",buf);
  25. close(testdev);
  26. return 0;
  27. }

编译加载和使用:
<1>程序chardev.c是字符驱动程序,是以内核模块的形式插入内核的,所以编译方法和内核模块的编译方法一致。
<2>模块的加载和卸载也和上面所述的内核模块的加载和卸载方法一致。
<3>设备节点的创建,mknod /dev/chardev0 c 250 0
命令解释:
mknod是建立设备节点的命令;
/dev/chardev0:在/dev/目录下建立chardev0这样一个节点。
c:这个节点是指向一个字符设备的节点
250:这个设备的主设备号
0:次设备号
<3>编译用户程序gcc -o chardev_test main.c
<4>运行chmod 666 /dev/chardev0 使其它用户也可以对这个设备进行读写操作,否则只有root用户可以对它进行读写。
<5>运行chardev_test,如果没有什么问题的话应该要输出这几个字符。
R:hello world!

阅读(1765) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~