[轉]http://www.wowotech.net/basic_tech/mmc_sd_sdio_intro.html
1. 前言
熟悉Linux kernel的人都知道,kernel使用MMC subsystem統一管理MMC、SD、SDIO等設備,為什么呢?到底什么是MMC?SD和SDIO又是什么?為什么可以用MMC統稱呢?
在分析Linux kernel的MMC subsystem之前,有必要先介紹一些概念,以便對MMC/SD/SDIO有一個大致的了解,這就是本文的目的。
2. 基本概念
MMC是MultiMediaCard的簡稱,從本質上看,它是一種用於固態非易失性存儲的內存卡(memory card)規范[1],定義了諸如卡的形態、尺寸、容量、電氣信號、和主機之間的通信協議等方方面面的內容。
從1997年MMC規范發布至今,基於不同的考量(物理尺寸、電壓范圍、管腳數量、最大容量、數據位寬、clock頻率、安全特性、是否支持SPI mode、是否支持DDR mode、等等),進化出了MMC、SD、microSD、SDIO、eMMC等不同的規范(如下面圖片1所示)。雖然亂花迷人,其本質終究還是一樣的,絲毫未變,這就是Linux kernel將它們統稱為MMC的原因。
圖片1 MMC/SD/SDIO evolution
關於該圖片,這里強調幾點(其它的,大家可參考[1][2],不再詳細介紹):
MMC、SD、SDIO的技術本質是一樣的(使用相同的總線規范,等等),都是從MMC規范演化而來;
MMC強調的是多媒體存儲(MM,MultiMedia);
SD強調的是安全和數據保護(S,Secure);
SDIO是從SD演化出來的,強調的是接口(IO,Input/Output),不再關注另一端的具體形態(可以是WIFI設備、Bluetooth設備、GPS等等)。
3. 規范簡介
MMC分別從卡(Card Concept)、總線(Bus Concept)以及控制器(Host Controller)三個方面,定義MMC system的行為,如下面圖片2所示:
圖片2 mmc_sd_sdio_hw_block
不同崗位的工程師,可以根據自己的工作性質,重點理解某一部分的規范,下面從嵌入式軟件工程師的視角,簡單的介紹一下。
3.1 卡的規范
卡的規范主要規定卡的形狀、物理尺寸、管腳,內部block組成、寄存器等等,以eMMC為例[3]:
圖片3 Card Concept(eMMC)
1)有關形狀、尺寸的內容,這里不再介紹,感興趣的同學可參考[1]。
2)卡的內部由如下幾個block組成:
Memory core,存儲介質,一般是NAND flash、NOR flash等;
Memory core interface,管理存儲介質的接口,用於訪問(讀、寫、擦出等操作)存儲介質;
Card interface(CMD、CLK、DATA),總線接口,外界訪問卡內部存儲介質的接口,和具體的管腳相連;
Card interface controller,將總線接口上的協議轉換為Memory core interface的形式,用於訪問內部存儲介質;
Power模塊,提供reset、上電檢測等功能;
寄存器(圖片1中位於Card interface controller的左側,那些小矩形),用於提供卡的信息、參數、訪問控制等功能。
3)卡的管腳有VDD、GND、RST、CLK、CMD和DATA等,VDD和GND提供power,RST用於復位,CLK、CMD和DATA為MMC總線協議(具體可參考3.2小節)的物理通道:
CLK有一條,提供同步時鍾,可以在CLK的上升沿(或者下降沿,或者上升沿和下降沿)采集數據;
CMD有一條,用於傳輸雙向的命令。
DATA用於傳說雙向的數據,根據MMC的類型,可以有一條(1-bit)、四條(4-bit)或者八條(8-bit)。
4)以eMMC為例,規范定義了OCR, CID, CSD, EXT_CSD, RCA 以及DSR 6組寄存器,具體含義后面再介紹。
3.2 總線規范
前面我們提到過,MMC的本質是提供一套可以訪問固態非易失性存儲介質的通信協議,從產業化的角度看,這些存儲介質一般集成在一個獨立的外部模塊中(卡、WIFI模組等),通過物理總線和CPU連接。對任何有線的通信協議來說,總線規范都是非常重要的。關於MMC總線規范,簡單總結如下:
1)物理信號有CLK、CMD和DATA三類。
2)電壓范圍為1.65V和3.6V(參考上面圖片2),根據工作電壓的不同,MMC卡可以分為兩類:
High Voltage MultiMediaCard,工作電壓為2.7V~3.6V。
Dual Voltage MultiMediaCard,工作電壓有兩種,1.70V~1.95V和2.7V~3.6V,CPU可以根據需要切換。
3)數據傳輸的位寬(稱作data bus width mode)是允許動態配置的,包括1-bit (默認)模式、4-bit模式和8-bit模式。
注1:不使用的數據線,需要保持上拉狀態,這就是圖片2中的DATA中標出上拉的原因。另外,由於數據線寬度是動態可配的,這要求CPU可以動態的enable/disable數據線的那些上拉電阻。
4)MMC規范定義了CLK的頻率范圍,包括0-200MHz、0-26MHz、0-52MHz等幾種,結合數據線寬度,基本決定了MMC的訪問速度。
5)總線規范定義了一種簡單的、主從式的總線協議,MMC卡位從機(slave),CPU為主機(Host)。
6)協議規定了三種可以在總線上傳輸的信標(token):
Command,Host通過CMD線發送給Slave的,用於啟動(或結束)一個操作(后面介紹);
Response,Slave通過CMD線發送給Host,用於回應Host發送的Command;
Data,Host和Slave之間通過數據線傳說的數據。方向可以是Host到Slave,也可以是Slave到Host。數據線的個數可以是1、4或者8。在每一個時鍾周期,每根數據線上可以傳輸1bit或者2bits的數據。
7)一次數據傳輸過程,需要涉及所有的3個信標。一次數據傳輸的過程也稱作Bus Operation,根據場景的不同,MMC協議規定了很多類型的Bus Operation(具體可參考相應的規范)。
3.3 控制器規范
Host控制器是MMC總線規范在Host端的實現,也是Linux驅動工程師比較關注的地方,后面將會結合Linux MMC framework的有關內容,再詳細介紹。
4. 總結
本文對MMC/SD/SDIO等做了一個簡單的介紹,有了這些基本概念之后,在Linux kernel中編寫MMC驅動將不再是一個困難的事情(因為MMC是一個協議,所有有關協議的事情,都很簡單,因為協議是固定的),我們只需要如下步驟即可完成:
1)結合MMC的規范,閱讀Host MMC controller的spec,理解有關的功能和操作方法。
2)根據Linux MMC framework的框架,將MMC bus有關的操作方法通過MMC controller實現。
具體可參考后續MMC framework的分析文檔。
5. 參考文檔
[1] https://en.wikipedia.org/wiki/MultiMediaCard
[2] https://en.wikipedia.org/wiki/Secure_Digital
[3] eMM spec(注冊后可免費下載),http://www.jedec.org/standards-documents/results/jesd84-b51
[4]http://www.wowotech.net/basic_tech/mmc_sd_sdio_intro.html