linux i2c驅動開發

        網上介紹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消息的處理

                    對內容有異議者希望不吝指教;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章