日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Linux內(nèi)核i2c子系統(tǒng)驅(qū)動介紹 (linux內(nèi)核i2c子系統(tǒng)驅(qū)動)

I2C(Inter-Integrated Circuit)總線是一種串行數(shù)據(jù)傳輸協(xié)議,被用于連接芯片之間的通信。在Linux內(nèi)核中,i2c子系統(tǒng)驅(qū)動負責(zé)管理I2C總線,允許多個設(shè)備通過同一條總線進行通信。本文將介紹linux內(nèi)核i2c子系統(tǒng)驅(qū)動的相關(guān)知識。

創(chuàng)新互聯(lián)專注于臨澧網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供臨澧營銷型網(wǎng)站建設(shè),臨澧網(wǎng)站制作、臨澧網(wǎng)頁設(shè)計、臨澧網(wǎng)站官網(wǎng)定制、微信小程序開發(fā)服務(wù),打造臨澧網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供臨澧網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

一、i2c子系統(tǒng)驅(qū)動的結(jié)構(gòu)

在Linux內(nèi)核中,i2c子系統(tǒng)驅(qū)動通常包含以下幾個結(jié)構(gòu):

1. i2c_adapter結(jié)構(gòu)體

i2c_adapter結(jié)構(gòu)體描述了一條I2C總線的特性,包括總線地址、時鐘頻率、數(shù)據(jù)傳送方式等。該結(jié)構(gòu)體的定義在i2c.h頭文件中,如下所示:

struct i2c_adapter {

struct module *owner;

const char *name;

u32 class;

u32 nr;

struct bus_type *bus;

u32 algo_data;

struct i2c_algorithm *algo;

void *algo_priv;

struct device dev;

unsigned long algo_data_dma;

unsigned long owndata;

unsigned int timeout;

unsigned int retries;

bool (*unrecoverable)(struct i2c_adapter *, struct i2c_msg *);

int (*setup)(struct i2c_adapter *);

void (*shutdown)(struct i2c_adapter *);

int (*bus_recovery)(struct i2c_adapter *);

void *adapdata;

struct i2c_lock_operations *lock_ops;

const struct of_device_id *of_match_table;

};

2. i2c_algorithm結(jié)構(gòu)體

i2c_algorithm結(jié)構(gòu)體定義了I2C總線中的通信算法,包括數(shù)據(jù)傳輸格式、地址范圍等。該結(jié)構(gòu)體的定義在i2c.h頭文件中,如下所示:

struct i2c_algorithm {

int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,

int num);

int (*bus_xfer)(struct i2c_adapter *adapter, u16 addr,

unsigned short flags, char read_write,

u8 command, int size, union i2c_bus_data *data);

int (*master_recv)(struct i2c_adapter *adap, struct i2c_msg *msgs,

int num);

int (*master_send)(struct i2c_adapter *adap, struct i2c_msg *msgs,

int num);

u32 (*functionality)(struct i2c_adapter *);

struct module *owner;

const char *name;

};

3. i2c_driver結(jié)構(gòu)體

i2c_driver結(jié)構(gòu)體描述了一個i2c設(shè)備的特性,包括設(shè)備類型、ID等信息。該結(jié)構(gòu)體的定義在i2c.h頭文件中,如下所示:

struct i2c_driver {

unsigned int class;

const struct i2c_device_id *id_table;

int (*probe)(struct i2c_client *, const struct i2c_device_id *);

int (*remove)(struct i2c_client *);

void (*shutdown)(struct i2c_client *);

int (*suspend)(struct i2c_client *, pm_message_t state);

int (*resume)(struct i2c_client *);

const struct i2c_device_id *of_match_table;

const struct of_device_id *of_match_table;

struct device_driver driver;

};

4. i2c_client結(jié)構(gòu)體

i2c_client結(jié)構(gòu)體描述了一個具體的i2c設(shè)備,包括設(shè)備地址、設(shè)備類型、驅(qū)動等信息。該結(jié)構(gòu)體的定義在i2c.h頭文件中,如下所示:

struct i2c_client {

int irq;

unsigned short flags;

unsigned short addr;

char name[I2C_NAME_SIZE];

struct device dev;

struct i2c_adapter *adapter;

struct i2c_driver *driver;

void *algo_data;

struct i2c_board_info const *board_info;

};

二、i2c子系統(tǒng)驅(qū)動的通信過程

i2c子系統(tǒng)驅(qū)動的通信過程需要經(jīng)過以下步驟:

1. 注冊i2c_adapter

初次使用I2C總線時,需要先注冊i2c_adapter結(jié)構(gòu)體,告訴內(nèi)核I2C總線的特性。在Linux內(nèi)核中,注冊i2c_adapter結(jié)構(gòu)體可以使用i2c_add_adapter函數(shù)來完成。

2. 注冊i2c_driver

為了能夠與具體的i2c設(shè)備通信,需要先注冊i2c_driver結(jié)構(gòu)體。在Linux內(nèi)核中,注冊i2c_driver結(jié)構(gòu)體可以使用i2c_add_driver函數(shù)來完成。

3. 連接i2c_client設(shè)備

一旦I2C總線被注冊成功,可以使用i2c_new_device函數(shù)連接一個i2c_client設(shè)備。在連接設(shè)備時,需要指定設(shè)備地址、設(shè)備類型等信息。

4. 與設(shè)備通信

當(dāng)i2c_client設(shè)備連接成功后,就可以使用該設(shè)備進行I2C通信了。在Linux內(nèi)核中,I2C數(shù)據(jù)的傳輸通常使用i2c_transfer函數(shù)進行。該函數(shù)需要傳入一個指向i2c_msg結(jié)構(gòu)體的指針,該結(jié)構(gòu)體用于描述數(shù)據(jù)的傳輸信息。

5. 注銷i2c_driver和i2c_adapter

當(dāng)使用完i2c_driver和i2c_adapter之后,需要使用i2c_del_driver和i2c_del_adapter函數(shù)來注銷。

三、i2c子系統(tǒng)驅(qū)動的應(yīng)用場景

i2c子系統(tǒng)驅(qū)動在Linux內(nèi)核中的應(yīng)用廣泛,包括但不限于以下場景:

1. 屏幕顯示

在Linux內(nèi)核中,i2c子系統(tǒng)驅(qū)動可用于控制顯示器的點陣屏幕,比如樹莓派的OLED屏幕等。

2. 觸摸屏

i2c子系統(tǒng)驅(qū)動還可用于連接觸摸屏設(shè)備,實現(xiàn)觸摸控制。

3. 傳感器

i2c子系統(tǒng)驅(qū)動也可以用于連接各種傳感器設(shè)備,如溫度傳感器、氣壓傳感器等。這些設(shè)備通常需要I2C總線進行數(shù)據(jù)傳輸。

i2c子系統(tǒng)驅(qū)動在Linux內(nèi)核中的應(yīng)用范圍廣泛,是連接各種設(shè)備的重要手段。通過對i2c子系統(tǒng)驅(qū)動的深入了解,可以更好地開發(fā)和使用相關(guān)設(shè)備。

相關(guān)問題拓展閱讀:

  • 求教怎么學(xué)習(xí)linux內(nèi)核驅(qū)動
  • 在linux上怎樣增加一個i2c設(shè)備?

求教怎么學(xué)習(xí)linux內(nèi)核驅(qū)動

1. 分享Linux內(nèi)核學(xué)習(xí)和驅(qū)動開發(fā)的經(jīng)驗。

內(nèi)核逗戚學(xué)習(xí)

Linux 內(nèi)核功能越來越完善,如果沒有充裕的時間,深入內(nèi)核并不是很現(xiàn)實。所以建議先讀一本內(nèi)核的書,

之一遍是讀,會讀的很迷糊;之后反省一下,然后再瀏覽一下;可以想象一個 OS 是如何運行的,這樣可以不

陷入 Linux 內(nèi)核的細節(jié);最后可以深入自己感興趣或者需要的那一子系統(tǒng)

推薦 《Linux Kernel Development》

即便是子系統(tǒng),也是很龐大的。一個省力的方式是網(wǎng)上搜一些相關(guān)的文章,便于快速了解這個子系統(tǒng)的運作;

然后結(jié)合代碼,形成自己的認知,最后做一下總結(jié)。如果僅僅是快速了解某一子系統(tǒng)的運作,可以參考一些早期

代碼的注解書籍,再深入的時候看看最新的代碼實現(xiàn)

對內(nèi)核的認知是一個反復(fù)的過程,一開始并不完善,可能需要反復(fù)糾正。不要陷入這種糾錯中;而是以后繼續(xù)

使用和學(xué)習(xí)過程中,發(fā)現(xiàn)了沒有弄清楚的地方再深入,畢竟 Linux 內(nèi)核是不斷變化的

還有一個很好的方式是,從系統(tǒng)調(diào)用入手,現(xiàn)在這方面的數(shù)據(jù)不少,而且對系統(tǒng)調(diào)用的語義都有講解,這樣可以

間接了解 Linux 系統(tǒng)的一些概念。對系統(tǒng)調(diào)用熟悉了,可以根據(jù)系統(tǒng)調(diào)用的執(zhí)行過程,來大體了解內(nèi)核的一個

運作過程;但是跟蹤系統(tǒng)調(diào)用的時候要注意抓主線,現(xiàn)在內(nèi)核系統(tǒng)很復(fù)雜,一些 code path 上可能會涉及多個

子系統(tǒng),可以從名字上猜測它們是干什么的,不需要深入,否則會發(fā)現(xiàn)精力完全被分散掉了

學(xué)習(xí) Linux 內(nèi)核,一個很重要的是抽象的能力,所謂的抽象這里僅僅是指分清接口和接口的實現(xiàn)。因為 Linux

內(nèi)核子系統(tǒng)很多,有很多子系統(tǒng)相互滲透,這樣 code path 看上去很復(fù)雜。閱讀代碼的時候,為了排除干擾,

需要分清哪些是自己需要看的,哪些是其它子系統(tǒng)的接口,對于其它子系統(tǒng)的接口,先當(dāng)作它們功能完善不會

出問題好了,這樣可以關(guān)注重點;打個比方,一個應(yīng)用程序的代碼可能量很大,比如一個 apache 項目,它

包含很多組件,有時候閱讀代碼的時候會看到不同組件的 API,深入看相關(guān)組件實現(xiàn)并不現(xiàn)實,這時候分清主次

對于代碰孝碼的閱讀就很有幫助了,總不能看到了 malloc 就要先把它的實現(xiàn)弄清楚吧,系統(tǒng)調(diào)用多者呢

推薦書籍

OReilly.Linux.System.Programming.2nd.Edition

The.Linux.Programming.Interface

驅(qū)動開發(fā)

一直圍繞服務(wù)器做,接觸的比較多的是網(wǎng)卡驅(qū)動。最開始想著從上到下,好好學(xué)習(xí)協(xié)議棧,后來發(fā)現(xiàn)內(nèi)容太多,

進展太慢。后來參考一些驅(qū)動開發(fā)方面的書籍,把驅(qū)動獨立開,使用內(nèi)核提供的接口,就類似寫應(yīng)用的時候很多

情況下只需要了解系統(tǒng)接口和庫函數(shù)的原型描述而不需要繼續(xù)深入一樣。這樣把自己從內(nèi)核復(fù)雜的實現(xiàn)細節(jié)中解

放出來,可以重點看網(wǎng)卡的特性部分;之后可以再深入了解設(shè)備的運作過程,比如網(wǎng)卡的收發(fā)包在協(xié)議棧中的

位置和運作

個人感覺如果工作中能接觸驅(qū)動開發(fā)更好,否則很多情況下,有的設(shè)備并不常見,比如 Infiniband 卡

現(xiàn)在民用設(shè)備越來越廣泛,可以選擇自己感興山吵陵趣而手頭又容易有的設(shè)備進行研究,比如無線網(wǎng)卡、wifi 等

驅(qū)動開發(fā),一定要先專注一個設(shè)備,從頭到尾熟悉一遍,然后總結(jié)驅(qū)動開發(fā)是怎樣的、驅(qū)動是如何關(guān)聯(lián)到系統(tǒng)中

的、Linux 采用什么樣的分層模式來提供對多種多樣設(shè)備的支持,如類似 VFS 一樣的抽象分層

推薦

linux device driver, 3rd edition

Linux設(shè)備驅(qū)動開發(fā)詳解

2. 您覺得Linux驅(qū)動開發(fā)的難點是什么,有什么好的方法來克服?

Linux 內(nèi)核對各種設(shè)備的驅(qū)動開發(fā)提供了完善的框架支持,對應(yīng)某個驅(qū)動,把對外的接口弄清楚就可以了。打個

比方,一個設(shè)備可能在不同的 OS 上需要支持,比如 FreeBSD/Windows 等,每個 OS 都有自己定義的接口,

設(shè)備的驅(qū)動定義好與這些 OS 接口的連接,剩下的就是設(shè)備本身的特性管理以及驅(qū)動接口中對設(shè)備管理函數(shù)的調(diào)

用了,比如寄存器訪問、配置管理、緩沖區(qū)管理、數(shù)據(jù)收發(fā)等,比較重要的中斷和同步的控制,要避免數(shù)據(jù)處理的

時候的死鎖。

比如網(wǎng)卡驅(qū)動,基本的要求是提供內(nèi)核需要的接口,這樣網(wǎng)卡驅(qū)動才能掛接到系統(tǒng)中,剩下的就是接口需要調(diào)用

網(wǎng)卡驅(qū)動的內(nèi)部函數(shù),來對網(wǎng)卡進行控制、數(shù)據(jù)收發(fā)和管理等

Linux 支持的設(shè)備種類繁多,不可能所有都掌握,某一子系統(tǒng)也只能是熟悉,因為同類設(shè)備還有許多自由的特性。

寫驅(qū)動的步驟可以概括為:

) 閱讀設(shè)備規(guī)范,對設(shè)備的運行機理有所了解

為了減少干擾,不考慮要支持的 OS,獨立與 OS 考慮基本的功能如何實現(xiàn)

) 參考同類設(shè)備在 Linux 內(nèi)核中的驅(qū)動架構(gòu)

) 提供基本的 Linux 設(shè)備驅(qū)動接口和實現(xiàn)設(shè)備的基本功能,比如網(wǎng)卡收發(fā)小數(shù)據(jù)量

) 在性能上逐步提示,比如網(wǎng)卡傳輸?shù)臄?shù)據(jù)量加大、中斷及時處理、避免死鎖等

) 對邊界條件進行完善,網(wǎng)卡上就是對一些特殊大小的數(shù)據(jù)包傳輸完善等

) 對設(shè)備進行更高級控制的支持,比如網(wǎng)卡支持 ethtool 等工具

) 反復(fù)調(diào)試、改進和優(yōu)化

3. Linux內(nèi)核有上百個驅(qū)動子系統(tǒng),你研究過內(nèi)核各種驅(qū)動子系統(tǒng)的共性,層次結(jié)構(gòu)設(shè)計嗎?分享學(xué)習(xí)一個Linux內(nèi)核子系統(tǒng)的經(jīng)驗,例如USB、I2C、HID等driver。

每一個子系統(tǒng)都巨大無比,而且涉及各種硬件規(guī)范,很難去搞明白所有。只能是遇到問題的時候,

能對某一部分深入下去。之前了解過 SCSI 的架構(gòu),最上層的抽象,中間層的橋梁,更底層的設(shè)備

驅(qū)動控制

如果僅僅是做 driver 的工作,可以把精力放在設(shè)備特性上,Linux 內(nèi)核部分只需要了解驅(qū)動

接口和同步、內(nèi)存管理等基本功能

4. 您深入研究過Linux設(shè)備驅(qū)動模型,關(guān)注過Linux內(nèi)核驅(qū)動的設(shè)計思想嗎?

Linux 設(shè)備驅(qū)動模型是從分類的角度來看待設(shè)備,分類是多維的,所以 /sys 下也是多個目錄

另外,設(shè)備驅(qū)動模型給出了系統(tǒng)中設(shè)備布局信息,比如根據(jù)總線地址可以定位對應(yīng)的設(shè)備目錄等

Linux 內(nèi)核驅(qū)動可以都是遵循一個逐層抽象的架構(gòu):

最上層的抽象層便于系統(tǒng)軟件的訪問,

中間層的實現(xiàn)硬件協(xié)議細節(jié),同時提供上下兩層連接的接口,

對于最下層的 driver 來說就是要定義底層驅(qū)動要實現(xiàn)的接口和實際的設(shè)備控制

由于 Linux 內(nèi)核各類驅(qū)動的框架支持,driver 可以更加關(guān)注設(shè)備本身的特性

5. Android系統(tǒng)是基于Linux內(nèi)核的,傳統(tǒng)的Linux驅(qū)動開發(fā)和Android驅(qū)動開發(fā)有什么區(qū)別?

傳統(tǒng)的 Linux 內(nèi)核驅(qū)動開發(fā),只需要定義好 Linux 需要的驅(qū)動接口就好了,之后

專注與設(shè)備本身的特性

而 Android 驅(qū)動開發(fā),需要將設(shè)備操作接口繼續(xù)封裝,提供上層使用的 Java API;

driver 部分可以使用 C 代碼,一些更復(fù)雜的操作可以用 Java 實現(xiàn),然后 driver

提供對復(fù)雜操作的接口支持

一個很重要的方面是功能的分離定義,比如哪些是 driver 實現(xiàn)的,哪些是上層實現(xiàn)的,

它們之間的接口是怎樣的,定義好這些,就可以按照傳統(tǒng) driver 的實現(xiàn)方式來做了;

從某種程度上,可以看作是傳統(tǒng) driver 跟相關(guān) tools 轉(zhuǎn)換成了 Android driver

和上層 Java 接口

1.首先要了解為什么要學(xué)習(xí)內(nèi)核?下圖已表明,如果要從事驅(qū)動開發(fā)或系統(tǒng)研究,就要學(xué)習(xí)內(nèi)核。

2.內(nèi)核的知識就像下面的繩結(jié)一樣,一環(huán)余或攜扣一環(huán),我們要解開它們,就必須要先找到線頭也就是內(nèi)核中的函數(shù)豎伏接口。初學(xué)階段,我們一般不深入的研究內(nèi)核代碼,會使用內(nèi)核的接口函數(shù)就不錯了。

3.下面提供了如何學(xué)習(xí)這些內(nèi)核函數(shù)的方法,就像解繩子一樣

4.學(xué)習(xí)內(nèi)核的四步法則,思維導(dǎo)圖的設(shè)計尤為團清重要,這也是能否學(xué)習(xí)好內(nèi)核的關(guān)鍵

5.語言基礎(chǔ)也需要扎實,所以需要把C語言鞏固鞏固

在linux上怎樣增加一個i2c設(shè)備?

假設(shè)手上有一塊從淘寶上買來的開發(fā)板,我要在開發(fā)板的I2C總線上增加一個從設(shè)備(如at24c08),那么我要怎樣寫這晌答個“I2C設(shè)備驅(qū)動”,讓

應(yīng)用程序可以訪問at24c08呢?

先來看一個最簡單的i2c設(shè)備驅(qū)動:

static struct i2c_board_info at24cxx_info = { //所支持的i2c設(shè)備的列表

I2C_BOARD_INFO(“at24c08”, 0x50), //一項代表一個支持的設(shè)備,它的名字叫做“at24c08”,器件地址是0x50

};

static struct i2c_client *at24cxx_client;

static int at24cxx_dev_init(void)

{

struct i2c_adapter *i2c_adap; //分配一個適配器的指針

i2c_adap = i2c_get_adapter(0); //調(diào)用core層的函數(shù),獲得一個i2c總線。這里我們已經(jīng)知道新增的器件掛接在編號為0的i2c總線上

at24cxx_client = i2c_new_device(i2c_adap, &at24cxx_info); // 把i2c適配器和新增的I2C器件關(guān)聯(lián)起來,這個用了i2c總線0,地址是0x50。這就組成了一個客戶端

at24cxx_client i2c_put_adapter(i2c_adap);

return 0;

}

static void at24cxx_dev_exit(void)

{

i2c_unregister_device(at24cxx_client);

}

module_init(at24cxx_dev_init);

module_exit(at24cxx_dev_exit);

從上面的程序可以看到,寫一個i2c設(shè)備驅(qū)動程序,與寫普通的字符驅(qū)動基本一樣。特別之處是它調(diào)用了i2c的core層的函數(shù),以獲得對i2c總線的控制。因為用的是開發(fā)板,板上的與soc芯片(一般來說就是arm的芯片)i2c總線驅(qū)動一般都做好了,直接調(diào)用core層的函數(shù)就可以控制soc的i2c模塊了。也就是說,寫i2c設(shè)備驅(qū)動不需要關(guān)注arm內(nèi)部的i2c模塊的寄存器,我們需要關(guān)注的是設(shè)備(at24c08)的寄存器以及猛謹高它的datasheet對時序的要求。

其實,添加i2c設(shè)備的方法很靈活。根據(jù)Linux的官方文檔《linux-3.4.2\Documentation\i2c\instantiating-devices》,添加i2c設(shè)備的方法總結(jié)有4種:

1. i2c_register_board_info:根據(jù)總線編號、設(shè)備名字(“at24c08”)、設(shè)備地址(0x50)注冊一個字符驅(qū)動。這種方法最簡單、最粗暴,最貼近平時在開片機上開發(fā)i2c器件的。

2. i2c_new_device:根據(jù)i2c總線的編號,聲明一個i2c設(shè)備:這種方法就是上面例子用的方法。這種方法也簡單,但是需要事先知道器件掛接在哪條總線上。對于設(shè)備,還實現(xiàn)知道了設(shè)備地址0x50,總線適配器也支持名字為“at24c08”的設(shè)備

3. i2c_new_probed_device:

4.從用戶空間實例化一個器件:這個方法相當(dāng)智能快速,如下輸入指令,即可增加一個i2c設(shè)備,同時增加了對應(yīng)的設(shè)備文件。

# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device

根據(jù)英文文檔的標題,添加i2c設(shè)備有稱之為枝尺“i2c設(shè)備的實例化”。

從上述可以知道,在實例化一個i2c設(shè)備之前,除了有對應(yīng)的驅(qū)動支持總線外(這里是總線0),還需要有一個驅(qū)動使用了總線0發(fā)送時序,支持名字為”at24c08″的器件。這個驅(qū)動用總線驅(qū)動的函數(shù),配置了at24c08的寄存器。

linux內(nèi)核i2c子系統(tǒng)驅(qū)動的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于linux內(nèi)核i2c子系統(tǒng)驅(qū)動,Linux內(nèi)核i2c子系統(tǒng)驅(qū)動介紹,求教怎么學(xué)習(xí)linux內(nèi)核驅(qū)動,在linux上怎樣增加一個i2c設(shè)備?的信息別忘了在本站進行查找喔。

成都服務(wù)器托管選創(chuàng)新互聯(lián),先上架開通再付費。
創(chuàng)新互聯(lián)(www.cdcxhl.com)專業(yè)-網(wǎng)站建設(shè),軟件開發(fā)老牌服務(wù)商!微信小程序開發(fā),APP開發(fā),網(wǎng)站制作,網(wǎng)站營銷推廣服務(wù)眾多企業(yè)。電話:028-86922220


網(wǎng)頁名稱:Linux內(nèi)核i2c子系統(tǒng)驅(qū)動介紹 (linux內(nèi)核i2c子系統(tǒng)驅(qū)動)
文章來源:http://www.dlmjj.cn/article/coedgig.html