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