国产毛片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
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩视频亚洲 | 中文字幕日韩精品麻豆系列 | 青青热久免费精品视频网站 | 亚洲国产日韩精品 | 国产一级特黄aa级特黄裸毛片 | 久久99精品久久久久久h | 亚洲精品国产精品乱码不97 | 国产激情自拍视频 | 日本精品影院 | 极品美女在线 | 青青青在线观看视频免费播放 | 99久久香蕉| 天堂在线免费观看 | 这里只有精品99re在线 | 亚洲婷婷六月 | 国产精品视频成人 | 一区二区三区毛片免费 | 欧美日韩视频在线第一区二区三区 | 四虎网站在线播放 | 韩国日本在线观看 | 欧美精品v国产精品v | 综合网插 | 在线视频一区二区日韩国产 | 四虎国产精品视频免费看 | 国产91精品久久久久久 | 人成免费在线视频 | 久久福利影院 | 成年人免费黄色 | 亚洲精品视频在线看 | 国产成人精品福利网站人 | 日韩黄色在线视频 | 欧美男人的天堂 | 欧美一区二区三区免费播放 | 韩国一级毛片在线观看 | 四虎影视国产884a精品亚洲 | 四虎国产精品成人永久免费影视 | 久久国产免费福利资源网站 | 日韩一级在线视频 | 午夜网站免费版在线观看 | 91高端极品外围在线观看 | 亚洲h在线观看 |