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");

相关推荐
AC赳赳老秦9 小时前
外文文献精读:DeepSeek翻译并解析顶会论文核心技术要点
前端·flutter·zookeeper·自动化·rabbitmq·prometheus·deepseek
invicinble2 天前
关于Rabbitmq在逻辑主体层面的配置
spring boot·rabbitmq·java-rabbitmq
I_Jln.2 天前
RabbitMQ+SpringAMQP 从入门到精通
分布式·rabbitmq
编程彩机2 天前
互联网大厂Java面试:从Spring Boot到消息队列的技术场景解析
java·spring boot·分布式·面试·kafka·消息队列·rabbitmq
洛阳纸贵2 天前
JAVA高级工程师--RabbitMQ消费者消息限流、超时、死信队列以及若依集成升级
java·rabbitmq·java-rabbitmq
福赖3 天前
《微服务即使通讯中RabbitMQ的作用》
c++·微服务·架构·rabbitmq
h7ml3 天前
基于 RabbitMQ 构建异步化淘客订单处理流水线:解耦、削峰与失败重试
分布式·rabbitmq·ruby
小北方城市网5 天前
Spring Boot Actuator+Prometheus+Grafana 生产级监控体系搭建
java·spring boot·python·rabbitmq·java-rabbitmq·grafana·prometheus
不想写bug呀5 天前
RabbitMQ集群和仲裁队列
rabbitmq·集群·仲裁队列
信创天地5 天前
国产化数据库深度运维:性能调优与故障排查实战指南
运维·数据库·安全·elk·自动化·rabbitmq