Linux I2C裝置驅動編寫(一)

2021-07-08 19:31:40 字數 3233 閱讀 9077

在linux驅動中i2c系統中主要包含以下幾個成員:

i2c adapter 即i2c介面卡

i2c driver 某個i2c裝置的裝置驅動,可以以driver理解。

i2c client 某個i2c裝置的裝置宣告,可以以device理解。

是cpu整合或外接的i2c介面卡,用來控制各種i2c從裝置,其驅動需要完成對介面卡的完整描述,最主要的工作是需要完成i2c_algorithm結構體。這個結構體包含了此i2c控制器的資料傳輸具體實現,以及對外上報此裝置所支援的功能型別。i2c_algorithm結構體如下:

struct i2c_algorithm ;
如果乙個i2c介面卡不支援i2c通道,那麼就將master_xfer成員設為null。如果介面卡支援smbus協議,那麼需要去實現smbus_xfer,如果smbus_xfer指標被設為null,那麼當使用smbus協議的時候將會通過i2c通道進行**。master_xfer指向的函式的返回值應該是已經成功處理的訊息數,或者返回負數表示出錯了。functionality指標很簡單,告訴詢問著這個i2c主控器都支援什麼功能。

在核心的drivers/i2c/i2c-stub.c中實現了乙個i2c adapter的例子,其中實現的是更為複雜的smbus。

smbus 與 i2c的區別

通常情況下,i2c和smbus是相容的,但是還是有些微妙的區別的。

時鐘速度對比:

i2csmbus最小無

10khz

最大100khz(標準)400khz(快速模式)2mhz(高速模式)

100khz超時無

35ms

在電氣特性上他們也有所不同,smbus要求的電壓範圍更低。

具體的i2c裝置驅動,如相機、感測器、觸控螢幕、背光控制器常見硬體裝置大多都有或都是通過i2c協議與主機進行資料傳輸、控制。結構體如下:

struct i2c_driver ;

#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) //一般編寫驅動過程中物件常是driver型別,可以通過to_i2c_driver找到其父型別i2c_driver

如同普通裝置的驅動能夠驅動多個裝置一樣,乙個i2c driver也可以對應多個i2c client。

以重力感測器axll34x為例,其實現的i2c驅動為:

static const struct i2c_device_id adxl34x_id = ,  //匹配i2c client名為adxl34x的裝置

}; module_device_table(i2c, adxl34x_id);

static struct i2c_driver adxl34x_driver = ,

.probe = adxl34x_i2c_probe, //組裝裝置匹配時候的匹配動作

.remove = adxl34x_i2c_remove, //組裝裝置移除介面

.id_table = adxl34x_id, //制定匹配裝置列表

}; module_i2c_driver(adxl34x_driver);

這裡要說明一下module_i2c_driver巨集定義(i2c.h):

#define module_i2c_driver(__i2c_driver) \

module_driver(__i2c_driver, i2c_add_driver, \

i2c_del_driver)

#define i2c_add_driver(driver) \

i2c_register_driver(this_module, driver)

module_driver():

#define module_driver(__driver, __register, __unregister, ...) \

static int __init __driver##_init(void) \

\module_init(__driver##_init); \

static void __exit __driver##_exit(void) \

\module_exit(__driver##_exit);

理解上述巨集定義後,將module_i2c_driver(adxl34x_driver)展開就可以得到:

static int __int adxl34x_driver_init(void)

module_init(adxl34x_driver_init);

static void __exit adxl34x_driver_exit(void)

module_exit(adxl34x_driver_exit);

這一句巨集就解決了模組module安裝解除安裝的複雜**。這樣驅動開發者在實現i2c驅動時只要將i2c_driver結構體填充進來就可以了,無需關心裝置的註冊與反註冊過程。

即i2c裝置。i2c裝置的註冊一般在板級**中,在解析例項前還是先熟悉幾個定義:

struct i2c_client ;

#define to_i2c_client(d) container_of(d, struct i2c_client, dev) //通常使用device裝置模型進行操作,可以通過to_i2c_client找到對應client指標

struct i2c_board_info ;

//可以看到,i2c_board_info基本是與i2c_client對應的。

#define i2c_board_info(dev_type, dev_addr) \

.type = dev_type, .addr = (dev_addr)

//通過這個巨集定義可以方便的定義i2c裝置的名稱和從位址(別忘了是7bit的)

下面還是以adxl34x為例:

static struct i2c_board_info i2c0_devices = ,  

, ,

, };...

i2c_register_board_info(0, i2c0_devices, array_size(i2c0_devices));

這樣adxl34x的i2c裝置就被註冊到了系統中,當名字與i2c_driver中的id_table中的成員匹配時就能夠出發probe匹配函式了。

Linux I2C裝置驅動學習

一 i2c 簡介 1 i2c簡介 a 優點 i2c匯流排僅用兩根訊號線 scl sda 就實現了裝置之間的資料互動,極大簡化了對硬體資源和pcb板佈線空間的占用 b 用途 eeprom 實時鐘 小型lcd等裝置與cpu的介面中 2 i2c驅動體系 i2c框架 通用 適應性強 i2c核心 i2c匯流排...

linux I2C裝置驅動例項 EEPROM

開發板 優龍公司的fs2410 核心版本 linux2.6.28.6 開發環境 ubuntu12.04 交叉編譯器 arm none linux gnueabi gcc 4.3.2 目標 在fs2410上驅動eeprom,實現應用層對eeprom的讀寫操作 一 linux2.6.28.6 系統上 i...

LinuxI2C核心 匯流排驅動與裝置驅動

i2c體系結構分為三個部分 i2c核心 匯流排驅動 裝置驅動 i2c核心 i2c核心提供了一組不依賴硬體的介面函式,i2c匯流排驅動和裝置驅動之間依賴於i2c核心作為紐帶 1 增加 刪除i2c adapter int i2c add adapter struct i2c adapter adap i...