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

相关推荐
S-X-S14 小时前
RabbitMQ持久化队列配置修改问题
分布式·rabbitmq
Buring_learn4 天前
springboot使用rabbitmq
开发语言·后端·rabbitmq·ruby
Onlooker1296 天前
RabbitMQ2-简单案例
rabbitmq
m0_748251726 天前
集成RabbitMQ+MQ常用操作
分布式·rabbitmq
大白菜和MySQL7 天前
rabbitmq单机与集群模式的部署
服务器·分布式·rabbitmq
DEARM LINER7 天前
RabbitMQ 架构分析
java·分布式·架构·rabbitmq·ruby
DEARM LINER7 天前
RabbitMQ 分布式高可用
java·spring boot·分布式·rabbitmq
小林想被监督学习7 天前
RabbitMQ 仲裁队列 -- 解决 RabbitMQ 集群数据不同步的问题
linux·分布式·rabbitmq
S-X-S7 天前
RabbitMQ模块新增消息转换器
分布式·rabbitmq
DEARM LINER8 天前
RabbitMQ 死信队列
java·rabbitmq·java-rabbitmq