使用register_chrdev注册字符设备

1.2.2 使用register_chrdev注册字符设备

注册字符设备可以使用register_chrdev函数。

  1. int register_chrdev (unsigned int major, const char name, struct file_operationsfops);

register_chrdev函数的major参数如果等于0,则表示采用系统动态分配的主设备号。

注销字符设备可以使用unregister_chrdev函数。

  1. int unregister_chrdev(unsigned int major, const char *name);

例1.3 register_chrdev注册字符设备实例

代码见光盘\src\1drivermodel\1-3register_chrdev。核心代码如下所示:

  1. static unsigned charsimple_inc=0;
  2. static unsigned char demoBuffer[256];
  3. int simple_open(struct inode inode, struct file filp)
  4. {
  5. if(simple_inc>0)return -ERESTARTSYS;
  6. simple_inc++;
  7. return 0;
  8. }
  9. int simple_release(struct inode inode, struct file filp)
  10. {
  11. simple_inc--;
  12. return 0;
  13. }
  14. ssize_t simple_read(struct file filp, char __user buf, size_t count,loff_t *f_pos)
  15. {
  16. / 把数据复制到应用程序空间 /
  17. if (copy_to_user(buf,demoBuffer,count))
  18. {
  19. count=-EFAULT;
  20. }
  21. return count;
  22. }
  23. ssize_t simple_write(struct file filp, const char __user buf, size_t count,loff_t *f_pos)
  24. {
  25. / 把数据复制到内核空间 /
  26. if (copy_from_user(demoBuffer+*f_pos, buf, count))
  27. {
  28. count = -EFAULT;
  29. }
  30. return count;
  31. }
  32. struct file_operationssimple_fops = {
  33. .owner =THIS_MODULE,
  34. .read =simple_read,
  35. .write =simple_write,
  36. .open =simple_open,
  37. .release =simple_release,
  38. };
  39. /*********
  40. MODULE ROUTINE
  41. *********/
  42. void simple_cleanup_module(void)
  43. {
  44. unregister_chrdev(simple_MAJOR, "simple");
  45. printk("simple_cleanup_module!\n");
  46. }
  47. int simple_init_module(void)
  48. {
  49. int ret;
  50. //根据设备号与设备名注册字符设备
  51. ret =register_chrdev(simple_MAJOR, "simple", &simple_fops);
  52. if (ret<0)
  53. {
  54. printk("Unable to register character device %d!\n",simple_MAJOR);
  55. return ret;
  56. }
  57. return 0;
  58. }
  59. module_init(simple_init_module);
  60. module_exit(simple_cleanup_module);

应用程序的代码如下:

  1. void main(void)
  2. {
  3. int fd;
  4. int i;
  5. char data[256];
  6. int retval;
  7. fd=open("/dev/fgj",O_RDWR);
  8. if(fd==-1)
  9. {
  10. perror("error open\n");
  11. exit(-1);
  12. }
  13. printf("open /dev/fgj successfully\n");
  14. //写数据
  15. retval=write(fd,"fgj",3);
  16. if(retval==-1)
  17. {
  18. perror("write error\n");
  19. exit(-1);
  20. }
  21. //读数据
  22. retval=read(fd,data,3);
  23. if(retval==-1)
  24. {
  25. perror("read error\n");
  26. exit(-1);
  27. }
  28. data[retval]=0;
  29. printf("read successfully:%s\n",data);
  30. //关闭设备
  31. close(fd);
  32. }

使用register_chrdev(LED_MAJOR,DEVICE_NAME,&dev_fops)注册字符设备驱动程序时都要手动建立节点 ,否则在应用程序无法打开该设备

字符设备模块使用insmod加载,加载完毕需要在/dev目录下使用mkmod命令建立相应的文件结点,编译生成的应用层可执行程序为test。本例运行结果如下:

[root@/home]#insmod demo.ko  
[root@urbetter /home]# mknod /dev/fgj c 224 0  
[root@urbetter /home]# ./test   
open /dev/fgj successfully  
read successfully:fgj

原文链接: https://www.cnblogs.com/qiynet/p/5726579.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/237979

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午5:36
下一篇 2023年2月13日 下午5:37

相关推荐