日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux I2C核心、总线与设备驱动(一)

發布時間:2023/12/10 linux 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux I2C核心、总线与设备驱动(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本章導讀

I2C總線僅僅使用SCLSDA兩根信號線就實現了設備之間的數據交互,極大地簡化對硬件資源和PCB板布線空間的占用。因此,I2C總線被非常廣泛地應用在EEPROM、實時鐘、小型LCD等設備與CPU的接口中。

Linux定義了系統的I2C驅動體系結構,在Linux系統中,I2C驅動由3部分組成,即I2C核心、I2C總線驅動和I2C設備驅動。這3部分相互協作,形成了非常通用、可適應性很強的I2C框架。
??
本章第1節將對Linux I2C體系結構進行分析,講明3個組成部分各自的功能及相互聯系。第2節將對Linux I2C核心進行分析,解釋i2c-core.c文件的功能和主要函數的實現。第34節將分別詳細介紹I2C總線驅動和I2C設備驅動的編寫方法,給出可供參考的設計模板。第56節將以第34節給出的設計模板為基礎,講解S3C2410 ARM處理器I2C總線驅動及掛接在上的SAA7113H視頻模擬/數字轉換芯片設備驅動的編寫方法。
15.1 Linux I2C
體系結構
Linux
I2C體系結構分為3個組成部分:
?? I2C
核心
I2C
核心提供了I2C總線驅動和設備驅動的注冊、注銷方法,I2C通信方法(即“algorithm”,筆者認為直譯為運算方法并不合適,為免引起誤解, 下文將直接使用“algorithm”)上層的、與具體適配器無關的代碼以及探測設備、檢測設備地址的上層代碼等。
?? I2C
總線驅動
I2C
總線驅動是對I2C硬件體系結構中適配器端的實現,適配器可由CPU控制,甚至直接集成在CPU內部。
I2C
總線驅動主要包含了I2C適配器數據結構i2c_adapterI2C適配器的algorithm數據結構i2c_algorithm和控制I2C適配器產生通信信號的函數。
經由I2C總線驅動的代碼,我們可以控制I2C適配器以主控方式產生開始位、停止位、讀寫周期,以及以從設備方式被讀寫、產生ACK等。
?? I2C
設備驅動
I2C
設備驅動是對I2C硬件體系結構中設備端的實現,設備一般掛接在受CPU控制的I2C適配器上,通過I2C適配器與CPU交換數據。
I2C
設備驅動主要包含了數據結構i2c_driveri2c_client,我們需要根據具體設備實現其中的成員函數。

15.1 Linux I2C體系結構
Linux 2.6內核中,所有的I2C設備都被在sysfs文件系統中顯示,存在于/sys/bus/i2c/目錄,以適配器地址和芯片地址的形式列出,如:
$ tree /sys/bus/i2c/
/sys/bus/i2c/
|-- devices
|?? |-- 0-0048 -> ../../../devices/legacy/i2c-0/0-0048
|?? |-- 0-0049 -> ../../../devices/legacy/i2c-0/0-0049
|?? |-- 0-004a -> ../../../devices/legacy/i2c-0/0-004a
|?? |-- 0-004b -> ../../../devices/legacy/i2c-0/0-004b
|?? |-- 0-004c -> ../../../devices/legacy/i2c-0/0-004c
|?? |-- 0-004d -> ../../../devices/legacy/i2c-0/0-004d
|?? |-- 0-004e -> ../../../devices/legacy/i2c-0/0-004e
|?? `-- 0-004f -> ../../../devices/legacy/i2c-0/0-004f
`-- drivers
??? |-- i2c_adapter
??? `-- lm75
??????? |-- 0-0048 -> ../../../../devices/legacy/i2c-0/0-0048
??????? |-- 0-0049 -> ../../../../devices/legacy/i2c-0/0-0049
??????? |-- 0-004a -> ../../../../devices/legacy/i2c-0/0-004a
??????? |-- 0-004b -> ../../../../devices/legacy/i2c-0/0-004b
??????? |-- 0-004c -> ../../../../devices/legacy/i2c-0/0-004c
??????? |-- 0-004d -> ../../../../devices/legacy/i2c-0/0-004d
??????? |-- 0-004e -> ../../../../devices/legacy/i2c-0/0-004e
??????? `-- 0-004f -> ../../../../devices/legacy/i2c-0/0-004f
Linux內核源代碼中的drivers目錄下包含一個 i2c目錄,而在i2c目錄下又包含如下文件和文件夾:
?? i2c-core.c
這個文件實現了I2C核心的功能以及/proc/bus/i2c*接口。
?? i2c-dev.c
實現了I2C適配器設備文件的功能,每一個I2C適配器都被分配一個設備。通過適配器訪問設備時的主設備號都為89,次設備號為0255。應用程序通過 “i2c-%d” (i2c-0, i2c-1, ..., i2c-10, ...)文件名并使用文件操作接口open()write()read()ioctl()close()等來訪問這個設備。
i2c-dev.c
并沒有針對特定的設備而設計,只是提供了通用的read()write()ioctl()等接口,應用層可以借用這些接口訪問掛接在適配器上的I2C設備的存儲空間或寄存器并控制I2C設備的工作方式。
?? chips
文件夾
這個目錄中包含了一些特定的I2C設備驅動,如Dallas公司的DS1337實時鐘芯片、EPSON公司的RTC8564實時鐘芯片和I2C接口的EEPROM驅動等。
?? busses
文件夾
這個文件中包含了一些I2C總線的驅動,如S3C2410I2C控制器驅動為i2c-s3c2410.c
?? algos
文件夾
實現了一些I2C總線適配器的algorithm
此外,內核中的i2c.h這個頭文件對i2c_driveri2c_clienti2c_adapteri2c_algorithm4個數據結構進行了定義。理解這4個結構體的作用十分關鍵,代碼清單15.115.215.315.4分別給出了它們的定義。
代碼清單15.1 i2c_adapter結構體
1? struct i2c_adapter {
2? ?struct module *owner;/*
所屬模塊*/
3 ?unsigned int id;?? /*algorithm
的類型,定義于i2c-id.h,以I2C_ALGO_開始*/
4 ?unsigned int class;
5 ?struct i2c_algorithm *algo;/*
總線通信方法結構體指針?*/
6 ?void *algo_data;?/* algorithm
數據 */
7 ?int (*client_register)(struct i2c_client *);? /*client
注冊時調用*/
8 ?int (*client_unregister)(struct i2c_client *); /*client
注銷時調用*/
9 ?struct semaphore bus_lock;??? /*
控制并發訪問的自旋鎖*/
10?struct semaphore clist_lock;
11?int timeout;
12?int retries;??? /*
重試次數*/
13?struct device dev;??/*
適配器設備 */
14?struct class_device class_dev;?/*
類設備 */
15?int nr;
16?struct list_head clients;? /* client
鏈表頭*/
17?struct list_head list;
18?char name[I2C_NAME_SIZE];? /*
適配器名稱*/
19?struct completion dev_released;??? /*
用于同步*/
20?struct completion class_dev_released;
21};
代碼清單15.2 i2c_algorithm結構體
1? struct i2c_algorithm {
2? ?int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
3? ??????????????????? int num);? /*i2c
傳輸函數指針*/
4? ?int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,?? /*smbus
傳輸函數指針*/
5? ??????????????????? unsigned short flags, char read_write,
6? ??????????????????? u8 command, int size, union i2c_smbus_data * data);
7? ?int (*slave_send)(struct i2c_adapter *,char*,int);/*
i2c適配器為slave時,發送函數*/
8? ?int (*slave_recv)(struct i2c_adapter *,char*,int); /*
i2c適配器為slave時,接收函數*/
9? ?int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long); /*
類似ioctl*/
10 ?u32 (*functionality) (struct i2c_adapter *);/*
返回適配器支持的功能*/
11 };
上述代碼第4行對應為SMBus傳輸函數指針,SMBus大部分基于I2C總線規范,SMBus不需增加額外引腳。與I2C總線相比,SMBus增加了一些新的功能特性,在訪問時序也有一定的差異。
代碼清單15.3 i2c_driver結構體
1? struct i2c_driver {
2? ?int id;
3? ?unsigned int class;
4? ?int (*attach_adapter)(struct i2c_adapter *); /*
依附i2c_adapter函數指針 */
5? ?int (*detach_adapter)(struct i2c_adapter *); /*
脫離i2c_adapter函數指針*/
6? ?int (*detach_client)(struct i2c_client *);? /*i2c client
脫離函數指針*/
7? ?int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); /*
類似ioctl*/
8? ?struct device_driver driver;??? /*
設備驅動結構體*/
9? ?struct list_head list;???????? /*
鏈表頭*/
10 };
代碼清單15.4 i2c_client結構體
1? struct i2c_client {
2? ?unsigned int flags;??/*
標志 */
3? ?unsigned short addr;???? /*
7位為芯片地址 */
4? ?struct i2c_adapter *adapter;?/*
依附的i2c_adapter*/
5? ?struct i2c_driver *driver;??? /*
依附的i2c_driver */
6? ?int usage_count;???? /*
訪問計數? */
7? ?struct device dev;???? /*
設備結構體?*/
8? ?struct list_head list;?????? /*
鏈表頭 */
9? ?char name[I2C_NAME_SIZE]; /*
設備名稱 */
10 ?struct completion released;?? /*
用于同步 */
11 };
下面分析一下i2c_driveri2c_clienti2c_adapteri2c_algorithm4個數據結構的作用及其盤根錯節的關系。
?? i2c_adapter
i2c_algorithm
i2c_adapter
對應于物理上的一個適配器,而i2c_algorithm對應一套通信方法。一個I2C適配器需要i2c_algorithm中提供的通信函數來控制適配器上產生特定的訪問周期。缺少i2c_algorithmi2c_adapter什么也做不了,因此i2c_adapter中包含其使用的 i2c_algorithm的指針。
i2c_algorithm
中的關鍵函數master_xfer()用于產生I2C訪問周期需要的信號,以i2c_msg(即I2C消息)為單位。i2c_msg結構體也非常關鍵,代碼清單15.5給出了它的定義。
代碼清單15.5 i2c_msg結構體
1 struct i2c_msg {
2 ?__u16 addr;?/*
設備地址*/
3? ?__u16 flags;?/*
標志 */?
4? ?__u16 len;??/*
消息長度*/
5? ?__u8 *buf;??/*
消息數據*/
6 };
?? i2c_driver
i2c_client
i2c_driver
對應一套驅動方法,是純粹的用于輔助作用的數據結構,它不對應于任何的物理實體。i2c_client對應于真實的物理設備,每個I2C設備都需要一個i2c_client來描述。i2c_client一般被包含在i2c字符設備的私有信息結構體中。
i2c_driver
i2c_client發生關聯的時刻在i2c_driverattach_adapter()函數被運行時。attach_adapter()會探測物理設備,當確定一個client存在時,把該client使用的i2c_client數據結構的adapter指針指向對應的i2c_adapterdriver指針指向該i2c_driver,并會調用i2c_adapterclient_register()函數。相反的過程發生在 i2c_driver detach_client()函數被調用的時候。
?? i2c_adpater
i2c_client
i2c_adpater
i2c_client的關系與I2C硬件體系中適配器和設備的關系一致,即i2c_client依附于i2c_adpater。由于一個適配器上可以連接多個I2C設備,所以一個i2c_adpater也可以被多個i2c_client依附,i2c_adpater中包括依附于它的i2c_client 的鏈表。
假設I2C總線適配器xxx上有兩個使用相同驅動程序的yyy I2C設備,在打開該I2C總線的設備結點后相關數據結構之間的邏輯組織關系將如圖15.2所示。


15.2 I2C驅動各數據結構關系

總結

以上是生活随笔為你收集整理的Linux I2C核心、总线与设备驱动(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。