Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux I2C 驅動架構概述:總線驅動與裝置驅動協作機制

編輯:Linux 教學

Linux I2C 子系統將驅動分為總線驅動與裝置驅動兩層,實現硬體抽象與複用。本文以 AU1550 處理器為例,詳細說明 i2c_adapter/i2c_algorithm 總線層實作、i2c_driver/i2c_client 裝置層實作、掃描匹配機制、i2c_master_send/recv 通訊介面,並提供完整程式碼範本。

一、架構總覽

  • 總線驅動:提供特定控制器的讀寫方法,被動等待裝置驅動呼叫
  • 裝置驅動:透過總線驅動介面與具體晶片通訊,屏蔽控制器差異

二、總線驅動實作

1. i2c_adapter 定義


static struct i2c_adapter pb1550_board_adapter = {
    .name          = "pb1550 adapter",
    .id            = I2C_HW_AU1550_PSC,
    .algo          = NULL,  // 稍後指定
    .algo_data     = &pb1550_i2c_info,
    .inc_use       = pb1550_inc_use,
    .dec_use       = pb1550_dec_use,
    .client_register   = pb1550_reg,
    .client_unregister = pb1550_unreg,
    .client_count      = 0,
};

2. i2c_algorithm 定義(核心傳輸邏輯)


static struct i2c_algorithm au1550_algo = {
    .name         = "Au1550 algorithm",
    .id           = I2C_ALGO_AU1550,
    .master_xfer  = au1550_xfer,   // 核心收發函數
    .functionality = au1550_func,  // 功能位圖
};

3. 關聯與註冊


pb1550_board_adapter.algo = &au1550_algo;
i2c_add_adapter(&pb1550_board_adapter);

三、裝置驅動實作

1. i2c_driver 定義


static struct i2c_driver driver = {
    .name           = "i2c TV tuner driver",
    .id             = I2C_DRIVERID_TUNER,
    .flags          = I2C_DF_NOTIFY,
    .attach_adapter = tuner_probe,    // 掃描入口
    .detach_client  = tuner_detach,
    .command        = tuner_command,
};
i2c_add_driver(&driver);

2. 掃描與匹配


static int tuner_probe(struct i2c_adapter *adap) {
    return i2c_probe(adap, &addr_data, tuner_attach);
}

i2c_probe() 遍歷位址清單,對每個位址呼叫 tuner_attach()。

3. 建立 i2c_client(綁定三方關係)


struct i2c_client *new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
new_client->addr    = address;      // 裝置位址
new_client->adapter = adapter;      // 所屬總線
new_client->driver  = &driver;      // 綁定驅動
err = i2c_attach_client(new_client);

i2c_client 將「適配器 + 位址 + 驅動」三方綁定,代表一個具體裝置實例。

四、資料收發介面


extern int i2c_master_send(struct i2c_client *, const char *, int);
extern int i2c_master_recv(struct i2c_client *, char *, int);
  • 參數:client 指定裝置、緩衝區、長度
  • 回傳:實際傳輸位元組數
  • 複雜傳輸可用 i2c_transfer() 支援多訊息原子傳輸

五、關鍵特性

  • 一條總線可掛多種裝置
  • 一個裝置驅動可服務多條總線上的同類裝置
  • 總線驅動可共用演算法(i2c_algorithm)
  • 用戶空間可透過 /dev/i2c-N 直接存取(i2c-dev.c)

六、移植建議

將既有裸機 I2C 驅動移植到 Linux,核心工作是:

  1. 實作總線驅動的 master_xfer(對應原 I2C_Start/Write/Read/Stop)
  2. 將裝置驅動的收發呼叫改為 i2c_master_send/recv
  3. 其餘邏輯(初始化序列、暫存器定義)基本不變
Copyright © Windows教程網 All Rights Reserved