您的位置:首页 > 运维架构 > Linux

linux i2c驱动开发

2014-07-22 08:29 435 查看
        网上介绍i2c总线的资料比较多,对于i2c基础这里就不细谈了。对于初入门的linux驱动工程师还是有些困难,此文章主要介绍了i2c子系统的数据处理流程,以及编写过程。相对于其他参考,该文档减少了长篇文字(枯燥),以图文和源代码的方式来进行介绍。好了废话不多说,让我们一起进入正文,下面是参考一些网上大神的资料,以及自己的分析方式:

一、linux   i2c驱动框架:



         对linux驱动框架分析时,框架 ——》 结构体  ——》 框架  ——》源代码分析;
        目前多数主控芯片都含有i2c控制器,因此驱动开发工程师编写驱动时需要将对应的gpio接口配置成i2c功能无需过分关注时钟,只需要按照芯片要求的格式进行读写操                 作,linux 中i2c驱动也提供了具体的读写接口;(是不是感觉i2c驱动简单很多了^_^)
二、 i2c驱动编写
经过以上分析可以得知linux i2c驱动需要 驱动开发工程师实现 i2c-driver 和  i2c-client;
1、 需要再开发板的扳文件中(board-xxx.c)中 i2c_board_info中添加相应的硬件信息,然后内核会帮你注册一个i2c_device设备;
               例:static struct i2c_board_info i2c_info[] = {
               {
             I2C_BOARD_INFO("dm365evm_keys", 0x25),        //0x25,0x50,0x18均为i2c从设备地址一般为8位,不带读写标识
              },
              {
            I2C_BOARD_INFO("24c256", 0x50),
            .platform_data= &eeprom_info,
              },
             {
            I2C_BOARD_INFO("tlv320aic3x", 0x18),
              },
                     };
               i2c_board_info主要用于构建信息表来列出存在的i2c设备,用于增长i2c驱动模块的驱动树,对于主板,会调用i2c_new_device()创建client设备
2、其中i2c-driver中主要是  i2c_driver 注册,注销,以及 file_operations函数的实现。
3、i2c驱动中最重要的为次设备的读写操作:(引用http://blog.csdn.net/zclongembedded/article/details/8255977)
      i2c-core.c中提供了  i2c_master_send   i2c_master_recv 和 i2c_transfer 接口与i2c从设备进行数据交互,最好对i2c_transfer进行封装使用,以提高代码移植性,通用性;
      以上三个函数本身不具备驱动物理硬件完成消息传递的功能,它只是寻找i2c_adapter对应的i2c_algorithm,并使用i2c_algorithm的master_xfer()函数真正驱动硬件函数;         (http://tscsh.blog.163.com/blog/static/2003201032013519111134879/)
     static ssize_t yyy_write(struct file* file,char * buf,size_t count,loff_t off)              调用过程:
             {
                    struct i2c_client* client = (struct i2c_client*)file->private_data;         app:     write
                     i2c_msg   msg[1];                                                                                            ↓
                     char* tmp = kmalloc(count,GFP_KERNEL);                                i2c设备驱动文件接口 xxx_write()      
                     int ret;                                                                                                                  ↓     
          
                     if(NULL == tmp)                                                                                        i2c核心 i2c_transfer()
                                return -ENOMEM;                                                                                  ↓  
                     if(copy_from_user(tmp,buf,count))                                                      i2c总线驱动 master_xfer()   
                    
                     {
                           kfree(tmp);
                           return -EFAULT;
                     }
                    msg[0].addr = client->addr;    //地址
                    msg[0].flags=0;                         //写
                    msg[0].len = count;                   //要写的字节
                    msg[0].buf = tmp;                    // 要写的数据
                    ret = i2c_transfer(client->adapter,msg,1);
                    return (1 == ret)? count: ret; 
              }
  注:i2c写设备经历过程 1)在字符设备驱动中构造i2c_msg; 2)调用i2c_transfer将i2c_msg传送给i2c核心;3)i2c_transfer找到对应的algorithm通信方法函数                         master_xfer 最终完成i2c_msg消息的处理
                    对内容有异议者希望不吝指教;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息