Overview
深入理解SD卡系列文章將介紹SD卡,涉及SD卡的協議及驅動代碼。我們學習SD卡目的是為了理解SD卡的驅動代碼,修改它,最終解決工作中遇到的SD卡相關的問題。本系列文章的目標是理解SD,包括協議和驅動代碼。在學習任何設備驅動時,有個東西我們是無法繞過的,那就是協議,本文講的就是SD卡的協議。
學習SD卡協議,可以讓我們更好的了解SD卡的運作機制。在最開始學習SD卡的時候,我們只需要對SD卡的協議有個大概了解,能基本滿足我們看懂SD卡驅動代碼就行。如果之后在閱讀SD卡驅動代碼有不理解的地方,可以回過頭來翻翻SD協議文檔。建議在讀SD驅動源碼和學習SD卡協議之間交替進行,互相驗證。
關于SD卡,有個叫SD卡協會的組織,這個組織規定了各種涉及SD卡的協議,并發布協議文檔。這些SD卡協議文檔,最重要的有兩種文檔:SD Specifications Part 1 Physical Layer Simplified Specification 和SD Specifications Part A2 SD Host Controller Simplified Specification。
個人理解,定協議的目的就是為了使某個事物標準化,標準化后,可以方便大家協作,簡化工作量,提高效率,避免重復工作導致的浪費。Physical Layer Simplified Specification(以下簡稱:卡協議)規定了SD卡的物理規格和SD卡使用的命令協議,像Sandisk、Kingston這類SD卡制造商必須遵守該協議。假設Sandisk開發了一款SD卡沒有遵循該協議,而是自己內部新搞了一套協議,這樣市面上就沒有設備能使用該款SD卡。除非有人專門開發一個驅動去適配該款SD卡,但是這樣很浪費人力。如果每個SD卡廠商都使用自己的協議,那么每支持一款SD卡,都需要重新寫一套代碼去適配它,那這工作量就很恐怖了。
類似的,SD Host Controller Simplified Specification(以下簡稱:主機協議)用來標準化SD主機控制器,針對的是SD卡主機控制器廠商。這個協議不是強制的,在我們閱讀SD驅動代碼的時候,如果涉及到SD卡主機控制的代碼,我們可能需要翻一下這篇文檔,或者查閱SD卡主機控制器廠商提供給我們的文檔(一般都是各大cpu芯片廠商提供給我們開發者文檔)。
本文的講解的是卡協議,接下來,會有一些的英文夾雜在中文里面,因為有些名詞,還是原汁原味的好,我翻譯出來,沒了那種韻味,水平有限,望大家諒解。
System Features
本大章節講解SD的一些基本特征,包括SD卡的物理規格、容量、速度等方面。
Form-factor
目前市面上按物理規格來看,常見的SD卡有三種:
- 標準的SD卡,這種卡比較大,在有些相機或者PC電腦上會使用;
- 第二種是miniSD,這種卡我沒怎么使用,不作詳述;
- 最后一種是叫TF卡,也稱mirco SD,這種卡比較小,是我們最常接觸的,像我們的手機里面使用的就是這種卡。很多人基本上都管我們手機使用的那種卡叫SD卡,這樣的叫法實際上不夠準確,更準確應該是叫TF卡,但是不管怎樣,都沒人會去計較,能理解就行。
本文中,如果我說SD卡,都是泛指這三類SD卡,除非特意說明。并且如果特指,我會使用標準SD卡或者TF卡等名稱代替。
Capacity of Memory
SD卡按容量(Capacity)分類,可以分為標準容量卡、高容量卡,擴展容量卡,詳細如下:
- Standard Capacity SD Memory Card (SDSC): 這種卡容量小于等于2GB
- High Capacity SD Memory Card (SDHC): 這種卡容量大于2GB,小于等于32GB
- Extended Capacity SD Memory Card (SDXC):這種卡容量大于32GB, 小于等于2TB
如果你買了一張16G或者32G的SD卡,你會發現SD卡上面印有"HC"字樣,代表該卡是SDHC卡,同理,64G的SD卡上面印著"XC",表示SDXC卡。
Voltage range
SD卡按供電范圍劃分,分兩種:
- High Voltage SD Memory Card: 操作的電壓范圍在2.7-3.6V
- UHS-II SD Memory Card: 操作的電壓范圍VDD1: 2.7-3.6V, VDD2: 1.70-1.95V
UHS-II類型的卡參考協議文檔: SD Specifications Part 1 UHS-II Simplified Addendum
Bus Speed Mode (using 4 parallel data lines)
SD卡按總線速度模式來分,有下面幾種:
- Default Speed mode: 3.3V供電模式,頻率上限25MHz,速度上限 12.5MB/sec
- High Speed mode: 3.3V供電模式,頻率上限50MHz,速度上限 25MB/sec
- SDR12: UHS-I卡, 1.8V供電模式,頻率上限25MHz,速度上限 12.5MB/sec
- SDR25: UHS-I卡, 1.8V供電模式,頻率上限50MHz,速度上限 25MB/sec
- SDR50: UHS-I卡, 1.8V供電模式,頻率上限100MHz,速度上限 50MB/sec
- SDR104: UHS-I卡, 1.8V供電模式,頻率上限208MHz,速度上限 104MB/sec
- DDR50: UHS-I卡, 1.8V供電模式,頻率上限50MHz,性能上限 50MB/sec
- UHS156: UHS-II RCLK Frequency Range 26MHz - 52MHz, up to 1.56Gbps per lane.
SDR(Single Date Rate), 一個周期只能采集一次數據,即一個bit,由于SD卡是4條數據線并行傳輸,所以一個周期能傳輸4bit,如果頻率是50MHz(即1秒傳輸次數為50 000 000),那么1秒能傳輸的數據量為25MB(這里1MB為1 000 000 Byte)。所以這就是為什么各種SDR模式里面,頻率上限是速度上限的兩倍。而對于DDR(Double Data Rate),在時鐘上升沿和下降沿都可以采集數據,也就是單一周期內可讀取或寫入2次,因此4條并行數據線在一個周期內能傳輸8bit。
Speed Class
SD卡按照讀寫性能劃分,有5種規格,每種規格后面的數字象征最小的讀寫速度:
- Class 0 - 這種卡沒有性能要求
- Class 2 - 要求在 Default Speed mode 下,性能至少要達到(大于等于) 2MB/sec
- Class 4 - 要求在 Default Speed mode 下,性能至少要達到 4MB/sec
- Class 6 - 要求在 Default Speed mode 下,性能至少要達到 6MB/sec
- Class 10 - 要求在 High Speed mode 下,性能至少要達到 10MB/sec
廠商賣的SD卡上面基本上都會印著一個用圓圈包圍起來的數字10,表示該卡是Class 10 類型的卡。
Bus Protocol
在SD Bus上,有三種transaction:
- Command: 一個命令代表著將開始一個操作。命令通過CMD線傳輸,方向從host到card。
- Response: 響應是card對前一次host發送的命令的執行情況的反饋。也是通過CMD線傳輸,方向從card到host。
- Data: 數據是通過4條data線傳輸的,方向可以從card到host,也可以從host到card。
不管Command,還是Response或者Data,都開始于一個start bit (bit值0),結束于一個end bit(bit值1)。
關于這塊的內容不做過多解釋了,詳情自行閱讀"Physical Layer Simplified Specification Version 4.10"文檔 "3.6 Bus Protocl" 章節的內容。
Registers
下圖是SD卡的體系架構,可以看到內部包含了一系列的寄存器:
<div style="text-align:center" markdown="1">
</div>
各個寄存器的詳細信息如下:
OCR register
OCR寄存器保存著SD卡的工作電壓范圍。如果OCR寄存器的某位為1,表示卡支持該位對應的電壓。最后一位表示卡上電后的狀態(是否處于”忙狀態”),如果該位為0,表示忙,如果為1,表示處于空閑狀態。
CID register
CID是一個128 bits的寄存器,該寄存器包含一個卡的標識信息。
CSD Register
卡的描述數據寄存器(CSD)包含了訪問該卡數據時的必要配置信息,比如the data format, error correction type, maximum data access time, device size 等等。
RCA register
卡的相對地址,該16位卡地址寄存器保存了卡在識別過程中發布的地址。該地址用于在主機識別卡后,利用該地址與卡進行通信。該寄存器只有在SD模式下才有效。
SCR register
SD配置寄存器提供SD卡的特殊特性信息,其大小為64位。該寄存器由廠商編程,主機不能對它進行編程。
UHS
UHS(Ultra High Speed)是與SDXC同時推出的SD卡總線標準。此標準適用于SDHC和SDXC。
UHS-I最高傳輸速度(理論值)為104MB/s。英文字母I代表該設備(SD卡或讀卡器)支持UHS-I接口。英文字母U,包含數目字1,代表該設備讀寫速度達U1。
UHS-II最高傳輸速度達312MB/s,是UHS-I的三倍。
設備(如智能手機)必須支持UHS,才能保證達到U1或U3最低寫入速度。
下面介紹UHS-I初始化的命令序列流程。
- 上電后,卡會處于3.3V signaling模式下。第一個CMD0命令會選擇bus模式:SD模式或者SPI模式。只有在SD模式下,才能進入1.8V signaling模式。一旦卡進入1.8V signal模式,卡不能切換到SPI模式或者3.3V signal模式,除非重新上電。
- 收到CMD0命令后,卡將進入空閑狀態(Idle state),但是仍然工作在SDR12時序下。UHS-I只提供了SD模式,沒有提供SPI模式。
- 由于更高的總線速度需要低水平的signaling,對SDR50、DDR50和SDR104模式,UHS-I提供的signaling為1.8V。host會給卡提供3.3V的電壓,并且提供1.8V signaling水平的電壓給SDCLK、CMD和DAT[3:0]線,這幾個都是從3.3V的電源線轉換過來的。為了避免主機與卡之間的電壓不匹配,signaling水平在初始化時的電壓轉換序列中就已經被改變了。主機和卡通過ACMD41命令來確認雙方是否支持1.8V signaling模式。如果主機和卡都支持1.8V signaling模式,這就意味著UHS-I卡可用。
- UHS-I只能使用4-bit的bus模式,CMD42是個例外。如果卡被鎖住了,就需要通過發送CMD42命令(1-bit模式)解鎖,然后發送ACMD6命令將bus模式切換到4-bit。
- 在卡解鎖的情況下,CMD19命令執行在1.8V signaling的傳輸狀態。其他情況,CMD19都會被當做非法命令。
SD Memory Card Functional Description
對SD卡與主機(host)來說,有兩種操作模式:
- Card identification mode: 對卡reset重置后,主機進入卡識別模式,對卡來說,在reset后,除非收到CMD3命令,否則卡一直處于該模式下。
- Data transfer mode: 當卡第一次發布它的RCA后,該卡將處于數據傳輸模式。而對主機來說,在它識別了bus線上的所有卡后,進入該模式。
Card identification mode
Operating Condition Validation
SD卡識別模式流程圖如下:
在主機與卡通信之前,主機不清楚卡支持的電壓范圍,并且卡也不知道是否支持主機提供的供電電壓。主機會以默認電壓發送一個reset指令(CMD0),并且主機默認卡能支持該命令。然后,為了確認電壓,主機接下來會發送一個CMD8命令。
為了驗證SD卡接口的操作條件,主機通過發送SEND_IF_COND (CMD8)命令,去獲取SD卡支持的工作電壓范圍。SD卡通過檢測CMD8的參數部分來檢查主機使用的工作電壓,主機通過分析卡CMD8的response參數來確認SD卡是否可以在所給電壓下工作,如果SD卡可以在指定電壓下工作,則它的response里面會包含cmd8參數里面提供的電壓 。如果不支持所給電壓,則SD卡不會給出任何響應信息,并繼續處于IDLE狀態。如果要初始化SDHC和SDXC,在第一次發送ACMD41命令前,必須先發送CMD8。
SD_SEND_OP_COND (ACMD41)命令來識別或者拒絕不匹配host主機供電電壓范圍的卡。如果SD卡在主機規定的電壓范圍內不能實現數據傳輸,卡將放棄下一步的總線操作而進入不活動狀態(Inactive State)。
主機發送ACMD41命令時,可以通過將該命令所帶的OCR參數設置為0,用來查詢卡支持的工作電壓范圍。當ACMD41被用于查詢時,卡將忽略掉ACMD41里面的HCS參數。主機在查詢到卡的工作電壓后,也許會將該電壓作為接下來發送的ACMD41命令的參數。
在整個初始化過程中,主機不允許改變正在操作的電壓范圍。
Card Initialization and Identification Process
當總線被激合后,主機就開始處理卡的初始化和識別。在主機發送SD_SEND_OP_COND(ACMD41)命令開始處理SD卡初始化時,主機會在ACMD41的參數中設置它的操作條件和設置OCR中的HCS位。HCS位被設置為1表示主機支持SDHC或者SDXC。HCS被設置為0表示主機不支持SDHC和SDXC。
卡利用OCR里面的busy位來通知主機ACMD41的初始化已經完成。如果busy位為0,表示卡還在初始化,如果busy位為1,說明初始化已經完成。主機會在1s的時間內,重復不斷地發送ACMD41命令,直到busy位被置1為止??ㄖ挥性诘谝淮问盏皆O置電壓的ACMD41命令時,才會去檢查操作條件和OCR中的HCS位。并且在重復發送ACMD41命令的這段時間里,主機不應該發送任何命令,除了CMD0。
如果卡能正確響應CMD8,之后,卡對ACMD41命令的響應會包含一個CCS字段,CCS在卡返回ready時(busy位置1)有效。CCS=0表示卡是SDSC,CCS=1表示卡是SDHC或者SDXC。
在ACMD41之后,主機會發送 ALL_SEND_CID (CMD2),獲取卡的CID。在卡發送它的CID之后,卡進入識別狀態(Identification State)。
接著,主機發送CMD3 (SEND_RELATIVE_ADDR),請求卡發布卡的RCA。RCA是一個比CID短的,并且將來在數據傳輸模式中使用的地址。
Data Transfer Mode
因為一些卡在識別模式(Identification Mode)下,對操作頻率有限制,所以在識別模式結束前,主機的頻率需要一直保持在 fOD。在數據傳輸模式(Data Transfer Mode),主機頻率在fpp范圍內是可執行的。
主機必須發送SEND_CSD(CMD9)來獲得卡規格數據寄存器(CSD)內容,獲取像塊大小、卡容量這類信息。
SET_DSR(CMD4)廣播命令配置所有識別到的卡的驅動階段。它對DSR寄存器進行編程以適應應用的總線布局(長度)、總線上卡的數目和數據傳輸頻率。clock rate也是在這個時候從fOD切到fpp。對卡和主機來說,SET_DSR(CMD4)命令是個可選。
CMD7用于選擇卡,并且將卡帶入傳輸狀態(Transfer State)。在同一個時間內,只有一張卡能進入傳輸狀態。當發送的CMD7的RCA地址參數為"0x0000",所有卡將跳回到準備狀態(Stand-by State )。
SD卡數據傳輸模式的流程圖如下:
對已經擁有RCA的卡來說,對它發送identification commands(比如ACMD41、CMD2),它將不會有任何回應。在數據傳輸模式下,主機與被選中的卡(使用定向命令)之間的數據傳輸都是點對點的。通過cmd線,所有定向命令(addressed commands)都會收到一個用于確認的response。
下面是數據傳輸模式下關于數據傳輸的一些總結:
- 在任何時候,所有的讀命令集在執行過程中都可以被stop command (CMD12)打斷。cmd12命令將會使數據傳輸終止,并且使卡退回到傳輸狀態(Transfer State)。讀命令集包括:block read(CMD17), multiple block read(CMD18), send write protect(CMD30), send SCR(ACMD51) 和 general command in read mode (CMD56)。
- 在任何時候,所有的寫命令集在執行過程中都可以被stop command (CMD12)打斷。寫命令集包括: block write(CMD24 and CMD25), program CSD(CMD27), lock/unlock command(CMD42)和general command in write mode(CMD56)。
- 一旦數據傳輸完成,卡就會退出數據寫狀態,并且進入正在編程狀態(Programming State)(傳輸成功),或者進入傳輸狀態(傳輸失敗)。
- 如果一個塊寫操作被打斷,但是最后一個block的塊長度和CRC有效的話,這塊數據也將會被編程到卡里。
- 卡也許會對塊寫操作提供緩存,這意味著,在一個block還在被編程的情況下,下一個block可以被發送這個卡里面。如果所有的寫緩存都已經滿了的話,只要卡還在正在編程狀態,DAT0線就會一直保持在拉低狀態。
- 對寫CSD、寫保護和擦除操作來說,卡不會提供緩存。這意味著,在卡正忙于處理這其中任何一個命令時,卡不會接收任何發送到卡的數據。只要卡還在忙,DAT0線就會拉低,并且處于正在編程狀態(Programming State)。
- 當卡正在編程時,不允許任何一個參數設置命令集(Parameter set commands)。參數設置命令集包括: set block length(CMD16), erase block start(CMD32)和erase block end(CMD33)。
- 當卡正在編程時,不允許任何一個讀命令集。
- 當將其他的卡從準備狀態(Stand-by)切換到傳輸狀態(使用CMD7),不會中斷當前卡的擦除或者編程操作。當前卡將會切換到斷開狀態(Disconnect State),并且釋放數據線。
- 當卡正在編程或者待編程時,對其重置(發送CMD0或者CMD15),將會導致操作終止,并且可能會導致卡內的數據內容被破壞。因此主機有責任去禁止這樣的操作。
至此,本文關于SD卡協議的內容就介紹到這里。通過本文,可以對SD卡有個大概的了解,尤其是關于SD卡初始化這段內容。就SD卡協議這方面來說,了解一些基本的東西就行。在我們今后在遇到SD問題時需要時,可以翻出來看一下。水平有限,有些地方可能會出現錯誤,望各位能指出來,希望能和各位共同探討技術方面的內容。