4.19作业 驱动开发

一、编程要求

  • 在内[[核中不支持浮点类型打印

  • 将si7006硬件数据读取到内核空间,拷贝到用户空间

  • 在i2c子系统驱动中,需要编写读取温湿度传感器函数

  • 在probe函数中

    • 注册字符设备驱动(分步注册)
    • 自动创建设备节点
  • 通过ioctl函数判断应用层发送命令码,是读取温度的数据还是湿度的数据

  • 编写应用层程序 公式

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/i2c.h>
    #include <linux/fs.h>
    #include <linux/device.h>

    struct i2c_client *gclient;
    unsigned int major = 0;
    #define CNAME "myled"
    struct class *cls;
    struct device *device;

    int myled_open(struct inode *inode, struct file *file)
    {
    printk("%s:%s:%d\n",FILE,func,LINE);
    return 0;
    }

    ssize_t myled_read(struct file *file, char __user *ubuf, size_t size, loff_t *loff)
    {
    printk("%s:%s:%d\n",FILE,func,LINE);
    return 0;
    }

    ssize_t myled_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loff)
    {
    printk("%s:%s:%d\n",FILE,func,LINE);
    return 0;
    }

    int myled_close(struct inode *inode, struct file *file)
    {
    printk("%s:%s:%d\n",FILE,func,LINE);
    return 0;
    }

    //操作方法结构体
    const struct file_operations fops = {
    .open = myled_open,
    .read = myled_read,
    .write = myled_write,
    .release = myled_close,
    };

    //函数功能:读取电子串号和固件版本号的函数
    int read_serial_firmware(unsigned short reg)
    {
    char r_buf[] = {(reg >> 8 & 0xff),reg & 0xff};
    char value;
    int num;
    struct i2c_msg r_msg[2] = {
    [0] = {
    .addr = gclient->addr, //从机地址
    .flags = 0, //写标志位
    .len = 2, //消息长度
    .buf = r_buf, //从reg寄存器中读取数据
    },
    [1] = {
    .addr = gclient->addr, //从机地址
    .flags = 1,//读标志位
    .len = 1, //消息长度
    .buf = &value, //读取到的数据内容
    },
    };
    //发送数据
    num = i2c_transfer(gclient->adapter,r_msg,ARRAY_SIZE(r_msg));
    if(num != ARRAY_SIZE(r_msg))
    {
    printk("i2c transfer is error\n");
    return -EIO;
    }
    return value;
    }

    //当设备驱动层和总线驱动层匹配成功执行probe函数
    int si7006_probe(struct i2c_client *client, const struct i2c_device_id *id)
    {
    int ret;
    gclient = client;
    printk("%s:%s:%d\n",FILE,func,LINE);
    //读取电子串号
    ret = read_serial_firmware(0xFCC9);
    printk("serial(0x06) = %#x\n",ret);
    //读取固件版本号
    ret = read_serial_firmware(0x84B8);
    printk("fireware(0xff/0x20) = %#x\n",ret);

    复制代码
      //读取温湿度传感器协议版本号
      ret = read_serial_firmware(0xE340);
      printk("temperature(0xff/0x20)  = %#x\n",ret);
      ret = read_serial_firmware(0xE540);
      printk("Relative Humidity(0xff/0x20) = %#x\n",ret);
    
      //注册字符设备驱动
      major = register_chrdev(0,CNAME,&fops);
      if(major < 0){
          printk("register chrdev is error\n");
          return -EIO;
      }
          //向上层提交目录信息
      cls = class_create(THIS_MODULE,CNAME);
      if(IS_ERR(cls)){
          return PTR_ERR(cls);
      }
      //向上层提交设备节点信息
      device = device_create(cls,NULL,MKDEV(major,0),NULL,CNAME);
      if(IS_ERR(device)){
          return PTR_ERR(device);
      }
      printk("major = %d\n",major);//打印主设备号的值
    
      //判断读取的是温度还是湿度的数据,此处不会
      if(gclient->flags==1 && gclient->flags)
      {
          ;
      }
    
    
    
    
    
      return 0;

    }

    //当任意一方卸载,执行remove函数
    int si7006_remove(struct i2c_client *client)
    {
    //注销字符设备驱动
    unregister_chrdev(major,CNAME);
    printk("%s:%s:%d\n",FILE,func,LINE);
    return 0;
    }

    const struct of_device_id si7006_tabble[] = {
    {.compatible = "hqyj,si7006",},
    {},//防止数组越界
    };

    //初始化i2c_driver结构体
    struct i2c_driver si7006 ={
    .probe = si7006_probe,
    .remove = si7006_remove,
    .driver = {
    .name = "hello",
    .of_match_table = si7006_tabble,
    }
    };

    module_i2c_driver(si7006);
    MODULE_LICENSE("GPL");

相关推荐
J_liaty14 小时前
RabbitMQ面试题终极指南
开发语言·后端·面试·rabbitmq
maozexijr18 小时前
RabbitMQ Exchange Headers类型存在的意义?
分布式·rabbitmq
独自破碎E18 小时前
RabbitMQ的消息确认机制是怎么工作的?
分布式·rabbitmq
maozexijr20 小时前
注解实现rabbitmq消费者和生产者
分布式·rabbitmq
Java 码农2 天前
RabbitMQ集群部署方案及配置指南09
分布式·rabbitmq
论迹2 天前
RabbitMQ
分布式·rabbitmq
Java 码农2 天前
RabbitMQ集群部署方案及配置指南08--电商业务延迟队列定制化方案
大数据·分布式·rabbitmq
Java 码农2 天前
Spring Boot集成RabbitMQ的各种队列使用案例
spring boot·rabbitmq·java-rabbitmq
vb2008112 天前
Ubuntu 系统下 RabbitMQ 作为 MQTT 代理的配置方案
mqtt·rabbitmq
win x2 天前
RabbitMQ快速上手
分布式·rabbitmq