SDIO架構初解2

2021-06-22 14:44:09 字數 3117 閱讀 9698

謹以此文紀念過往的歲月

以sdio為例其會採用mmc_attach_sdio來實現驅動和裝置的匹配,其本質還是根據sdio_bus的匹配規則來實現匹配。在mmc_attach_sdio中首先是mmc匹配乙個bus,即採用何種bus來進行mmc bus來處理host。在這裡需要理解一點就是在sdio中,對於sd卡儲存器mmc為實體裝置,而對於非sd卡儲存器,如sdio介面的裝置,則mmc則表徵為bus,這個比較重要。除了mmc bus外還存在sdio_bus。

int mmc_attach_sdio(struct mmc_host *host,u32 ocr)

interr;

inti, funcs;

structmmc_card *card;

mmc_attach_bus(host,&mmc_sdio_ops); --host匹配一條mmc bus

card= mmc_alloc_card(host, null); --申請乙個card實體,類似於匯流排裝置。

card->type= mmc_type_sdio;

card->sdio_funcs= funcs;

host->card= card;

for(i = 0;i < funcs;i++) {

sdio_init_func(host->card,i + 1);

mmc_release_host(host);

mmc_add_card(host->card);

for(i = 0;i < funcs;i++) {

sdio_add_func(host->card->sdio_func[i]);      

return0;

比較難以理解的是func,這個東東其實是乙個實體裝置的封裝,可以認為其是乙個裝置。

struct sdio_func *sdio_alloc_func(structmmc_card *card)

structsdio_func *func;

func= kzalloc(sizeof(struct sdio_func), gfp_kernel);

func->card= card;

device_initialize(&func->dev);

func->dev.parent= &card->dev;  --很明顯card裝置為sdio裝置的父裝置。

func->dev.bus= &sdio_bus_type;

func->dev.release= sdio_release_func;

returnfunc;

上面的code一目了然,其就是具體裝置實體的封裝,其bus型別為sdio_bus. sdio_init_func僅僅是初始化乙個裝置,而並沒有register。在sdio_add_func實現裝置的register,同理就是card實體,在mmc_add_card之前並沒有註冊,在mmc_add_card函式中才實現裝置的註冊。

到此裝置註冊也就完成了,其實sdio匯流排在形式上類似於usb bus,為什麼呢?編寫過usb驅動的童鞋們應該知道,編寫usb驅動僅僅是編寫驅動的載入,並沒有具體載入裝置實體,導致很多童鞋的困惑,為什麼沒有裝置的載入,其實在usb裝置插入時,會動態的建立乙個usb裝置實體,在usb裝置實體建立完成後,根據不同裝置id呼叫相匹配的驅動。而sdio裝置裝置也是一樣的。上面的code比較混亂,總是讓人看不出具體的裝置的載入。其實在上面的code中,其中包括了mmc host的驅動。

三.驅動載入

我們還是以sdio驅動為例,註冊乙個sdio驅動會呼叫下面的函式。

int sdio_register_driver(struct sdio_driver*drv)

drv->drv.name= drv->name;

drv->drv.bus= &sdio_bus_type;

returndriver_register(&drv->drv);

其實很好理解sdio_driver其實是driver的封裝,並且該driver的bus為sdio_bus_type。這個裝置的驅動很簡單。那來看sdio_driver結構

struct sdio_driver{

char*name; --驅動名稱

conststruct sdio_device_id *id_table;  --驅動裝置id

int(*probe)(struct sdio_func *, const struct sdio_device_id *);

void(*remove)(struct sdio_func *);

structdevice_driver drv;

id_table很熟悉吧,嘿嘿在usb的驅動中如何將裝置和驅動匹配就是根據這個東西。在sdio中也是根據該id_table來進行裝置和驅動的匹配。

四.驅動和裝置匹配

在介紹了裝置註冊和驅動註冊後,那來看這兩個是怎樣匹配的。記住sdio驅動之上有兩條匯流排乙個mmc bus 乙個是sdio bus。

先來看mmc bus的match

static int mmc_bus_match(struct device *dev,struct device_driver *drv)

return1;

這個很省事,直接就是1.

那在看sdio bus 的match

static int sdio_bus_match(struct device *dev,struct device_driver *drv)

structsdio_func *func = dev_to_sdio_func(dev);

structsdio_driver *sdrv = to_sdio_driver(drv);

if(sdio_match_device(func, sdrv))

return1;

return0;

通過檢視上面的具體code的實現你就會發現就是根據id_table來實現裝置和驅動的匹配。

五.probe

不管在裝置註冊還是驅動註冊時,如果發現存在對應的裝置和驅動則會呼叫對應的驅動。不過記住一點是均會先呼叫mmc bus的probe其次是sdio bus的probe。其實現的過程與platfrom類似,不多加贅述。

六.總結

sdio說白了還是一種匯流排,其本質還是離不開驅動和裝置這兩者,如果有usb驅動的經驗則會很好的理解sdio匯流排的驅動。在linux核心是可以觸類旁通的。

SDIO架構初解2

謹以此文紀念過往的歲月 以sdio為例其會採用mmc attach sdio來實現驅動和裝置的匹配,其本質還是根據sdio bus的匹配規則來實現匹配。在mmc attach sdio中首先是mmc匹配乙個bus,即採用何種bus來進行mmc bus來處理host。在這裡需要理解一點就是在sdio中...

sdio架構初解

一.前言 sd卡的大名是耳熟能詳,但是sdio匯流排確是不為人解,不過說起他的近親spi就知道了。我們這裡主要是理解sdio匯流排,並不去理解spi匯流排。也許大家會畏懼其龐大的 其實我們並不需要詳細理解其具體的實現,我們需要理解其架構。二.主機 host 在linux2.6.28中,在sdhci ...

Rete演算法初解

rete匹配演算法是一種進行大量模式集合和大量物件集合間比較的高效方法,通過這種方法找出所有匹配各個模式的物件。rete演算法以犧牲記憶體換取高速的策略 rete演算法分為兩個部分 規則編譯 rule compilation 執行時執行 runtime execution 規則編譯 功能 如何在pr...