1.2.2  使用register_chrdev注册字符设备

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

  1. int register_chrdev (unsigned int major, const  char *name, struct file_operations*fops);

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 char simple_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_operations simple_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
[root@urbetter /home]# ./test
open /dev/fgj successfully
read successfully:fgj

使用register_chrdev注册字符设备的更多相关文章

  1. register_chrdev_region/alloc_chrdev_region和cdev注册字符设备驱动

    内核提供了三个函数来注册一组字符设备编号,这三个函数分别是 register_chrdev_region().alloc_chrdev_region() 和 register_chrdev(). (1 ...

  2. 29.使用register_chrdev_region()系列来注册字符设备

    1.之前注册字符设备用的如下函数注册字符设备驱动: register_chrdev(unsigned int major, const char *name,const struct file_ope ...

  3. 002_linux驱动之_register_chrdev注册字符设备

    (一)解析:register_chrdev函数和unregister_chrdev函数 (二)register_chrdev函数原型 int register_chrdev(unsigned int ...

  4. 字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev() (转载)

    1. 字符设备结构体 内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里.该散列表中的每一个元素是一个 char_device_struct 结构,它的定义如下: static ...

  5. 字符设备之register_chrdev与register_chrdev_region(转)

    之前写字符设备驱动,都是使用register_chrdev向内核注册驱动程序中构建的file_operations结构体,之后创建的设备文件,只要是主设备号相同(次设备号不同),则绑定的都是同一个fi ...

  6. liunx驱动之字符设备的注册

    上一篇文章学习了如何编写linux驱动,通过能否正常加载模块进行验证是否成功,有做过liunx应用开发的小伙伴都知道驱动会在'/dev'目录下以文件的形式展现出来,所以只是能加载驱动模块不能算是完成驱 ...

  7. linux 字符设备驱动写法

    字符设备,块设备书 一.register_chrdev_region, register_chrdev, misc_register misc device(杂项设备) 在 Linux 内核的incl ...

  8. Linux学习 :字符设备框架

    一.系统功能框架: U-boot : 启动内核 linux kernel: 启动应用 应用: open,read,write 都是通过C库实现,汇编就相当于swi val,引发中断,通过系统调用接口在 ...

  9. Tiny6410 LED字符设备驱动

    1.查看用户手册 led1.led2.led3.led4 连接的分别是 GPK4.GPK5.GPK6.GPK7 2.查询6410芯片手册 下面还需要3个步骤: 1.设置GPIO为OUTPUT. 将GP ...

随机推荐

  1. Redis学习笔记(五)- 数据类型之set类型

    Redis 的set是string类型的无序集合.set元素最大可以包含(2的32次方-1)个元素.set的是通过hash table实现的,所以添加,删除,查找的复杂度都是O(1).hash tab ...

  2. IIS 7.0、IIS 7.5 和 IIS 8.0 使用的 HTTP 状态代码【转载自微软官方】

    HTTP 状态代码 本部分描述 IIS 7.0.IIS 7.5 和 IIS 8.0 使用的 HTTP 状态代码. 注意 本文不会列出 HTTP 规范中所述的每个可能的 HTTP 状态代码.本文只包括 ...

  3. html5与css3入门知识点精炼

    <meta name = "keywords" content="…………"/>(网页搜索时要输入的关键字) <meta name = &qu ...

  4. 省市区县的sql语句——城市

    /*SQLyog v10.2 MySQL - 5.5.48 : Database - 省市县****************************************************** ...

  5. SQL server基本语法

    此处源于一个基本的SQL Server试题,基本上涵盖了SQL Server的全部基本语法,粘贴在此处,权当分享   --1.  创建TestDB数据库 create database TestDB; ...

  6. css+js+html实现的遮罩

    ——————页面遮罩(CSS+JS+HTML)—————— HTML: <div id="mask" class="mask"></div&g ...

  7. Oracle数据库基础知识总结(一)

    数据库名.实例名.数据库域名.全局数据库名.服务名,这是几个令很多初学者容易混淆的概念.相信很多初学者都与我一样被标题上这些个概念搞得一头雾水. 我们现在就来把它们弄个明白. 一.数据库名 什么是数据 ...

  8. hibernate中的懒加载和急加载

    懒加载(FatchType.LAZY)是Hibernate为提高程序执行效率而提供的一种机制,简单说就是只有正真使用其属性的时候,数据库才会进行查询. 具体的执行过程就是:Hibernate从数据库获 ...

  9. [Jxoi2012]奇怪的道路 题解(From luoguBlog)

    题面 状压好题 1<= n <= 30, 0 <= m <= 30, 1 <= K <= 8 这美妙的范围非状压莫属 理所当然地,0和1代表度的奇偶 dp[i][j ...

  10. esp32(M5STACK) ARDUINO开发环境搭建(ubuntu)

    首先去官网下载arduino https://www.arduino.cc/en/main/software         由于国产链接下载慢的缘故,所以可以采用百度网盘的方式进行下载,具体下载方法 ...