【Z-turn Board试用体验】+ Zynq linux的I2C驱动学习笔记(四) - 问答 - 电子技术论坛 - 最好最受欢迎电子论坛!

【Z-turn Board试用体验】+ Zynq linux的I2C驱动学习笔记(四)

中科院 ( 楼主 ) 2015-6-24 20:23:36  只看该作者 倒序浏览
本帖最后由 中科院 于 2015-6-24 20:29 编辑


大家可以先看看这两张图




在linux系统下编写I2C驱动,目前主要有两种方法一种是把I2C设备当作一个普通的字符设备来处理另一种是利用linux下I2C驱动体系结构来完成。下面比较下这两种方法:
  第一种方法:
    优点:思路比较直接,不需要花很多时间去了解linux中复杂的I2C子系统的操作方法。
    缺点
      要求工程师不仅要对I2C设备的操作熟悉,而且要熟悉I2C的适配器(I2C控制器)操作。
       要求工程师对I2C的设备器及I2C的设备操作方法都比较熟悉,最重要的是写出的程序可以移植性差。
       对内核的资源无法直接使用,因为内核提供的所有I2C设备器以及设备驱动都是基于I2C子系统的格式。

  第一种方法的优点就是第二种方法的缺点,
  第一种方法的缺点就是第二种方法的优点。

接着我们上一个帖子谈,有了上面两张图,就显得更加清晰:
  1. static int myir_stlm75x_probe(struct i2c_client *client,
  2.                      const struct i2c_device_id *id)
  3. {
  4.         int ret = 0;
  5.         struct myir_stlm75x_data *pdata = NULL;
  6.         
  7.         printk(KERN_ALERT "%s()n", __func__);
  8.         
  9.         pdata = kmalloc(sizeof(struct myir_stlm75x_data), GFP_KERNEL);
  10.         if(!pdata) {
  11.                 printk(KERN_ERR "No memory!n");
  12.                 return -ENOMEM;
  13.         }
  14.         memset(pdata, 0, sizeof(struct myir_stlm75x_data));

  15.         pdata->client = client;
  16.         
  17.         /* Init class */
  18.         mutex_init(&pdata->mutex);
  19.         pdata->class.name = DEV_NAME;
  20.         pdata->class.owner = THIS_MODULE;
  21.         pdata->class.class_attrs = myir_stlm75x_class_attrs;
  22.         ret = class_register(&pdata->class);
  23.         if(ret) {
  24.                 printk(KERN_ERR "class_register failed!n");
  25.                 goto class_register_fail;
  26.         }
  27.         i2c_set_clientdata(client, pdata);
  28.         //将设备的数据结构挂到i2c_client.dev->p->driver_data下
  29.         printk(KERN_ALERT "%s driver initialized successfully!n", DEV_NAME);
  30.         return 0;

  31. class_register_fail:
  32.         
  33.         return ret;
  34. }
复制代码
  1. /* Attributes declaration: Here I have declared only one attribute attr1 */
  2. static struct class_attribute myir_stlm75x_class_attrs[] = {
  3.         __ATTR(value_degree, S_IRUGO | S_IWUSR , myir_stlm75x_show, NULL), //use macro for permission
  4.         __ATTR_NULL
  5. };
复制代码

不过有一点本人还是不太理解,Linux早就提供了对于LM75设备的支持,而且我看了Z-TURN上面的datasheet,感觉可以不必要写这额外的一个驱动的?不过Kevin Su 真的是没有多余的代码。我一直感觉,自己写代码要比读别人的代码容易,读他人的代码又是太多不好,太少也无法读,AI领域的代码就是一个很好的例子。

不多说了。读取温度的代码就容易多了:
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include

  6. #define TEMP_FILE        "/sys/class/myir-stlm75x/value_degree"

  7. #define ERR_MSG(fmt, args...)        fprintf(stderr, fmt, ##args)
  8. #define DBG_MSG(fmt, args...)        fprintf(stdout, fmt, ##args)

  9. #define READ_DELAY_US        (100*1000) /* 100 ms */

  10. int main(int argc, const char *argv[])
  11. {
  12.         int ret = -1, fd = -1;
  13.         char degree_str[64] = {0};
  14.         
  15.         /* Open device */
  16.         fd = open(TEMP_FILE, O_RDONLY);
  17.         if ( fd < 0) {
  18.                 ERR_MSG("open %s failed!n", TEMP_FILE);
  19.                 return fd;
  20.         }
  21.         
  22.         /* endless loop to read temperature */
  23.         for (;;) {
  24.                 /* Set the read/write pos to the beginning */
  25.                 lseek(fd, 0, SEEK_SET);
复制代码

这里就不多说了。其中3轴加速度计等等的I2C通信设备也是类似的操作过程,



把它作为一个字符文件就可以了。
板卡上面的I2C设备的学习笔记,记录过程就到此,接下来我会转战与PL通信的部分



1个回复

party帅 发表于 2016-12-23 14:50:20
向你学习
回复 1

举报 使用道具

您需要登录后才可以回帖 登录 | 注册

本版积分规则


关闭

站长推荐上一条 /6 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 湘ICP备2023018690号 )

GMT+8, 2024-7-27 21:27 , Processed in 0.531652 second(s), Total 40, Slave 30 queries .

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表