嵌入式系統(tǒng)磚家_寄存器讀寫抽象之regmap

目錄:

一、regmap子系統(tǒng)的引入

二绣檬、regmap子系統(tǒng)的內(nèi)部實(shí)現(xiàn)


一足陨、regmap子系統(tǒng)的引入

沒(méi)有regmap子系統(tǒng)之前

在內(nèi)核代碼里,有成千上萬(wàn)的以I2C / SPI為通訊接口的設(shè)備驅(qū)動(dòng)娇未。

以I2C設(shè)備為例

各種I2C接口的設(shè)備驅(qū)動(dòng)都需要通過(guò)I2C子系統(tǒng)的API(i2c_transfer())來(lái)進(jìn)行讀寫寄存器的操作墨缘。在對(duì)應(yīng)的設(shè)備驅(qū)動(dòng)中,I2C讀寫寄存器的操作通常會(huì)被封裝成2個(gè)靜態(tài)函數(shù)忘蟹。

xxx_i2c_read_reg()/xxx_i2c_write_reg():

在沒(méi)有regmap抽象層之前飒房,內(nèi)核里充斥著大量類似的代碼,這些代碼都是多余的媚值,使用I2C總線來(lái)讀寫寄存器的操作是有共性的,應(yīng)該被抽象出來(lái)护糖,形成一份統(tǒng)一的代碼褥芒。驅(qū)動(dòng)開(kāi)發(fā)人員應(yīng)使用該抽象層的API來(lái)讀寫I2C設(shè)備的寄存器,然后把更多的精力放在驅(qū)動(dòng)的邏輯設(shè)計(jì)上嫡良。

同樣的锰扶,沒(méi)有regmap子系統(tǒng)時(shí),spi設(shè)備的寄存器讀寫操作也是散落在各個(gè)spi設(shè)備驅(qū)動(dòng)寝受。

i2c/spi drvier坷牛、i2c/spi device、i2c/spi subsystem之間的關(guān)系如下:

有了regmap子系統(tǒng)后

1. 同樣以I2C設(shè)備為例很澄,先定義struct regmap_config:

struct regmap_config里包含了讀寫芯片寄存器所需所有信息京闰,例如寄存器數(shù)據(jù)位寬、地址位寬等甩苛。

2. 將struct regmap_config注冊(cè)給regmap子系統(tǒng):

得到一個(gè)struct regmap對(duì)象蹂楣,有了這個(gè)對(duì)象,就可以調(diào)用regmap子系統(tǒng)提供的用于讀寫寄存器的API了讯蒲。

3. 使用regmap API讀寫寄存器:

int regmap_read(struct regmap *map, unsigned int reg,

? ? ? ? ? ? ? ? unsigned int *val);

int regmap_write(struct regmap *map, unsigned int reg,

? ? ? ? ? ? ? ? unsigned int val);

int regmap_update_bits(struct regmap *map, unsigned int reg,

? ? ? ? ? ? ? ? unsigned int mask, unsigned int val);

讀寫寄存器的操作已經(jīng)抽象到regmap子系統(tǒng)里了痊土,完整的API位于include/linux/regmap.h。

有了regmap后墨林,i2c/spi drvier赁酝、i2c/spi device、i2c/spi subsystem之間的關(guān)系如下:

我在Linux-4.14內(nèi)核里搜索了一下旭等,目前大約有491個(gè)地方使用了regmap子系統(tǒng)酌呆,將來(lái)可能會(huì)更多。


二辆雾、regmap子系統(tǒng)的內(nèi)部實(shí)現(xiàn)

regmap的拓?fù)浣Y(jié)構(gòu)

在Linux-4.14內(nèi)核中肪笋,regmap分為3層:

源碼文件:

regmap的緩存功能

在regmap子系統(tǒng)里,可以選擇是否使用緩存功能:

regmap內(nèi)支持3 種緩存類型:數(shù)組(flat)、LZO 壓縮和紅黑樹(rbtree)

1) 數(shù)組是最簡(jiǎn)單的緩存類型藤乙,當(dāng)設(shè)備寄存器很少時(shí)猜揪,可以用這種類型來(lái)緩存寄存器值。

2) LZO(Lempel–Ziv–Oberhumer) 是 Linux 中經(jīng)常用到的一種壓縮算法坛梁,Linux 編譯后就會(huì)用這個(gè)算法來(lái)壓縮而姐。這個(gè)算法有 3 個(gè)特性:壓縮快,解壓不需要額外內(nèi)存划咐,壓縮比可以自動(dòng)調(diào)節(jié)拴念。在這里,你可以理解為一個(gè)數(shù)組緩存褐缠,套了一層壓縮政鼠,來(lái)節(jié)約內(nèi)存。當(dāng)設(shè)備寄存器數(shù)量中等時(shí)队魏,可以考慮這種緩存類型公般。

3) 紅黑樹特性就是索引快,所以當(dāng)設(shè)備寄存器數(shù)量比較大胡桨,或者對(duì)寄存器操作延時(shí)要求低時(shí)官帘,就可以用這種緩存類型。

相關(guān)結(jié)構(gòu)體:

struct regmap_config

struct regmap_config里包含了讀寫芯片寄存器所需的所有信息昧谊,它是regmap API里最核心的結(jié)構(gòu)體刽虹。使用regmap子系統(tǒng)的第一步就是填充該結(jié)構(gòu)體。這個(gè)結(jié)構(gòu)體看著龐大呢诬,但是大多數(shù)情況下只要初始化幾個(gè)成員變量就足夠了涌哲,最簡(jiǎn)單和常見(jiàn)的情況類似這樣:

struct regmap_config重要成員變量的含義如下:

struct regmap_bus

該結(jié)構(gòu)體用于描述一種硬件總線的寄存器讀寫操作(a hardware bus for the register map infrastructure)。

regmap_bus并不是面向用戶的API馅巷,也就是說(shuō)使用regmap子系統(tǒng)并不要求一定要了解該結(jié)構(gòu)體膛虫,但是理解該結(jié)構(gòu)體有助于我們了解regmap是如何抽象寄存器讀寫操作的。無(wú)論是i2c還是spi钓猬,在調(diào)用devm_regmap_init_[i2c|spi|...]將struct regmap_config注冊(cè)給regmap子系統(tǒng)后稍刀,在子系統(tǒng)內(nèi)部都會(huì)根據(jù)remap_config里的配置信息找到對(duì)應(yīng)的struct regmap_bus。

比如:

static struct regmap_bus regmap_i2c

[...]

static struct regmap_bus regmap_i2c_smbus_i2c_block

static struct regmap_bus regmap_spi

static struct regmap_bus regmap_spmi_base

[...]

有了適配芯片的 regmap_config 和 regmap_bus敞曹,regmap子系統(tǒng)就有了讀寫該芯片寄存器的能力账月,然后就會(huì)返回一個(gè)struct regmap供設(shè)備驅(qū)動(dòng)來(lái)使用了,struct regmap類似一個(gè)大管家澳迫,包含了所有信息局齿,負(fù)責(zé)統(tǒng)籌一切。

struct regmap_bus重要成員變量的含義如下:

定義一個(gè)regmap_bus結(jié)構(gòu)體時(shí)不需要初始化其所有成員變量橄登,例如某些 i2c 芯片的寄存器是16bit(2Byte)的抓歼,其使用的regmap_bus如下:

常用的regmap API

regmap提供出來(lái)的讀寫寄存器的API非常多讥此,最常用的3個(gè)API如下:

可以猜測(cè)上述API會(huì)利用struct regmap_config + struct regmap_bus完成寄存器的讀寫操作。

簡(jiǎn)單看下regmap_read()的實(shí)現(xiàn):

regmap_read

? ? struct regmap *map

? ? map->reg_read(context, reg, val);

? ? ? ? _regmap_bus_reg_read

? ? ? ? ? ? map->bus->reg_read


總結(jié)

regmap 是在 Linux 3.1 加入進(jìn)來(lái)的特性谣妻,其最初的目的是減少i2c/spi等設(shè)備驅(qū)動(dòng)里的重復(fù)邏輯萄喳,提供一種通用的接口來(lái)操作芯片內(nèi)寄存器,隨著版本的更迭蹋半,regmap 支持的bus越來(lái)越多他巨,并且除了能做到統(tǒng)一的 寄存器I/O 接口,還可以在驅(qū)動(dòng)和硬件 IC 之間做一層緩存减江,從而能減少底層 I/O 的操作次數(shù)染突。給我的感覺(jué)是:內(nèi)核越來(lái)越強(qiáng)大了,但是學(xué)習(xí)的難度也越來(lái)越大辈灼,前路漫漫啊份企,求老司機(jī)帶路...

你和我各有一個(gè)蘋果,如果我們交換蘋果的話茵休,我們還是只有一個(gè)蘋果薪棒。但當(dāng)你和我各有一個(gè)想法,我們交換想法的話榕莺,我們就都有兩個(gè)想法了。如果你也對(duì)嵌入式系統(tǒng)開(kāi)發(fā)有興趣棵介,并且想和更多人互相交流學(xué)習(xí)的話钉鸯,請(qǐng)關(guān)注我的公眾號(hào):ESexpert,一起來(lái)學(xué)習(xí)吧邮辽,歡迎各種收藏/轉(zhuǎn)發(fā)/批評(píng)唠雕。

?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吨述,隨后出現(xiàn)的幾起案子岩睁,更是在濱河造成了極大的恐慌,老刑警劉巖揣云,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捕儒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡邓夕,警方通過(guò)查閱死者的電腦和手機(jī)刘莹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)焚刚,“玉大人点弯,你說(shuō)我怎么就攤上這事】蠊荆” “怎么了抢肛?”我有些...
    開(kāi)封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵狼钮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我捡絮,道長(zhǎng)熬芜,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任锦援,我火速辦了婚禮猛蔽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灵寺。我一直安慰自己曼库,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布略板。 她就那樣靜靜地躺著毁枯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叮称。 梳的紋絲不亂的頭發(fā)上种玛,一...
    開(kāi)封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音瓤檐,去河邊找鬼赂韵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛挠蛉,可吹牛的內(nèi)容都是我干的祭示。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼谴古,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼质涛!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起掰担,我...
    開(kāi)封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤汇陆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后带饱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毡代,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年纠炮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了月趟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恢口,死狀恐怖孝宗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耕肩,我是刑警寧澤因妇,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布问潭,位于F島的核電站,受9級(jí)特大地震影響婚被,放射性物質(zhì)發(fā)生泄漏狡忙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一址芯、第九天 我趴在偏房一處隱蔽的房頂上張望灾茁。 院中可真熱鬧,春花似錦谷炸、人聲如沸北专。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拓颓。三九已至,卻和暖如春描孟,著一層夾襖步出監(jiān)牢的瞬間驶睦,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工匿醒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留场航,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓廉羔,卻偏偏與公主長(zhǎng)得像旗闽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜜另,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容