一.SD/MMC卡介紹
1.1.什麼是MMC卡
MMC:MMC就是MultiMediaCard的縮寫,即多媒體卡。它是一種非易失性存儲器件,體積小巧(24mm*32mm*1.4mm),容量大,耗電量低,傳輸速度快,廣泛應用於消費類電子產品中。
1.2.什麼是SD卡
SD:SD卡爲Secure Digital Memory Card, 即安全數碼卡。它在MMC的基礎上發展而來,增加了兩個主要特色:SD卡強調數據的安全安全,可以設定所儲存的
使 用權限,防止數據被他人複製;另外一個特色就是傳輸速度比2.11版的MMC卡快。在數據傳輸和物理規範上,SD卡(24mm*32mm*2.1mm,比 MMC卡更厚一點),向前兼容了MMC卡.所有支持SD卡的設備也支持MMC卡。SD卡和2.11版的MMC卡完全兼容。
1.3.什麼是SDIO
SDIO:SDIO是在SD標準上定義了一種外設接口,它和SD卡規範間的一個重要區別是增加了低速標準。在SDIO卡只需要SPI和1位SD傳輸模式。低速卡的目標應用是以最小的硬件開銷支持低速IO能力。
1.4.什麼是MCI
MCI:MCI是Multimedia Card Interface的簡稱,即多媒體卡接口。上述的MMC,SD,SDI卡定義的接口都屬於MCI接口。MCI這個術語在驅動程序中經常使用,很多文件,函數名字都包括”mci”.
1.5.MMC/SD/SDIO卡的區別
二.SD/MMC協議與命令
1.SD/MMC卡相關寄存器
SD卡內部有7個寄存器.其中OCR,CID,CSD和SCR寄存器保存卡的配置信息;RCA寄存器保存着通信過程中卡當前暫時分配的地址(只適合SD模 式);卡狀態(Card Status)和SD狀態(SD Status)寄存器保存着卡的狀態(例如,是否寫成功,通信的CRC校驗是否正確等),這兩個寄存器的內容與通信模式(SD模式或SPI模式)相 關.MMC卡沒有SCR和SD Status寄存器.如下表1所示:
表1 SD卡內部7個寄存器
1.1.OCR寄存器
OCR寄存器保存着SD/MMC卡的供電電允許範圍.如下表2所示:如果OCR寄存器的某位爲1,表示卡支持該位對應的電壓。最後一位表示卡上電後的狀態(是否處於”忙狀態”),如果該位爲0,表示忙,如果爲1,表示處於空閒狀態(MMC/SD協議P60)。
表2 OCR寄存器
1.2.CID寄存器
CID爲一個16個字節的寄存器,該寄存器包含一個獨特的卡標識號。如下表3所示:
表3 CID寄存器
1.3.CSD寄存器
CSD寄存器(卡特殊數據寄存器)包含訪問卡存儲時需要的相關信息。如下表4所示:
表4 CSD寄存器
1.4.SCR寄存器
SCR寄存器提供SD卡的特殊特性信息,其大小爲64位。該寄存器由廠商編程,主機不能對它進行編程。
MMC卡沒有SCR。如下表5所示:
表 5 SCR寄存器
1.5. RCA寄存器
該16位卡地址寄存器保存了在卡識別過程中卡發佈的器件地址。該地址用於在卡識別後主機利用該地址與卡進行通信。該寄存器只有在SD總線模式下才有效。
二. SD卡的引腳圖
三.SD卡的命令
3.1.SD卡的命令格式:
SD卡的指令由6字節(Byte)組成,如下:
Byte1:0 1 x x x x x x(命令號,由指令標誌定義CMD39爲100111即16進制0x27,那麼完整的CMD39第一字節爲01100111,即0x27+0x40)。
Byte2-5:Command Arguments,命令參數,有些命令沒有參數。
Byte6:前7位爲CRC(Cyclic Redundacy Check,循環冗餘校驗)校驗位,最後一位爲停止位0。
3.2. SD卡的命令
SD卡命令共分爲12類,分別爲class0到Class11.
3.2.1. Class0 :(卡的識別、初始化等基本命令集)
CMD0:復位SD 卡。
CMD1:讀OCR寄存器。
CMD9:讀CSD寄存器。
CMD10:讀CID寄存器。
CMD12:停止讀多塊時的數據傳輸。
CMD13:讀 Card_Status 寄存器。
3.2.2.Class2 (讀卡命令集):
CMD16:設置塊的長度。
CMD17:讀單塊。
CMD18:讀多塊,直至主機發送CMD12爲止 。
3.2.3.Class4(寫卡命令集) :
CMD24:寫單塊。
CMD25:寫多塊。
CMD27:寫CSD寄存器 。
3.2.4.Class5 (擦除卡命令集):
CMD32:設置擦除塊的起始地址。
CMD33:設置擦除塊的終止地址。
CMD38: 擦除所選擇的塊。
3.2.5.Class6(寫保護命令集):
CMD28:設置寫保護塊的地址。
CMD29:擦除寫保護塊的地址。
CMD30: Ask the card for the status of the write protection bits
class7:卡的鎖定,解鎖功能命令集。
class8:申請特定命令集 。
class10 -11 :保留。
3.3.SD卡的工作流程
首先看下脫離操作系統如何在ARM處理器上實現SD卡的讀寫。過程可以分爲3個大的步驟:初始化sd卡、寫sd卡、讀sd卡。
3.3.1.工作條件檢測
卡在識別模式下的命令流程如圖3.1所示(英文版見標準SD卡協議P24)
圖3.1 卡在識別模式下的命令流程
1)在主機和SD卡進行任何通信之前,主機不知道SD卡支持的工作電壓範圍,卡也不知道是否支持主機當前提供的電壓。因此主機首先使用默認的電壓發送一條reset指令(CMD0)。
2)爲了驗證SD卡的接口操作狀態,主機發送SEND_IF_COND(CMD8),用於取得SD卡支持工 作的電壓範圍數據。SD卡通過檢測CMD8的參數部分來檢查主機使用的工作電壓,主機通過分析回傳的CMD8參數部分來校驗SD卡是否可以在所給電壓下工 作,如果SD卡可以在指定電壓下工作,則它回送CMD8的命令響應字 。如果不支持所給電壓,則SD卡不會給出任何響應信息,並繼續處於IDLE狀態。
3)在發送ACMD41命令初始化高容量的SD卡前,需要強制發送CMD8命令。強制低電壓主機在發送CMD8前發送ACMD41,萬一雙重電壓SD卡沒有收到CMD8命令且工作在高電壓狀態,在這種情況下,低電壓主機不能不發送CMD8命令給卡,則收到ACMD41後進
入無活動狀態。
4)SD_SEND_OP_COND(ACMD)命令是爲SD卡主機識別卡或者電壓不匹配時拒絕卡的機制設計的。主機發送命令操作數代表要求的電壓窗口大小。如果SD卡在所給的範圍內不能實現數據傳輸,將放棄下一步的總線操作而進入無活動。操作狀態寄存器也將被定義。
5)在主機發出復位命令(CMD0)後,主機將先發送CMD8再發送ACMD41命令重新初始化SD卡。
3.3.2.卡的初始化和識別處理
當總線被激合後,主機就開始卡的初始化和識別3處理。初始化處理設置它的操作狀態和是設置OCR中的HCS比特命令 SD_SEND_OP_COND(ACMD41)開始。HCS比特位被設置爲1表示主機支持高容量SD卡。HCS被設置爲0表示主機不支持高容量SD卡。
卡的初始化和識別流程見圖3.2
圖 3.2卡的初始化和識別流程
3.3.3.數據傳輸模式
卡在識別模式結束後,主機時鐘fpp(數據傳輸時鐘頻率)將保存爲fod(卡識別模式下的時鐘),由於有些卡對操作時鐘有限制。主機必須發送 SEND_CSD(CMD9)來獲得卡規格數據積存器內容,如塊大小,卡容量。廣播命令SET_DSR(CMD4)配置所有識別卡的驅動階段。它對DSR 積存器進行編程以適應應用總線佈局,總線上的卡數目和數據傳輸頻率。
SD卡數據傳輸模式的流程圖(英文版協議P26)如圖3.3所示
圖3.3 SD卡數據傳輸模式的流程圖
1)CMD7命令用來選擇某個SD卡,使其進入Transfer狀態,在指定時間段內,只有一個卡能處於 Transfer狀態。當某個先前被選中的處於Transfer狀態的SD卡接收到CMD7之後,會釋放與控制器的連接,並進入Stand-by態。當 CMD7使用保留地址0x0000時,所有的SD卡都會進入Stand-by狀態 。
2)所有的數據讀命令都可以被停止命令(CMD12)在任意時刻終止。數據傳輸會終止,SD卡返回Transfer狀態。讀命令有:塊讀操作(CMD17)、多塊讀操作(CMD18)、發送寫保護(CMD30)、發送scr(ACMD51)以及讀模式下的普通命令
(CMD56)。
3)所有的數據寫命令都可以被停止命令(CMD12)在任意時刻終止。寫命令也會在取消選擇命令(CMD7)之前停止。寫命令有:塊寫操作(CMD24,CMD25)、編程命令(CMD27)、鎖定/解鎖命令(CMD42)以及寫模式下的普通命令(CMD56)。
4)數據傳輸一旦完成,SD卡會退出數據寫狀態,進入Programming狀態(傳輸成功)或者Transfer狀態(傳輸失敗)。
四.Linux中SD/MMC設備驅動流程
4.1.MMC子系統的基本框架
4.1.1.MMC子系統的代碼在kernel/driver/MMC下面,目前MMC子系統支持一些形式的記憶卡:SD,SDIO,MMC。
4.1.2.HOST:針對不同主機的驅動程序,這一部分需要根據自己的特定平臺來完成。
4.1.3.CORE:這是整個MMC的核心層,這部分完成了不同協議和規範的實現,並且爲HOST層的驅動提供接口函數。
4.1.4.CARD:因爲這些記憶卡都是塊設備,當然需要提供塊設備的驅動程序,這部分就是實現了將SD卡如何實現爲塊設備的。
4.1.5.各層之間的關係
4.2.重要的結構體
4.2.1. struct mmc_host 用來描述卡控制器位kernel/include/linux/mmc/host.h下面。
4.2.2.struct mmc_card 用來描述卡位於kernel/include/linux/mmc/card.h下面
4.2.3.struct mmc_driver 用來描述mmc卡驅動在kernel/include/linux/mmc/card.h下面。
4.2.4.struct mmc_host_ops用來描述卡控制器操作集,用於從主機控制器向core層註冊操作函數,從而將core層與具體的主機控制器隔離。也就是說 core要操作主機控制器,就是這個ops當中給的函數指針操作,不能直接調用具體主控制器的函數。
位於kernel/include/linux/mmc/host.h下面。
2.5.struct mmc_ios用於描述了控制器對卡的I/O狀態。位於kernel/include/linux/mmc/host.h下面。
4.2.6.struct mmc_request用於描述讀寫MMC卡的請求,它包括命令,數據以及請求完成後的回調函數。位於kernel/include/linux/mmc/core.h中。
4.2.7.struct mmc_queue是MMC的請求隊列結構,它封裝了通用請求隊列結構,加入了MMC卡相關結構。位於kernel/drivers/mmc/card/queue.h中。
4.2.8.struct mmc_data描述了MMC卡讀寫的數據相關信息,如:請求,操作命令,數據以及狀態等。位於kernel/include/linux/mmc/core.h中。
4.2.9.struct mmc_command描述了MMC卡操作相關命令及數據,狀態信息等。位於kernel/include/linux/mmc/core.h中。
4.3.host,core以及card之間的關聯和處理流程
4.3.1總體的流程如下圖所示
4.3.2.數據.命令的處理流程在代碼分析那裏會仔細分析
4.4:核心任務
MMC/SD卡的驅動整個構架由三個文件組成,其實一共就做了兩件事件:
1).卡的檢測。
2).卡數據的讀取。
4.4.1.卡的檢測中涉及到的函數
tcc_mmc_probe(host/tcc_sdhc.c)
mmc_alloc_host(core/core.c)
mmc_rescan(core/core.c)
mmc_attach_mmc(core/mmc.c)
mmc_init_card(core/mmc.c)
mmc_add_card(core/bus.c)
device_add
mmc_bus_match(core/bus.c)
mmc_bus_probe(core/bus.c)
mmc_blk_probe(card/block.c)
alloc_disk/add_disk
4.4.2.卡中數據讀寫涉及到的函數
mmc_blk_issue_rq(card/block.c)
mmc_wait_for_req(core/core.c)
mmc_start_request(core/core.c)
host->ops->requset(host,mrq)
//tcc_sdhc.c中的tcc_mmc_request