国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

思路清晰!Linux設備驅動子系統之I2C

發布時間:2017-12-2 09:48    發布者:技術小白
1. Overview
2. Data Structure
3. Adapter
4. I2C-core
5. Slave Device

1. Overview
1.1 Definition
·  I2C           Inter-Integrated Circuit
·  SMBUS      System Management Bus, the I2C subset

1.2 Characteristics
·  The amount of data exchanged is small.
·  The required data transfer rate is low.

1.3 Speed
·  Fast speed     400 kbps
·  Full speed      100 kbps
  1.4 Topology

2 Data Structure

理解數據結構對理解整個驅動程序子系統是很重要的。I2C的主要有兩大數據結構,struct i2c_client 和 struct

i2c_adapter。

  2.1 i2c_client

    struct i2c_client {
        unsigned short flags;  /* div., see below  */
        unsigned short addr;  /* chip address */
        char name[I2C_NAME_SIZE];
        struct i2c_adapter *adapter; /* the adapter we sit on */
        struct i2c_driver *driver; /* and our access routines */
        struct device dev;  /* the device structure  */
        int irq;   /* irq issued by device (or -1) */
        char driver_name[KOBJ_NAME_LEN];
        struct list_head list;  /* DEPRECATED */
        struct completion released;
};

struct i2c_client代表一個掛載到i2c總線上的i2c從設備,該設備所需要的數據結構,其中包括
· 該i2c從設備所依附的i2c主設備 struct i2c_adapter *adapter
· 該i2c從設備的驅動程序struct i2c_driver *driver
· 作為i2c從設備所通用的成員變量,比如addr, name等
· 該i2c從設備驅動所特有的數據,依附于dev->driver_data下

2.2 i2c_adapter
     struct i2c_adapter {
        struct module *owner;
        unsigned int id;
        unsigned int class;
        const struct i2c_algorithm *algo; /* the algorithm to access the bus */
        void *algo_data;
        ... ...
     };

struct i2c_adapter代表主芯片所支持的一個i2c主設備,該設備所需要的數據結構,

其中,struct i2c_algorithm *algo是該i2c主設備傳輸數據的一種算法,或者說是在i2c總線上完成主從設備間數

據通信的一種能力。
struct i2c_algorithm {
        int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs, int num);
        int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
                    unsigned short flags, char read_write,
                    u8 command, int size, union i2c_smbus_data * data);
        u32 (*functionality) (struct i2c_adapter *);
    };

接下來,要實現整個i2c子系統的驅動,便圍繞這兩個數據結構展開,其主要步驟可總結為以下三步,
· 實現i2c主設備驅動                (drivers/i2c/bus/*)
· 注冊i2c從設備的i2c_client    (drivers/i2c/i2c-core)
· 實現i2c從設備驅動

3 Adapter
內核目錄drivers/i2c下有兩個文件夾,algorithm和bus,其中bus存放i2c主設備的驅動,主設備驅動完成兩大

任務,
· 提供該i2c主設備與從設備間完成數據通信的能力
· 完成該i2c_adapter和所有已知的i2c_client的注冊

以i2c-pxa.c為例,
  /* drivers/i2c/bus/i2c-pxa.c */
static int __init i2c_adap_pxa_init(void)
{
return platform_driver_register(&i2c_pxa_driver);
}
static struct platform_driver i2c_pxa_driver = {
.probe  = i2c_pxa_probe,
... ...
.id_table = i2c_pxa_id_table,
};
static int i2c_pxa_probe(struct platform_device *dev)
{
struct pxa_i2c *i2c;
  i2c->adap.algo = i2c_pxa_algorithm;             // 提供該i2c主設備與從設備間完成數據通信的能力
  i2c_add_numbered_adapter(&i2c->adap);      // 調用i2c-core.c中的接口函數,完成該i2c_adapter和

i2c_client的注冊
  ... ...
}
static const struct i2c_algorithm i2c_pxa_algorithm = {
.master_xfer = i2c_pxa_xfer,                  // 根據pxa具體芯片的要求,完成i2c數據傳輸
.functionality = i2c_pxa_functionality,
};

4 I2C-core
內核目錄drivers/i2c下的i2c-core.c,顧名思義,是內核為I2C提供的統一系統接口。

看看i2c_add_numbered_adapter做了些什么,
int i2c_add_numbered_adapter(struct i2c_adapter *adap)
{
   ... ...
  status = i2c_register_adapter(adap);
  return status;
}

static int i2c_register_adapter(struct i2c_adapter *adap)
{
   ... ...
  device_register(&adap->dev);     //完成I2C主設備adapter的注冊,即注冊object和發送uevent等
  i2c_scan_static_board_info(adap);      
   ... ...
}

i2c_scan_static_board_info(adap),此函數為整個I2C子系統的核心,它會去遍歷一個由I2C從設備組成的雙向

循環鏈表,并完成所有I2C從設備的i2c_client的注冊,具體過程如下,
static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
struct i2c_devinfo *devinfo;     //已經建立好了的I2C從設備鏈表

list_for_each_entry(devinfo, &__i2c_board_list, list) {
     i2c_new_device(adapter,&devinfo->board_info);
     ... ...
}
}
struct i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
{
   ... ...
   i2c_attach_client(client);
   ... ...
}
int i2c_attach_client(struct i2c_client *client)
{
   ... ...
   device_register(&client->dev);     //完成I2C從設備client的注冊
   ... ...
}

那么,這個I2C從設備組成的雙向循環鏈表,是什么時候通過什么方式建立起來的呢?

以某重力感應設備為例,
/* /arch/arm/mach-pxa/starwood_p1.c */
static void __init saar_init(void)
{
   ... ...
   i2c_register_board_info(0, ARRAY_AND_SIZE(saar_i2c_bma220_info));
   ... ...
}
static struct i2c_board_info saar_i2c_bma220_info[] = {
{
  .driver_name = "bma220",
  .addr  = 0x0B,
  .irq  = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO15)),
},
};
/* drivers/i2c/i2c-boardinfo.c */
int __init i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)
{
   ... ...
  struct i2c_devinfo *devinfo;
  devinfo->board_info = *info;
  list_add_tail(&devinfo->list, &__i2c_board_list);    //將I2C從設備加入該鏈表中
   ... ...
}

所以,在系統初始化的過程中,我們可以通過 i2c_register_board_info,將所需要的I2C從設備加入一個名為

__i2c_board_list雙向循環鏈表,系統在成功加載I2C主設備adapt后,就會對這張鏈表里所有I2C從設備逐一地

完成 i2c_client的注冊。


5 Slave Driver

如果說硬件方面,I2C主設備已經集成在主芯片內,軟件方面,linux也為我們提供了相應的驅動程序,位于

drivers/i2c/bus下,那么接下來I2C從設備驅動就變得容易得多。既然系統加載I2C主設備驅動時已經注冊了

i2c_adapter和i2c_client,那么I2C從設備主要完成三大任務,
· 系統初始化時添加以i2c_board_info為結構的I2C從設備的信息
· 在I2C從設備驅動程序里使用i2c_adapter里所提供的算法,即實現I2C通信。
· 將I2C從設備的特有數據結構掛在到i2c_client.dev->driver_data下。

以重力感應裝置為例,
static int __init BMA220_init(void)
{
return i2c_add_driver(&bma220_driver);
}
static struct i2c_driver bma220_driver = {
.driver = {
  .owner = THIS_MODULE,
  .name = "bma220",
},
.class  = I2C_CLASS_HWMON,
.probe  = bma220_probe,
.remove  = bma220_remove,
};
static int bma220_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct bma220_data *data;      
i2c_check_functionality(client->adapter, I2C_FUNC_I2C)
i2c_smbus_read_word_data(client, 0x00);    // i2c-core提供的接口,利用i2c_adapter的算法實現I2C通信
i2c_set_clientdata(bma220_client, data);      // 將設備的數據結構掛到i2c_client.dev->driver_data下
misc_register(&bma_device);
request_irq(client->irq, bma220_irq_handler, IRQF_TRIGGER_RISING, "bma220", &data->bma220);
bma220_set_en_tt_xyz(0);
bma220_reset_int();
... ...
}

信盈達靠技術打天下
以下課程可免費試聽C語言電子PCBSTM32LinuxFPGA、JAVA、安卓等。
想學習的你和我聯系預約就可以免費聽課了。
宋工企鵝號:35--24-65--90-88   Tel/WX:173--17--95--19--08



本文地址:http://m.qingdxww.cn/thread-520316-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • Dev Tool Bits——使用MPLAB® Discover瀏覽資源
  • Dev Tool Bits——使用條件軟件斷點宏來節省時間和空間
  • Dev Tool Bits——使用DVRT協議查看項目中的數據
  • Dev Tool Bits——使用MPLAB® Data Visualizer進行功率監視
  • 貿澤電子(Mouser)專區
關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 男女做羞羞的视频 | 国产高清视频一区二区 | 久久综合香蕉久久久久久久 | 日本深夜福利19禁在线播放 | 国产精欧美一区二区三区 | 国产成人精品曰本亚洲 | 夜夜骑日日 | 亚洲第一成人影院 | 手机在线播放视频 | 四虎成人4hutv影院 | 久99re视频9在线观看 | www.99色| 婷婷射图 | 99热在线看 | 日本特黄的免费大片视频 | 欧美高清一区二区三 | 免费高清欧美大片在线观看 | 中文字幕一区二区三区免费看 | 性色吧 | 视频国产91 | 色一伦一情一区二区三区 | 高清一区二区三区免费 | 黑人巨大精品欧美一区二区区 | 中文字幕精品一区二区三区在线 | 亚洲天堂久 | 色偷偷www8888 | 亚洲国产日韩在线人高清不卡 | 黄色的网站免费 | 在线国产福利 | 色综合视频| 免费福利网站在线观看 | 免费精品精品国产欧美在线 | 国产精品久久久一区二区三区 | 国产高清在线精品 | 国产精品社区在线观看 | 一色屋免费视频 | 印度最猛性ⅹxxxxx | 含羞草麻豆 | 亚洲污视频 | 国产91av视频| 亚洲日韩视频免费观看 |