2.6驱动程序-字符驱动

简介: 驱动程序: /*chardev.c*/ #include linux/kernel.h> #include linux/fs.h>                   /*for file-f_op*/ #include linux/module.

驱动程序:

  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(length12)
  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(rf0)
  23. perror("read error\n");
  24. printf("R:%s\n",buf);
  25. close(testdev);
  26. return 0;
  27. }

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

目录
相关文章
|
Linux
Linux驱动开发(使用I2C总线设备驱动模型编写AT24C02驱动程序)
Linux驱动开发(使用I2C总线设备驱动模型编写AT24C02驱动程序)
149 0
|
5月前
|
Linux 程序员 芯片
【Linux驱动】普通字符设备驱动程序框架
【Linux驱动】普通字符设备驱动程序框架
|
6月前
|
Linux 编译器 测试技术
探索Linux设备树:硬件描述与驱动程序的桥梁
探索Linux设备树:硬件描述与驱动程序的桥梁
514 0
|
存储 安全 Unix
【Linux驱动】字符设备驱动
【Linux驱动】字符设备驱动
61 0
|
Linux 芯片
Linux驱动之I2C设备驱动
下面的代码分析主要都在注释中,会按照驱动中函数的执行顺序分析。
|
开发工具 git
UART子系统(七)字符设备驱动程序的另一种注册方法
UART子系统(七)字符设备驱动程序的另一种注册方法
117 0
UART子系统(七)字符设备驱动程序的另一种注册方法
|
物联网 Linux 开发者
字符驱动设备03 | 学习笔记
快速学习字符设备驱动03
|
Linux
简单字符设备驱动程序
linux驱动程序开发步骤 1)查看原理图、数据手册,了解设备的操作方法。 2)在内核中找到相近的驱动程序,以它为模板进行开发,有时候需要从零开始。 3)实现驱动程序的初始化:比如向内核注册驱动程序,这样应用程序传入文件名时,内核才能找到相应的驱动程序。
1176 0