0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核中I2C子系統(tǒng)的整體視圖

FPGA之家 ? 來(lái)源:FPGA之家 ? 作者:FPGA之家 ? 2020-12-31 10:40 ? 次閱讀

本文通過(guò)閱讀內(nèi)核代碼,來(lái)梳理一下I2C子系統(tǒng)的整體視圖。在開發(fā)I2C設(shè)備驅(qū)動(dòng)程序時(shí),往往缺乏對(duì)于系統(tǒng)整體的認(rèn)識(shí),沒(méi)有一個(gè)清晰的思路。所以從高層級(jí)來(lái)分析一下I2C系統(tǒng)的設(shè)計(jì)思路,將有助于設(shè)計(jì)調(diào)試具體的驅(qū)動(dòng)程序。

I2C/SMBUS基礎(chǔ)

I2C是一種芯片間通訊總線技術(shù),最早由Philips設(shè)計(jì)制定。下面內(nèi)容參考I2C 2.1 規(guī)格

半雙工通信方式,通信采用主/從結(jié)構(gòu)

支持多主模式,下圖來(lái)源于I2C 2.1規(guī)格書

4da6518a-4ad5-11eb-8b86-12bb97331649.png

其內(nèi)部電氣實(shí)現(xiàn)采用集電極開路(Open-collector)/漏極開路(open-drain)結(jié)構(gòu)以實(shí)現(xiàn)線與功能,這是總線的實(shí)現(xiàn)基礎(chǔ),多芯片通過(guò)查詢總線狀態(tài)實(shí)現(xiàn)介質(zhì)仲裁以實(shí)現(xiàn)總線控制。

總線信號(hào)由兩線實(shí)現(xiàn),串行時(shí)鐘線SCL(Serial Clock Line)/串行數(shù)據(jù)線SDA(serial Data Line)。

具有三種通訊速率模式:

standard mode:0-100 kbps (bps: bit/s)

Fast mode:0-400 kbps

High-speed mode : 0-3.4Mbps

可支持混速模式

4df96b40-4ad5-11eb-8b86-12bb97331649.png

不同的速率在硬件設(shè)計(jì)時(shí)需要注意信號(hào)的完整性,I2C總線等效電容Cx,主要需要考慮PCB布線,以及上拉電阻選取。

支持7bit/10bit 兩種芯片地址模式

I2C總線電氣特性,這個(gè)非常重要,須嚴(yán)格遵守標(biāo)準(zhǔn)的電氣特性

4e17220c-4ad5-11eb-8b86-12bb97331649.png

4e5734a0-4ad5-11eb-8b86-12bb97331649.png

SMBUS(system management bus) 。大多數(shù)SMBus系統(tǒng)也符合I2C,電氣約束對(duì)于SMBus更為嚴(yán)格,并且它標(biāo)準(zhǔn)化了特定的協(xié)議消息和習(xí)慣用語(yǔ)。支持I2C的控制器也可以支持大多數(shù)SMBus操作,但是SMBus控制器并不支持I2C控制器將支持的所有協(xié)議選項(xiàng)。通過(guò)使用I2C原語(yǔ)或通過(guò)向不支持這些I2C操作的i2c_adapter設(shè)備發(fā)出SMBus命令,可以執(zhí)行各種SMBus協(xié)議操作。

http://smbus.org/

I2C bus(Inter-Integrated Circuit bus) https://www.i2c-bus.org/

I2C 在Linux設(shè)備中的拓?fù)浣Y(jié)構(gòu)

在PC體系中,大體如下拓?fù)洌?/p>

4e84bc54-4ad5-11eb-8b86-12bb97331649.png

PC體系中通過(guò)橋接芯片,擴(kuò)展出PCI,在由PCI擴(kuò)展出I2C適配器,進(jìn)而得到I2C總線,或者橋接芯片直接擴(kuò)展出SMBUS/I2C總線。

嵌入式應(yīng)用中,則可能為:

4ebbbc22-4ad5-11eb-8b86-12bb97331649.png

嵌入式應(yīng)用中,則可能更多的情況是處理器內(nèi)置了I2C/SMBUS總線控制器,直接可得到I2C/SMBUS總線。嵌入式系統(tǒng)中常常會(huì)設(shè)計(jì)很多傳感器掛載在I2C總線上,比如溫度檢測(cè),壓力檢測(cè)等等,又或者諸如電容觸摸屏、電源管理IC等等。

代碼實(shí)現(xiàn)

I2C 的core實(shí)現(xiàn)位于./drivers/i2c/下,實(shí)現(xiàn)了I2C總線設(shè)備以及驅(qū)動(dòng)(適配器)和設(shè)備驅(qū)動(dòng)的注冊(cè)、注銷方法,I2C通信方法algorithm抽象,以及與具體硬件無(wú)關(guān)的代碼

I2C主控制器驅(qū)動(dòng)位于 ./drivers/i2c/busses/,這里主要實(shí)現(xiàn)總線控制器,具體體現(xiàn)為i2c_adapter的實(shí)現(xiàn)。負(fù)責(zé)I2C適配器與從設(shè)備通信。I2C總線驅(qū)動(dòng)由i2c_adapter和i2c_algorithm來(lái)抽象描述。

設(shè)備驅(qū)動(dòng)則分散在./driver/下,這取決于具體的實(shí)現(xiàn),種類繁多。

i2c-dev,大多位于drivers/i2c/i2c-dev.c,這種方法只是封裝了主機(jī)(I2Cmaster,一般是SoC中內(nèi)置的I2C控制器)的I2C基本操作,并且向應(yīng)用層提供相應(yīng)的操作接口,應(yīng)用層代碼需要自己去實(shí)現(xiàn)對(duì)slave的控制和操作,所以這種I2C驅(qū)動(dòng)相當(dāng)于提供給應(yīng)用層可以訪問(wèn)slave硬件設(shè)備的接口,本身并未對(duì)硬件做任何操作,應(yīng)用需要實(shí)現(xiàn)對(duì)硬件的操作。這種模式也稱為應(yīng)用驅(qū)動(dòng)程序。

另一種I2C驅(qū)動(dòng)是將所有的代碼都放在驅(qū)動(dòng)層實(shí)現(xiàn),直接向應(yīng)用層提供最終結(jié)果。應(yīng)用層甚至不需要知道這里面有I2C存在,譬如電容式觸摸屏驅(qū)動(dòng),直接向應(yīng)用層提供/dev/input/event1的操作接口,應(yīng)用層編程的人根本不知道event1中涉及到了I2C。

I2C子系統(tǒng)的主要目的是,對(duì)I2C總線以及設(shè)備利用面向?qū)ο缶幊趟枷雽?shí)現(xiàn)統(tǒng)一建模,以高內(nèi)聚-低耦合的軟件工程思想,實(shí)現(xiàn)一個(gè)分層體系結(jié)構(gòu),以便于內(nèi)核統(tǒng)一管理I2C設(shè)備,從而可以更容易的在linux下實(shí)現(xiàn)I2C設(shè)備以及高可移植。

主要數(shù)據(jù)結(jié)構(gòu)

其內(nèi)部有幾個(gè)關(guān)鍵數(shù)據(jù)結(jié)構(gòu),來(lái)梳理一下:

i2c_client, 用于抽象掛載在I2C總線上的從設(shè)備

i2c_driver,用于驅(qū)動(dòng)掛載在I2C總線的從設(shè)備,也即從設(shè)備的設(shè)備驅(qū)動(dòng)程序

i2c_adapter,用于抽象I2C的主設(shè)備

i2c_algorithm,抽象I2C總線操作接口

i2c_devinfo

該結(jié)構(gòu)體主要用于板級(jí)I2C信息管理

i2c_msg

該結(jié)構(gòu)體主要用于抽象I2C報(bào)文,其內(nèi)容如下:

i2c_timings

主要用于抽象I2C電氣特性,對(duì)于支持設(shè)備樹的系統(tǒng)構(gòu)建而言,主要通過(guò)以下內(nèi)核接口函數(shù),從設(shè)備樹解析電氣特性參數(shù)。

voidi2c_parse_fw_timings(structdevice*dev,structi2c_timings*t,booluse_defaults) { intret; memset(t,0,sizeof(*t)); ret=device_property_read_u32(dev,"clock-frequency",&t->bus_freq_hz); if(ret&&use_defaults) t->bus_freq_hz=100000; ret=device_property_read_u32(dev,"i2c-scl-rising-time-ns",&t->scl_rise_ns); if(ret&&use_defaults){ if(t->bus_freq_hz<=?100000) ???t->scl_rise_ns=1000; elseif(t->bus_freq_hz<=?400000) ???t->scl_rise_ns=300; else t->scl_rise_ns=120; } ret=device_property_read_u32(dev,"i2c-scl-falling-time-ns",&t->scl_fall_ns); if(ret&&use_defaults){ if(t->bus_freq_hz<=?400000) ???t->scl_fall_ns=300; else t->scl_fall_ns=120; } device_property_read_u32(dev,"i2c-scl-internal-delay-ns",&t->scl_int_delay_ns); ret=device_property_read_u32(dev,"i2c-sda-falling-time-ns",&t->sda_fall_ns); if(ret&&use_defaults) t->sda_fall_ns=t->scl_fall_ns; device_property_read_u32(dev,"i2c-sda-hold-time-ns",&t->sda_hold_ns); } EXPORT_SYMBOL_GPL(i2c_parse_fw_timings);

i2c_device_identity

該結(jié)構(gòu)體主要用于抽象I2C 設(shè)備的ID屬性,通過(guò)內(nèi)核接口函數(shù)i2c_get_device_id以獲取設(shè)備ID屬性。

總體框架

概述

Linux I2C編程接口支持總線交互的主端和從端。從高層級(jí)看由兩種驅(qū)動(dòng)程序和兩種設(shè)備構(gòu)成:

適配器設(shè)備與適配器設(shè)備驅(qū)動(dòng)對(duì):I2C 適配器驅(qū)動(dòng)程序用于抽象控制器硬件;它綁定到一個(gè)物理設(shè)備(可能是一個(gè)PCI設(shè)備(PC體系多一些)或platform_device(嵌入式應(yīng)用居多)),并構(gòu)建i2c_adapter實(shí)體以呈現(xiàn)所管理的1個(gè)I2C總線段。

/*ALI1535deviceaddressregisterbits*/ #defineALI1535_RD_ADDR0x01/*Read/WriteBitinDevice*/ /*Addressfield*/ /*->Write=0*/ /*->Read=1*/ #defineALI1535_SMBIO_EN0x04/*SMBI/OSpaceenable*/ /*PCI設(shè)備驅(qū)動(dòng)*/ staticstructpci_driverali1535_driver; staticunsignedlongali1535_smba; staticunsignedshortali1535_offset;

pci-I2C 適配器設(shè)備。如在i2c-ali1535.c中:

platform_device。比如:i2c-s3c2410,如下:

staticconststructplatform_device_ids3c24xx_driver_ids[]={ { .name="s3c2410-i2c", .driver_data=0, },{ .name="s3c2440-i2c", .driver_data=QUIRK_S3C2440, },{ .name="s3c2440-hdmiphy-i2c", .driver_data=QUIRK_S3C2440|QUIRK_HDMIPHY|QUIRK_NO_GPIO, },{}, }; MODULE_DEVICE_TABLE(platform,s3c24xx_driver_ids);

I2C從設(shè)備及設(shè)備驅(qū)動(dòng):每個(gè)I2C總線段上將有一個(gè)由結(jié)構(gòu)i2c_client表示的I2C設(shè)備。這些設(shè)備將被綁定到一個(gè)struct i2c_driver,遵循標(biāo)準(zhǔn)的Linux驅(qū)動(dòng)程序模型。

架構(gòu)

圖片來(lái)源//www.kernel.org/doc/html/latest/i2c/slave-interface.html

5131bd1c-4ad5-11eb-8b86-12bb97331649.png

主端總線驅(qū)動(dòng)職責(zé):

適配器和算法驅(qū)動(dòng)程序,見(jiàn)下面i2c_algorithm結(jié)構(gòu)體詳細(xì)描述

管理I2C總線交互

從端設(shè)備驅(qū)動(dòng)職責(zé):

i2c_client結(jié)構(gòu)體具有設(shè)備的I2C總線地址以及適配器的驅(qū)動(dòng)程序指針

當(dāng)用戶程序發(fā)出文件操作申請(qǐng)I2C事務(wù)時(shí):

i2C_transfer (i2C-core.c) 調(diào)用 adap_algo_master_xfer,數(shù)據(jù)或消息以i2c_msg結(jié)構(gòu)體傳入。

適配器對(duì)硬件I / O地址進(jìn)行讀/寫操作,實(shí)現(xiàn)底層的I2C讀寫設(shè)備操作。

從應(yīng)用程序直到底層的大致交互流程如下:

5152a658-4ad5-11eb-8b86-12bb97331649.png

總結(jié)一下

I2C總線子系統(tǒng)在Linux內(nèi)核中總線模型分為主/從兩端,主端主要有適配器以及適配器驅(qū)動(dòng)負(fù)責(zé)管理總線,從端主要有從設(shè)備抽象以及設(shè)備驅(qū)動(dòng),實(shí)現(xiàn)具體的從設(shè)備應(yīng)用。主端適配器以兩種形式存在于內(nèi)核代碼中,分為PCI橋接適配器或者platform_device形式。從總體理解I2C子系統(tǒng)的驅(qū)動(dòng)模型,以及相應(yīng)主要數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系,將有助于開發(fā)調(diào)試驅(qū)動(dòng)程序,快速定位問(wèn)題。

責(zé)任編輯:xj

原文標(biāo)題:Linux內(nèi)核中I2C總線及設(shè)備長(zhǎng)啥樣?

文章出處:【微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1336

    瀏覽量

    40084
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207912
  • I2C
    I2C
    +關(guān)注

    關(guān)注

    28

    文章

    1452

    瀏覽量

    122253

原文標(biāo)題:Linux內(nèi)核中I2C總線及設(shè)備長(zhǎng)啥樣?

文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    I2C基本指南

    電子發(fā)燒友網(wǎng)站提供《I2C基本指南.pdf》資料免費(fèi)下載
    發(fā)表于 09-10 09:40 ?0次下載
    <b class='flag-5'>I2C</b>基本指南

    I2C轉(zhuǎn)UART子系統(tǒng)設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《I2C轉(zhuǎn)UART子系統(tǒng)設(shè)計(jì).pdf》資料免費(fèi)下載
    發(fā)表于 08-28 10:27 ?0次下載
    <b class='flag-5'>I2C</b>轉(zhuǎn)UART<b class='flag-5'>子系統(tǒng)</b>設(shè)計(jì)

    什么是I2C協(xié)議 I2C總線的控制邏輯

    在實(shí)際使用過(guò)程,I2C比較容易出現(xiàn)的一個(gè)問(wèn)題就是死鎖 ,死鎖在I2C主要表現(xiàn)為:I2C死鎖時(shí)表現(xiàn)為SCL為高,SDA一直為低。
    發(fā)表于 03-12 09:17 ?645次閱讀
    什么是<b class='flag-5'>I2C</b>協(xié)議 <b class='flag-5'>I2C</b>總線的控制邏輯

    GD32 MCU硬件I2C不可靠不如軟件I2C?來(lái)看看紅楓派開發(fā)版的硬件I2C驅(qū)動(dòng)如何做到穩(wěn)得一批

    在一個(gè)評(píng)論,看到網(wǎng)友對(duì)硬件I2C的討論,硬件I2C Busy找不到原因、軟件I2C穩(wěn)得一批。
    的頭像 發(fā)表于 02-23 09:37 ?2250次閱讀
    GD32 MCU硬件<b class='flag-5'>I2C</b>不可靠不如軟件<b class='flag-5'>I2C</b>?來(lái)看看紅楓派開發(fā)版的硬件<b class='flag-5'>I2C</b>驅(qū)動(dòng)如何做到穩(wěn)得一批

    嵌入式學(xué)習(xí)-ElfBoard ELF 1-gpio模擬i2c的方法

    一、驅(qū)動(dòng)配置io模擬i2c驅(qū)動(dòng)在內(nèi)核的路徑:linux-4.1.15-elf1/drivers/i2c/busses/i2c-gpio.c
    發(fā)表于 02-22 15:17

    嵌入式開發(fā)I2C協(xié)議詳解

    I2C協(xié)議中最重要的一點(diǎn)是I2C地址。這個(gè)地址有7位和10位兩種形式。
    的頭像 發(fā)表于 12-05 09:16 ?914次閱讀
    嵌入式開發(fā)<b class='flag-5'>中</b><b class='flag-5'>I2C</b>協(xié)議詳解

    I2C地址跳變問(wèn)題的調(diào)試案例

    引言:I2C作為使用最為廣泛的通訊接口,調(diào)試各類I2C器件,大家應(yīng)該都很輕車熟路。一般對(duì)于外掛電阻配置器件的I2C地址,例如電阻上拉之后,器件的地址就會(huì)固定下來(lái)不再變動(dòng),但是今天給大家分享一個(gè)自己的調(diào)試案例,即
    的頭像 發(fā)表于 11-22 10:51 ?1135次閱讀
    <b class='flag-5'>I2C</b>地址跳變問(wèn)題的調(diào)試案例

    I2C總線信號(hào)與測(cè)試案例(一)

    I2C bus是Inter-IC bus的縮寫,意思是IC器件之間的通訊總線;I2C 總線的特點(diǎn)如下
    的頭像 發(fā)表于 11-20 15:45 ?1506次閱讀
    <b class='flag-5'>I2C</b>總線信號(hào)與測(cè)試案例(一)

    I2C總線—電平轉(zhuǎn)換

    我們先來(lái)看一張圖,熟悉I2C的人一看,這不是I2C的level shifter電路嘛,在Philip的I2C標(biāo)準(zhǔn)里面有,沒(méi)有啥復(fù)雜的。
    的頭像 發(fā)表于 11-02 12:32 ?3833次閱讀
    <b class='flag-5'>I2C</b>總線—電平轉(zhuǎn)換

    I2C總線學(xué)習(xí)筆記

    I2C在小P以前接觸的設(shè)計(jì)中大多只用到400k的速率,EVB的設(shè)計(jì)更經(jīng)常發(fā)現(xiàn)實(shí)現(xiàn)不了就降速到100k。現(xiàn)在突然再看看I2C,發(fā)現(xiàn)原來(lái)還有更高的速率規(guī)范,最高都已經(jīng)到5M了。
    的頭像 發(fā)表于 10-25 14:35 ?1319次閱讀
    <b class='flag-5'>I2C</b>總線學(xué)習(xí)筆記

    I2C總線原理詳解

    I2C兩線式串行總線通訊協(xié)議,它是由飛利浦開發(fā)的,主要用于連接微控制器及其外圍設(shè)備之間,它是由數(shù)據(jù)線SDA和信號(hào)線SCL構(gòu)成的,可發(fā)送和接收數(shù)據(jù)即在MUC和I2C設(shè)備之間,I2CI2C
    發(fā)表于 10-18 17:20 ?1946次閱讀
    <b class='flag-5'>I2C</b>總線原理詳解

    基于ARM處理器S3C2440和Linux統(tǒng)的I2C觸摸屏設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《基于ARM處理器S3C2440和Linux統(tǒng)的I2C觸摸屏設(shè)計(jì).pdf》資料免費(fèi)下載
    發(fā)表于 10-12 10:32 ?0次下載
    基于ARM處理器S3<b class='flag-5'>C</b>2440和<b class='flag-5'>Linux</b>統(tǒng)的<b class='flag-5'>I2C</b>觸摸屏設(shè)計(jì)

    Linux內(nèi)核之LED子系統(tǒng)(一)

    Linux內(nèi)核的LED子系統(tǒng)是一種重要的框架,用于管理和控制設(shè)備上的LED指示燈。在嵌入式系統(tǒng)和物聯(lián)網(wǎng)設(shè)備,LED
    發(fā)表于 10-02 16:53 ?885次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>之LED<b class='flag-5'>子系統(tǒng)</b>(一)

    I2C總線介紹 I2C讀寫時(shí)序介紹

    作為嵌入式開發(fā)人員,無(wú)論是硬件還是軟件工程師,或多或少都會(huì)接觸過(guò)I2C接口的外設(shè)。諸如常用的存儲(chǔ)器EEPROM等皆是I2C接口進(jìn)行通信。
    發(fā)表于 10-01 16:57 ?2122次閱讀
    <b class='flag-5'>I2C</b>總線介紹 <b class='flag-5'>I2C</b>讀寫時(shí)序介紹

    I2C讀寫時(shí)序分析和實(shí)現(xiàn)思路

    上篇推文對(duì)I2C總線的特性進(jìn)行了介紹和描述。對(duì)于開發(fā)者而言,最重要的是編碼I2C的讀寫時(shí)序驅(qū)動(dòng)。本篇推文主要總結(jié)和分享I2C總線主機(jī)端通信的編程實(shí)現(xiàn)思路,并不對(duì)應(yīng)特定MCU的硬件I2C
    發(fā)表于 10-01 16:54 ?1362次閱讀
    <b class='flag-5'>I2C</b>讀寫時(shí)序分析和實(shí)現(xiàn)思路