看到一篇寫的比較好的筆記,分享給大家
一、SD卡概述
1、定義
2、容量等級
3、SD卡框圖
4、SD卡與TF卡的區(qū)別
二、?SD卡內(nèi)部結(jié)構(gòu)
1、 SD卡內(nèi)部結(jié)構(gòu)簡圖
2、 存儲陣列結(jié)構(gòu)圖
3、Buffer?
4、“存儲陣列Block”--最小的存儲單元
5、SD卡的特殊功能寄存器
四、SD卡協(xié)議的核心--數(shù)據(jù)讀、寫、擦除
1、SD卡寫數(shù)據(jù)塊
2、SD卡讀數(shù)據(jù)塊?
3、擦除SD卡
五、SD卡物理層協(xié)議
1、接口?
2、命令格式
3、響應(yīng)格式
4、SD卡的工作狀態(tài)
5、SD卡的兩種狀態(tài)信息
六、STM32與SD卡相配的外設(shè)--SDIO適配器
1、SDIO adapter 結(jié)構(gòu)圖?
2、命令狀態(tài)機(jī)(CPSM)
3、數(shù)據(jù)通道狀態(tài)機(jī)(DPSM)
4、SDIO的FIFO?
5、SDIO的特殊功能寄存器
七、SD卡編程?
1、SD卡編程的內(nèi)容
2、SD卡初始化?
3、讀SD卡的一個(gè)塊
4、寫SD卡的一個(gè)塊?
八、SD卡疑惑
1、SD卡擦除后,其中的內(nèi)容是0,還是1 ??
2、在SDIO_DCTRL中設(shè)置傳輸Block的要求
? ?3、STM32固件庫“stm32_eval_sdio_sd.c version v4.5.0”偶遇BUG
? ?4、SD卡寫B(tài)lock是怎樣進(jìn)行的?
九、SD卡參數(shù)測試
一、SD卡概述
1、定義
SD卡(安全數(shù)碼卡),是一種基于半導(dǎo)體快閃記憶器的新一代記憶設(shè)備,它被廣泛地于便攜式裝置上使用,例如數(shù)碼相機(jī)、個(gè)人數(shù)碼助理(外語縮寫PDA)和多媒體播放器等。
2、容量等級
容量等級 | 容量范圍 | 磁盤格式 |
SD | 上限至2GB | FAT 12, 16 |
SDHC | 2GB至 32GB | FAT 32 |
SDXC | 32GB至2TB | exFAT |
3、SD卡框圖
?引腳說明:
4、SD卡與TF卡的區(qū)別
TF卡又名micro SD卡,個(gè)頭是比SD卡的1/4還小,可以通過“TF轉(zhuǎn)SD卡套”轉(zhuǎn)換成SD卡。
詳細(xì)區(qū)別參考:SD卡與TF卡的區(qū)別
二、?SD卡內(nèi)部結(jié)構(gòu)
(摘自SanDisk Secure Digital Card Product Manual Version 1.9)
1、 SD卡內(nèi)部結(jié)構(gòu)簡圖
由SD卡控制器和存儲陣列組成,SD卡與外界的通訊接口是SD Bus或者SPI Bus。
2、 存儲陣列結(jié)構(gòu)圖
Block: ?
讀寫時(shí)的單元(數(shù)據(jù)傳輸單元),它的單位是“字節(jié)”。
Sector:
如果CSD寄存器ERASE_BLK_EN = 0時(shí),Sector是最小的擦除單元,它的單位是“塊”。Sector的值等于CSD寄存器中的SECTOR_SIZE的值+1。
WP Group:
最小的寫保護(hù)單元,它的單位是“扇區(qū)”。
3、Buffer
SD Card的Buffer最大容量定義在CSD寄存器的READ_BL_LEN和WRITE_BL_LEN。它們的值是一樣的,而且有可能超過512字節(jié),盡管這樣Block還是要設(shè)置成512字節(jié),因?yàn)?12字節(jié)是數(shù)據(jù)邊界(這句話不是太理解)。也就是SD卡上有數(shù)據(jù)傳輸緩沖器Buffer,不同的產(chǎn)品可能不一樣,但是在使用時(shí)要將Buffer設(shè)置成512字節(jié)。
4、“存儲陣列Block”--最小的存儲單元
資料上的Block通通指的是數(shù)據(jù)傳輸時(shí)的最小單元,定義這個(gè)數(shù)值是為了數(shù)據(jù)傳輸、CRC校驗(yàn)等。
存儲陣列通常采用NandFlash的結(jié)構(gòu),顯然不能按字節(jié)存取,而這里討論的“存儲陣列Block”就是指這個(gè)概念??上У氖悄壳?,我還沒有找到資料討論這個(gè)問題,所以這一章節(jié)是筆者自己的推測。
據(jù)我推測存儲陣列Block應(yīng)該是512Byes,因?yàn)楸姸嗟臄?shù)據(jù)都圍繞著512Bytes在轉(zhuǎn)。比如說最小的擦除單元是512Byes,最小的讀寫單位應(yīng)該被設(shè)置成512Bytes,那么有理由推測是這個(gè)數(shù)值。
5、SD卡特殊功能寄存器
CID: 寬度128位,卡標(biāo)識號
RCA: 寬度16位,卡相對地址,在初始化的時(shí)候確定
CSD: 寬度128位,卡描述數(shù)據(jù):卡操作條件的信息
SCR: 寬度64位,SD卡配置寄存器:SD卡特定信息數(shù)據(jù)
OCR: 寬度32位,操作條件寄存
三、SDIO接口
四、SD卡協(xié)議之?dāng)?shù)據(jù)讀、寫、擦除
1、SD卡寫數(shù)據(jù)塊
執(zhí)行寫數(shù)據(jù)塊命令(CMD24-27) 時(shí),主機(jī)把一個(gè)或多個(gè)數(shù)據(jù)塊從主機(jī)傳送到卡中,同時(shí)在每個(gè)數(shù)據(jù)塊的末尾傳送一個(gè)CRC碼。主機(jī)傳送數(shù)據(jù),SD卡接收數(shù)據(jù)并將數(shù)據(jù)保存在Buffer中,累計(jì)接收數(shù)據(jù)達(dá)到Block長度的時(shí)候,SD卡把接下來的數(shù)據(jù)當(dāng)做CRC校驗(yàn)碼,并且開始數(shù)據(jù)校驗(yàn)。如果CRC校驗(yàn)錯(cuò)誤,卡通過SDIO_D 線指示錯(cuò)誤,傳送的數(shù)據(jù)被丟棄而不被寫入,所有后續(xù)(在多塊寫模式下)傳送的數(shù)據(jù)塊將被忽略。
? ? ?如果主機(jī)傳送部分?jǐn)?shù)據(jù)而累計(jì)的數(shù)據(jù)長度未與數(shù)據(jù)塊對齊,當(dāng)不允許塊錯(cuò)位( 未設(shè)置CSD的參數(shù)WRITE_BLK_MISALIGN),卡將在第一個(gè)錯(cuò)位的塊之前檢測到塊錯(cuò)位錯(cuò)誤( 設(shè)置狀態(tài)寄存器中的ADDRESS_ERROR 錯(cuò)誤位) 。當(dāng)主機(jī)試圖寫一個(gè)寫保護(hù)區(qū)域時(shí),寫操作也會(huì)被中止,此時(shí)卡會(huì)設(shè)置WP_VIOLATION位?!?/p>
數(shù)據(jù)塊Block的最大長度定義在CSD中的WRITE_BL_LEN,但是在數(shù)據(jù)傳輸時(shí)應(yīng)該用CMD16指令將其設(shè)置為512Byets,不去在意WRITE_BL_LEN是1024或者2048Bytes。
另外需要注意的是,Block的長度設(shè)置還要參考CSD寄存器的WRITE_BL_PARTIAL。當(dāng)WRITE_BL_PARTIAL為0時(shí),那么么辦法Block只能設(shè)置為512Bytes;如果WRITE_BL_PARTIAL=1,那么允許將Block設(shè)置成更小的塊,比如說一個(gè)字節(jié)。協(xié)議是這樣規(guī)定的,但是據(jù)我分析如果這樣的話SD卡的制作會(huì)非常復(fù)雜(寫入的單位可以是字節(jié)),價(jià)格也會(huì)很高。筆者測試了自己的SD卡,WRITE_BL_PARTIAL 等于0,也就是不支持“塊部分寫”功能。?
2、SD卡讀數(shù)據(jù)塊
在讀數(shù)據(jù)塊模式下,數(shù)據(jù)傳輸?shù)幕締卧菙?shù)據(jù)塊Block。為保證數(shù)據(jù)傳輸?shù)恼_,傳輸一個(gè)數(shù)據(jù)塊Blcok后都有一個(gè)CRC校驗(yàn)碼。筆者認(rèn)為主機(jī)在累計(jì)接收到Block長度數(shù)據(jù)后,軟件可以把接下來的數(shù)據(jù)當(dāng)做CRC校驗(yàn)碼,并且進(jìn)行校驗(yàn)。
Block的最大值在CSD中(READ_BL_LEN) 給出了定義,但是在數(shù)據(jù)傳輸時(shí)應(yīng)該用CMD16指令將其設(shè)置為512Byets,不去在意READ_BL_LEN是1024或者2048Bytes。
如果CSD寄存器中的READ_BL_PARTIAL等于1,可以傳送的較小數(shù)據(jù)塊,較小數(shù)據(jù)塊是指開始和結(jié)束地址完全包含在一個(gè)物理塊中。事實(shí)上,協(xié)議規(guī)定READ_BL_PARTIAL永遠(yuǎn)等于1,也就說在任何SD卡上都允許“讀部分塊”,讀的塊的最小字節(jié)是1Bytes。使用這種功能,可以通過CMD16命令設(shè)置更小的Block(比如說等于128)。讀取的這128字節(jié)必須在512Bytes邊界內(nèi),不能跨越邊界(其實(shí)因?yàn)榇鎯﹃嚵惺且?12Bytes為單位的,讀取“部分塊”只能在一個(gè)塊內(nèi),不允許跨塊讀)。
3、擦除SD卡
CSD寄存器ERASE_BLK_EN決定了SD卡的最小擦除單位。
當(dāng)ERASE_BLK_EN等于0的時(shí)候,主機(jī)擦除的最小單位是扇區(qū)。比如一個(gè)Sector包含32個(gè)Block,擦除時(shí)的起始地址是5,而結(jié)束地址是40,那么實(shí)際擦除的塊是從0到63。
當(dāng)ERASE_BLK_EN等于1的時(shí)候,主機(jī)擦除的最小單位是512 Byetes。比如擦除時(shí)的起始地址是5,而結(jié)束地址是40,那么實(shí)際擦除的塊就是從5到40。
五、SD卡物理層協(xié)議
SD卡的協(xié)議相對于SPI、I2C等協(xié)議的存儲器來說相對復(fù)雜,包含SD卡物理層(機(jī)械封裝、管腳、芯片結(jié)構(gòu)、命令集等)、SD卡接口(SDIO)、SD主機(jī)控制器,甚至是軟件設(shè)計(jì)的流程,都進(jìn)行了詳細(xì)的規(guī)定。
1、接口
① SDIO接口
<1> CLK 時(shí)鐘同步線
<2> CMD 命令信號線,主機(jī)發(fā)出的命令以及從機(jī)對命令的響應(yīng)都是通過這條線進(jìn)行傳輸
<3> DAT[3:0] 表示4條數(shù)據(jù)線,主機(jī)和從機(jī)的數(shù)據(jù)都是從這四條數(shù)據(jù)線上傳輸
② SPI接口
2、命令格式
3、響應(yīng)格式
以R1為例
4、SD卡的工作狀態(tài)
5、SD卡的兩種狀態(tài)信息
① Card Status
執(zhí)行命令過程中的狀態(tài)信息,比如地址不對齊錯(cuò)誤、塊長度錯(cuò)誤、卡鎖、ECC校驗(yàn)錯(cuò)誤等等
② SD Status
SD卡的專有特征,編程中不經(jīng)常涉及。這個(gè)狀態(tài)值有512位,不是通過命令線傳送給主機(jī),而是通過數(shù)據(jù)線。
六、STM32與SD卡相配的外設(shè)--SDIO適配器
?1、SDIO adapter 結(jié)構(gòu)圖
2、命令狀態(tài)機(jī)(CPSM)
當(dāng)發(fā)送命令和接收響應(yīng)時(shí),啟動(dòng)CPSM狀態(tài)機(jī)。
3、數(shù)據(jù)通道狀態(tài)機(jī)
當(dāng)傳輸數(shù)據(jù)時(shí),啟動(dòng)數(shù)據(jù)通道狀態(tài)機(jī)。
4、FIFO
有關(guān)FIFO的資料參考:異步FIFO的FPGA實(shí)現(xiàn)
數(shù)據(jù)FIFO(先進(jìn)先出)子單元是一個(gè)具有發(fā)送和接收單元的數(shù)據(jù)緩沖區(qū)。
FIFO包含一個(gè)每字32位寬、共32個(gè)字的數(shù)據(jù)緩沖區(qū),和發(fā)送與接收電路。因?yàn)閿?shù)據(jù)FIFO工作在AHB 時(shí)鐘區(qū)域(HCLK/2),所有與SDIO時(shí)鐘區(qū)域(SDIOCLK)連接的信號都進(jìn)行了重新同步。依據(jù)TXACT和RXACT標(biāo)志,可以關(guān)閉FIFO、使能發(fā)送或使能接收。TXACT和RXACT 由數(shù)據(jù)通道子單元設(shè)置而且是互斥的:
─ 當(dāng) TXACT 有效時(shí),發(fā)送 FIFO 代表發(fā)送電路和數(shù)據(jù)緩沖區(qū)
─ 當(dāng) RXACT 有效時(shí),接收 FIFO 代表接收電路和數(shù)據(jù)緩沖區(qū)
5、SDIO的特殊功能寄存器
SDIO電源控制寄存器(SDIO_POWER)
SDIO時(shí)鐘控制寄存器(SDIO_CLKCR) : 時(shí)鐘選擇、分頻
SDIO參數(shù)寄存器(SDIO_ARG)
SDIO命令寄存器(SDIO_CMD):控制發(fā)送命令
SDIO命令響應(yīng)寄存器(SDIO_RESPCMD):包含響應(yīng)命令中的命令索引
SDIO響應(yīng)1..4寄存器(SDIO_RESPx):包含響應(yīng)命令中的卡狀態(tài)信息
SDIO數(shù)據(jù)定時(shí)器寄存器(SDIO_DTIMER)
SDIO數(shù)據(jù)長度寄存器(SDIO_DLEN):讀或者寫的長度,通常是是512的倍數(shù)
SDIO數(shù)據(jù)控制寄存器(SDIO_DCTRL):控制數(shù)據(jù)的讀寫方向、使能傳輸?shù)刃畔?/p>
SDIO數(shù)據(jù)計(jì)數(shù)器寄存器(SDIO_DCOUNT):當(dāng)DPSM狀態(tài)機(jī)從Idle state切換到Wait_R或者Wait_S狀態(tài)時(shí),SDIO_LEN的數(shù)值加載到該寄存器中
SDIO狀態(tài)寄存器(SDIO_STA)
SDIO清除中斷寄存器(SDIO_ICR)
SDIO中斷屏蔽寄存器(SDIO_MASK)
SDIO FIFO計(jì)數(shù)器寄存器(SDIO_FIFOCNT):當(dāng)SDIO_DCTRL中的DTEN使能,并且DPSM處于Idle state時(shí),SDIO_LEN/4的數(shù)值加載到該寄存器中
SDIO數(shù)據(jù)FIFO寄存器(SDIO_FIFO):讀寫數(shù)據(jù)緩沖FIFO
七、SD卡編程
SD卡的編程在STM32官方固件庫中就有例程,而且野火開發(fā)板對該例程進(jìn)行了中文注釋,不必再把源碼貼入。這里著重講一下SD卡編程流程,主要包含SD卡初始化、SD卡讀、SD卡寫、SD卡擦除。
1、SD卡編程的內(nèi)容
SD卡主要就是用來存儲數(shù)據(jù)的,所以核心就是讀寫。為了實(shí)現(xiàn)這個(gè)目標(biāo),必須實(shí)現(xiàn)響應(yīng)的驅(qū)動(dòng)。
配置過程中,不僅要設(shè)置好SD控制器,還需要將SD卡設(shè)置到合適的狀態(tài)。在讀取狀態(tài)的時(shí)候,不僅涉及到SD控制器的狀態(tài),還涉及到SD卡的狀態(tài)。
2、SD卡初始化
① STM32外設(shè)SDIO初始化
端口配置、端口時(shí)鐘、SDIO時(shí)鐘、DMA2時(shí)鐘使能
SDIO寄存器復(fù)位
設(shè)置時(shí)鐘SDIO_CK為400KHz以下,設(shè)置數(shù)據(jù)線寬度,開啟時(shí)鐘、開啟SDIO電源
② SD卡上電初始化
上電初始化流程如上圖所示,筆者認(rèn)為官方庫提供的例程沒有完全按照這個(gè)流程圖的指示去做。事實(shí)上,官方庫的程序只做了如上圖紅色方框內(nèi)的流程,之外的沒涉及。
CMD0命令復(fù)位所有的卡。
SD協(xié)議規(guī)定:在初始化的時(shí)候,使用ACMD41之前,必須先使用CMD8命令。而且ACMD41命令屬于應(yīng)用命令,在使用之前需要先發(fā)送命令CMD55。
CMD8命令是為了核查電源是否匹配。ACMD41命令不斷詢問SD卡是否支持主機(jī)提供的電壓,并且詢問SD卡是否上電完成進(jìn)入準(zhǔn)備狀態(tài)。ACMD41命令還能詢問SD卡的類型(SDSC、SDHC)。
③卡進(jìn)一步核查、獲取卡信息
發(fā)送命令CMD2,以獲取CID信息。
發(fā)送命令CMD3,以獲取RCA相對地址,可以通過多次發(fā)送CMD3獲取不同的RCA值,但是只有最后一次的才是有效的RCA地址。
發(fā)送命令CMD9,以獲取CSD寄存器。
④ 設(shè)置SDIO工作在數(shù)據(jù)傳輸模式
設(shè)置SDIO的時(shí)鐘為24MHz、數(shù)據(jù)線寬度為4位。
通過SD_GetCardInfo函數(shù)將之前得到CID、CSD處理成卡的信息。
通過CMD7命令選擇匹配地址的卡,而取消選擇其他的卡。
至此,初始化完成。
3、讀SD卡的一個(gè)塊
數(shù)據(jù)控制寄存器(SDIO_DCTRL)清零
發(fā)送命令CMD16,設(shè)置SD卡的Block大小
調(diào)用函數(shù)SDIO_DataConfig設(shè)置SDIO數(shù)據(jù)傳輸方式
發(fā)送命令CMD17,讀單個(gè)塊
SDIO數(shù)據(jù)傳輸結(jié)束中斷使能
SDIO的DMA傳輸功能使能
DMA設(shè)置,并使能
4、寫SD卡的一個(gè)塊
數(shù)據(jù)控制寄存器(SDIO_DCTRL)清零
發(fā)送命令CMD16,設(shè)置SD卡的Block大小
發(fā)送命令CMD24,寫單個(gè)塊
調(diào)用函數(shù)SDIO_DataConfig設(shè)置SDIO數(shù)據(jù)傳輸方式
SDIO數(shù)據(jù)傳輸結(jié)束中斷使能
DMA設(shè)置,并使能
使能SDIO的DMA傳輸功能?
八、SD卡疑惑
1、SD卡擦除后,其中的內(nèi)容是0,還是1 ??
The data at the card after an erase operation is either '0' or '1', depends on the card vendor.The SCR register bit DATA_STAT_AFTER_ERASE (bit 55) defines whether it is '0' or '1'.(摘自《SD Specifications_Part_1_Physical_Layer_Specification_Ver3.00_Final_090416.pdf》)
也就是說這是芯片廠商生產(chǎn)工藝決定的,可以通過SCR寄存器的 DATA_STAT_AFTER_ERASE位得知。
?2、在SDIO_DCTRL中設(shè)置傳輸Block的要求
Block大小決定了主機(jī)在發(fā)送數(shù)據(jù)時(shí),發(fā)送到什么程度時(shí)開始發(fā)送CRC校驗(yàn)碼;而在接收數(shù)據(jù)時(shí),在接收到什么程度時(shí)開始把SD卡的數(shù)據(jù)作為CRC校驗(yàn)碼并進(jìn)行校驗(yàn)。Block還可能影響著其他的時(shí)序。在STM32的SDIO寄存器組中,SDIO_DCTRL中的位段DBLOCKSIZE決定主機(jī)Block大小。
在摘自《Simplified_SD_Host_Controller_Spec.pdf》的引文中,提到這樣的配置要求:主機(jī)的Block一定要與SD卡設(shè)置的Block一樣大小,這顯然是必要的。我們經(jīng)常設(shè)置SD卡的Block大小是512Bytes,所以設(shè)置DBLOCKSIZE為9(2^9 = 512)。
?3、STM32固件庫“stm32_eval_sdio_sd.c version v4.5.0”偶遇BUG
參考網(wǎng)頁:http://www.cprogramdevelop.com/3742318/
?4、SD卡寫B(tài)lock是怎樣進(jìn)行的?
寫SD卡的單位是Block(512Bytes),再寫之前要先整塊擦除,然后才能寫。
在多塊寫操作中,可以在發(fā)送多塊寫命令CMD25之前,有選擇性的先發(fā)送命令A(yù)CMD23設(shè)置預(yù)擦除。怎樣理解呢?
既然是有選擇性的,也可以不發(fā)送ACMD23命令。在多塊寫的過程中,由于SD卡事先不知道你要寫入幾個(gè)塊(CMD25命令只告訴SD卡要寫入的起始地址),所以寫入的過程是:根據(jù)需要判斷要寫一個(gè)塊時(shí),先擦除然后再寫,再判斷是否要寫入下一個(gè)塊,如果是就再擦除再寫。
倘若發(fā)送ACMD23命令就不一樣了,ADM23命令會(huì)在寫命令CMD25生效之前,告訴SD卡準(zhǔn)備寫入的塊數(shù)N。這樣當(dāng)CMD25命令生效的時(shí)候,SD卡會(huì)一次性先將這N個(gè)塊都擦除,然后再一個(gè)塊一個(gè)塊寫。由于擦除操作比較集中,所以整個(gè)多塊寫操作更節(jié)省時(shí)間。
九、SD卡參數(shù)測試
使用野火開發(fā)板配套例程做測試,筆者測試用的SD卡是金士頓的2G內(nèi)存塊,打印SD卡的參數(shù)信息如下:
?
Card Type is :1
ManufacturerID is :2
Card device size is :3795
Card Block Size is :1024
Card device size multiplier is :7
Card Capacity is :1990197248
the maximum read date block length is :1024
partial blocks for write allowed is :0
the maximum write date block length is :1024
erase single block enable is :1
erase sector size is :127
write protect group size is :0
RCA is :4660?
?
Card Type:1 ? ? ? ? SDSC卡版本2.0
Card device size: C_SIZE(CSD),為3795
Card Block Size: max read data block length(READ_BL_LEN(CSD)) ,為1024 Bytes
Card device size multiplier is: ?C_SIZE_MULT(CSD),為7
Card Capacity: 1990197248 Bytes
計(jì)算方法(摘自《Simplified_Physical_Layer_Spec.pdf》):
memory capacity = BLOCKNR * BLOCK_LEN
?
BLOCKNR = (C_SIZE+1) * MULT ?(C_SIZE <= 4096)
MULT = 2^(C_SIZE_MULT+2) ? ? ? ?(C_SIZE_MULT < 8)
BLOCK_LEN = 2^READ_BL_LEN, ? ?(READ_BL_LEN < 12)
注意:SDSC最大為2GB。
the maximum read date block length:READ_BL_LEN(CSD)?,為1024 Bytes
partial blocks for write allowed:WRITE_BL_PARTIAL(CSD),為不支持
the maximum write date block length:WRITE_BL_LEN(CSD) ,為1024 Bytes
erase single block enable:ERASE_BLK_EN(CSD),為1,支持單塊擦除
erase sector size:SECTOR_SIZE(CSD),實(shí)際扇區(qū)擦除的block數(shù)為(SECTOR_SIZE+1),為128 Blocks
write protect group size:WP_GRP_SIZE(CSD),實(shí)際保護(hù)的扇區(qū)數(shù)為(WP_GRP_SIZE+1),為1 Sector
RCA: SD卡相對地址為4660
審核編輯:湯梓紅
評論
查看更多