• linux chrdev字符设备驱动程序示例


    简介

    下面代码是一个linux内核模块,用于实现一个简单的字符设备驱动程序示例。示例代码实现了一个简单的字符设备驱动程序,可以读取和写入内核缓冲区中的数据。

    代码说明

    头文件包含该代码包含了一些Linux内核头文件,这些头文件提供了与Linux内核功能和API相关的定义和声明。

    前面的代码段定义了一些用于内核模块的全局变量,包括一个表示设备打开次数的变量和一个用于存储数据的缓冲区。

    simple_open()函数和simple_release()函数分别用于处理设备的打开和释放操作。在simple_open()函数中,会检查设备是否已经被打开,若已经打开则返回错误码。在simple_release()函数中,会将设备打开次数减1。

    simple_read()函数和simple_write()函数分别用于处理从设备读取数据和向设备写入数据的操作。在simple_read()函数中,会将数据从内核空间拷贝到应用程序空间。在simple_write()函数中,会将数据从应用程序空间拷贝到内核空间。

    代码定义了一个struct file_operations结构体变量simple_fops,用于指定文件操作的回调函数。这些回调函数会在对设备进行读、写、打开、释放等操作时被调用。

    simple_init_module()函数通过调用register_chrdev()函数来注册字符设备,设备号为simple_MAJOR。simple_cleanup_module()函数用于注销字符设备,并在终端打印一条消息。

     代码

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

    头文件

    1. #ifndef _simple_H_
    2. #define _simple_H_
    3. #include /* needed for the _IOW etc stuff used later */
    4. /********************************************************
    5. * Macros to help debugging
    6. ********************************************************/
    7. #undef PDEBUG /* undef it, just in case */
    8. #ifdef simple_DEBUG
    9. #ifdef __KERNEL__
    10. # define PDEBUG(fmt, args...) printk( KERN_DEBUG "DEMO: " fmt, ## args)
    11. #else//usr space
    12. # define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
    13. #endif
    14. #else
    15. # define PDEBUG(fmt, args...) /* not debugging: nothing */
    16. #endif
    17. #undef PDEBUGG
    18. #define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */
    19. //设备号
    20. #define simple_MAJOR 224
    21. //设备结构
    22. struct simple_dev
    23. {
    24. struct cdev cdev; /* Char device structure */
    25. };
    26. //函数申明
    27. ssize_t simple_read(struct file *filp, char __user *buf, size_t count,
    28. loff_t *f_pos);
    29. ssize_t simple_write(struct file *filp, const char __user *buf, size_t count,
    30. loff_t *f_pos);
    31. loff_t simple_llseek(struct file *filp, loff_t off, int whence);
    32. int simple_ioctl(struct inode *inode, struct file *filp,
    33. unsigned int cmd, unsigned long arg);
    34. #endif /* _simple_H_ */

  • 相关阅读:
    Java配置24-gitlab分支管理
    Apache Beam 2.50.0发布,该版本包括改进功能和新功能
    扩散模型实战(十):Stable Diffusion文本条件生成图像大模型
    大数据毕业设计选题推荐-无线网络大数据平台-Hadoop-Spark-Hive
    2-FreeRTOS编码标准、风格指南
    SQL 时间范围和时间粒度
    131.Avro格式数据与在spark中应用
    KubeSphere Namespace 数据删除事故分析与解决全记录
    小程序授权头像昵称改为头像昵称填写能力详解
    在Ubuntu或linux中为coreutils工具包的cp和mv命令添加进度条
  • 原文地址:https://blog.csdn.net/realmardrid/article/details/124546759