日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

cmd52命令发送 mmc_乾坤合一~Linux SD/MMC/SDIO驱动分析(上)

發布時間:2023/12/2 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cmd52命令发送 mmc_乾坤合一~Linux SD/MMC/SDIO驱动分析(上) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、SD/MMC/SDIO概念區分

SD(SecureDigital)與 MMC(MultimediaCard)

SD 是一種 flash memory card 的標準,也就是一般常見的 SD 記憶卡,而 MMC 則是較早的一種記憶卡標準,目前已經被 SD 標準所取代。在維基百科上有相當詳細的 SD/MMC 規格說明:

SDIO(SecureDigital I/O)

SDIO 是目前我們比較關心的技術,SDIO 故名思義,就是 SD 的 I/O 接口(interface)的意思,不過這樣解釋可能還有點抽像。更具體的說明,SD 本來是記憶卡的標準,但是現在也可以把 SD 拿來插上一些外圍接口使用,這樣的技術便是 SDIO。

所以 SDIO 本身是一種相當單純的技術,透過 SD 的 I/O 接腳來連接外部外圍,并且透過 SD 上的 I/O 數據接位與這些外圍傳輸數據,而且 SD 協會會員也推出很完整的 SDIO stack 驅動程序,使得 SDIO 外圍(我們稱為 SDIO 卡)的開發與應用變得相當熱門。

現在已經有非常多的手機或是手持裝置都支持 SDIO 的功能(SD 標準原本就是針對 mobile device 而制定),而且許多 SDIO 外圍也都被開發出來,讓手機外接外圍更加容易,并且開發上更有彈性(不需要內建外圍)。目前常見的 SDIO 外圍(SDIO 卡)有:Wi-Fi card(無線網絡卡)

CMOS sensor card(照相模塊)

GPS card

GSM/GPRS modem card

Bluetooth card

Radio/TV card(很好玩)

SDIO 的應用將是未來嵌入式系統最重要的接口技術之一,并且也會取代目前 GPIO 式的 SPI 接口。

SD/SDIO 的傳輸模式

SD 傳輸模式有以下 3 種:SPI mode(required)

1-bit mode

4-bit mode

SDIO 同樣也支持以上 3 種傳輸模式。依據 SD 標準,所有的 SD(記憶卡)與 SDIO(外圍)都必須支持 SPI mode,因此 SPI mode 是「required」。此外,早期的 MMC 卡(使用 SPI 傳輸)也能接到 SD 插糟(SD slot),并且使用 SPI mode 或 1-bit mode 來讀取。

Secure digital I/Ocard,pin out

SD 的 MMCMode

SD 也能讀取 MMC 內存,雖然 MMC 標準上提到,MMC 內存不見得要支持 SPI mode(但是一定要支持 1-bit mode),但是市面上能看到的 MMC 卡其實都有支持 SPI mode。因此,我們可以把 SD 設定成 SPI mode 的傳輸方式來讀取 MMC 記憶卡。

SD 的 MMC Mode 就是用來讀取 MMC 卡的一種傳輸模式。不過,SD 的 MMC Mode 雖然也是使用 SPI mode,但其物理特性仍是有差異的:MMC 的 SPI mode 最大傳輸速率為 20 Mbit/s;

SD 的 SPI mode 最大傳輸速率為 25 Mbit/s。

為避免混淆,有時也用 SPI/MMC mode 與 SPI/SD mode 的寫法來做清楚區別。

參考網站:

二、MMC子系統介紹

MMC代碼分布

MMC子系統代碼主要在drivers/mmc目錄下,共有三個目錄:Card:存放閃存卡(塊設備)的相關驅動,如MMC/SD卡設備驅動,SDIOUART;

Host:針對不同主機端的SDHC、MMC控制器的驅動,這部分需要由驅動工程師來完成;

Core:整個MMC的核心層,這部分完成不同協議和規范的實現,為host層和設備驅動層提供接口函數。

MMC子系統框架

Linux MMC子系統主要分成三個部分:MMC核心層:完成不同協議和規范的實現,為host層和設備驅動層提供接口函數。MMC核心層由三個部分組成:MMC,SD和SDIO,分別為三類設備驅動提供接口函數;

Host 驅動層:針對不同主機端的SDHC、MMC控制器的驅動;

Client 驅動層:針對不同客戶端的設備驅動程序。如SD卡、T-flash卡、SDIO接口的GPS和wi-fi等設備驅動。

三、SD 總線協議

SD總線通信是基于指令和數據比特流,起始位開始和停止位結束。SD總線通信有三個元素:Command:由host發送到卡設備,使用CMD線發送;

Response:從card端發送到host端,作為對前一個CMD的相應,通過CMD線發送;

Data:即能從host傳輸到card,也能從card傳輸到host,通過data線傳輸。

Commands

以下是四種用于控制卡設備的指令類型,每個command都是固定的48位長度:

1、broadcast commands(bc), no response:廣播類型的指令,不需要有響應;

2、broadcast commands with response(bcr):廣播類型的指令且需要響應;

3、addressed(point-to-point) commands(ac):由HOST發送到指定的卡設備,沒有數據的傳輸;

4、address(point-to-point) data transfercommands(adtc):由HOST發送到指定的卡設備且伴隨有數據傳輸。

指令格式:Card register

幾個主要的寄存器:OCR,CID,CSD,RCA和SCR。

Operation condition register(OCR):32位的OCR包含卡設備支持的工作電壓表;

Card identification number register (CID):包含用于在卡識別階段的卡信息,包括制造商ID,產品名等;

Card specific data register(CSD):CSD寄存器提供了如何訪問卡設備的信息,包括定義了數據格式,錯誤校驗類型,最大訪問次數,數據傳輸率等;

Relative card address register(RCA):存放在卡識別階段分配的相對卡地址,缺省相對卡地址為0000h;

SD card configuration register(SCR):SCR是一個配置寄存器,用于配置SD memory card的特殊功能。

Response

所有的response都通過CMD線發送到host端,R4和R5響應類型是SDIO中特有的:

1、R1(normal response command):用來響應常用指令;

2、R2(CID,CSD register):用來響應CMD2和CMD10或CMD9,并把CID或CSD寄存器作為響應數據;

3、R3(OCR register):用來響應ACMD41指令,并把OCR寄存器作為響應數據;

4、R6(published RCA response):分配相對卡地址的響應;

5、R7(card interface condition):響應CMD8,返回卡支持的電壓信息;

6、R4(CMD5):響應CMD5,并把OCR寄存器作為響應數據;

7、R5(CMD52):CMD52是一個讀寫寄存器的指令,R5用于CMD52的響應;

Response 格式:

***詳情請參考spec***

四、SD初始化流程

當host上電后,使所有的卡設備處于卡識別模式,完成設置有效操作電壓范圍,卡識別和請求卡相對地址等操作。

1、發送指令CMD0使卡設備處于idle狀態;

2、發送指令CMD8,如果卡設備有response,說明此卡為SD2.0以上;

3、發送指令CMD55+ACMD41,該指令是用來探測卡設備的工作電壓是否符合host端的要求;在發送ACMD41這類指令之前需要先發送CMD55指令,在SDIO中ACMD41指令被CMD5替代。

4、發送指令CMD11轉換工作電壓到1.8V;

5、發送指令CMD2獲取CIA;

6、發送指令CMD3獲取RCA(relative card address)

SD初始化分析

系統上電時,SDI控制器會去掃描總線上的所有設備,然后對掛在總線上卡設備進行初始化。進行掃描和初始化工作都是由mmc_scan函數來完成,以下是Linux驅動中初始化流程圖(感謝同事Linkin的圖)。SDIO、SD和MMC這三者的初始化流程稍有不同,是向下兼容的。

五、SD卡調試關鍵點:

1. 上電時要延時足夠長的時間給 SD 卡一個準備過程,在我的程序里是 5 秒,根據不同的卡設置不同的延時時間。SD 卡初始化第一步在發送 CMD 命令之前,在片選有效的情況下首先要發送至少 74 個時鐘,否則將有可能出現 SD 卡不能初始化的問題。

2. SD 卡發送復位命令 CMD0 后,要發送版本查詢命令 CMD8 ,返回狀態一般分兩種,若返回 0x01 表示此 SD 卡接受 CMD8, 也就是說此 SD 卡支持版本 2 ;若返回 0x05 則表示此 SD 卡支持版本 1 。因為不同版本的 SD 卡操作要求有不一樣的地方,所以務必查詢 SD 卡的版本號,否則也會出現 SD 卡無法正常工作的問題。

3. 理論上要求發送 CMD58 獲得 SD 卡電壓參數,但實際過程中由于事先都知道了 SD 卡的工作電壓,因此可省略這一步簡化程序。協議書上也建議盡量不要用這個命令。

4. SD 卡讀寫超時時間要按照協議說明書書上的給定值 ( 讀超時:100ms ;寫超時:250ms) ,這個值要在程序中準確計算出來,否則將會出現不能正常讀寫數據的問題。我自己定義了一個計算公式:超時時間 =( 8/clk )*arg

5. 2GB 以內的 SD 卡 ( 標準卡 ) 和 2GB 以上的 SD 卡 ( 大容量卡 ) 在地址訪問形式上不同,這一點尤其要注意,否則將會出現無法讀寫數據的問題。如標準卡在讀寫操作時,對讀或寫命令令牌當中的地址域符初值 0x10 ,表示對第 16 個字節以后的地址單元進行操作 ( 前提是此 SD 卡支持偏移讀寫操作 ) ,而對大容量卡讀或寫命令令牌當中的地址域符初值 0x10 時,則表示對第 16 塊進行讀寫操作,而且大容量卡只支持塊讀寫操作,塊大小固定為 512 字節,對其進行字節操作將會出錯。

6. 對某一塊要進行寫操作時最好先執行擦出命令,這樣寫入的速度就能大大提高。進行擦除操作時不管是標準卡還是大容量卡都按塊操作執行,也就是一次擦除至少 512 字節。

7. 對標準卡進行字節操作時,起始和終止必須在一個物理扇區內,否則將不能進行讀寫操作。實際操作過程中建議用塊操作以提高效率。不管是標準卡還是大容量卡一個讀寫命令只能對一個塊進行操作,不允許跨物理層地址操作。

8. 在寫數據塊前要先寫入若干個 dummy data 字節,寫完一個塊數據時,主機要監測 MISO 數據線,如果從機處于忙狀態這根數據線會保持低電平,這樣主機就可以根據這根數據線的狀態以決定是否發送下一個命令,在從機沒有釋放 MISO 數據線之前,主機絕對不能執行其他命令,否則將會導致寫入的數據出錯,而且從機也不會響應主機的命令。

9. 在 SPI 模式下, CRC 校驗是被忽略的,但依然要求主從機發送 CRC 碼,只是數值可以是任意值,一般主機的 CRC 碼通常設為 0x00 或 0xFF 。

讀多塊操作和寫多塊操作的傳輸停止形式不一樣,讀多塊操作時用用命令 CMD12 終止傳輸,而寫多塊操作時用 Stop Tran Token( 停止傳輸令牌,值為 0xFD) 終止傳輸。

1、初始化步驟:

(1)延時至少 74clock,等待SD卡內部操作完成,在MMC協議中有明確說明。

(2)CS低電平選中SD卡。

(3) 發送 CMD0 ,需要返回 0x01 ,進入 Idle 狀態

(4) 為了區別SD卡是2.0還是1.0,或是MMC卡,這里根據協議向上兼容的原理,首先發送只有SD2.0才有的命令CMD8,如果CMD8返回無錯誤,則初步判斷為2.0卡,進一步發送命令循環發送 CMD55+ACMD41 ,直到返回 0x00 ,確定SD2.0卡初始化成功,進入Ready 狀態,再發送CMD58命令來判斷是HCSD還是SCSD,到此SD2.0卡初始化成功 。如果CMD8返回錯誤則進一步判斷為1.0卡還是MMC卡,循環發送CMD55+ACMD41 ,返回無錯誤,則為SD1.0卡,到此SD1.0卡初始成功,如果在一定的循環次數下,返回為錯誤,則進一步發送CMD1進行初始化,如果返回無錯誤,則確定為MMC卡,如果在一定的次數下,返回為錯誤,則不能識別該卡,初始結束。

(5)CS拉高。

2、讀步驟:

(1) 發送 CMD17 (單塊)或 CMD18 (多塊)讀命令,返回 0x00

(2) 接收數據開始令牌 0xfe (或 0xfc ) + 正式數據 512Bytes + CRC 校驗 2Bytes, 默認正式傳輸的數據長度是 512Bytes ,可用 CMD16 設置塊長度。

3、 寫步驟:

(1) 發送 CMD24 (單塊)或 CMD25 (多塊)寫命令,返回 0x00

(2) 發送數據開始令牌 0xfe (或 0xfc ) + 正式數據 512Bytes + CRC 校驗 2Bytes

4、 擦除步驟:

(1) 發送 CMD32 ,跟一個參數來指定首個要擦除的起始地址( SD 手冊上說是塊號)

(2) 發送 CMD33, ,指定最后的地址

(3) 發送 CMD38 ,擦除指定區間的內容

此 3 步順序不能顛倒。

六、SD卡的命令格式及解析

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

2.SD卡的命令

SD卡命令共分為12類,分別為class0到class11,不同的SDd卡,主控根據其功能,支持不同的命令集,如下:

Class0 :(卡的識別、初始化等基本命令集)

CMD0:復位SD 卡.

CMD1:讀OCR寄存器.

CMD9:讀CSD寄存器.

CMD10:讀CID寄存器.

CMD12:停止讀多塊時的數據傳輸

CMD13:讀 Card_Status 寄存器

Class2 (讀卡命令集):

CMD16:設置塊的長度

CMD17:讀單塊.

CMD18:讀多塊,直至主機發送CMD12為止 .

Class4(寫卡命令集) :

CMD24:寫單塊.

CMD25:寫多塊.

CMD27:寫CSD寄存器 .

Class5 (擦除卡命令集):

CMD32:設置擦除塊的起始地址.

CMD33:設置擦除塊的終止地址.

CMD38: 擦除所選擇的塊.

Class6(寫保護命令集):

CMD28:設置寫保護塊的地址.

CMD29:擦除寫保護塊的地址.

CMD30: Ask the card for the status of the write protection bits

class7:卡的鎖定,解鎖功能命令集

class8:申請特定命令集 。

class10 -11 :保留

3.有關sd卡驅動和fat fs的實現用了3個文件來實現。

sdboot.c為sd的驅動(可理解為pdd)層,主要實現一些對sd控制器的配置以及一些基本sd命令的實現和對sd 卡的操作。

sdmmc.c實現了從sd卡讀取nk并跳到內存去運行的代碼(基本可以理解為sd驅動的mdd層)。

sdfat.c文件就是實現fat fs的。mdd層通過fatfs來對pdd層操作以實現讀取文件。

在整個過程中遇到了很多問題,現在列舉如下:

1)sd卡初始化問題

配置gpio有關sd的功能:SDCMD, SDDAT[3:0]。

使能CLKCON中的SDI位。

時鐘以及計算公式:SDIPRE = PCLK/(CLK)-1;INICLK=300000;SDCLK=24000000;MMCCLK= 15000000

cmd0-cmd55-cmd41-cmd2-cmd3-cmd7-cmd6-cmd17

2)對sd卡操作問題

SD卡包括:一個標識寄存器CID,一個相應地址寄存器RCA,一個其他參數寄存器CSD。

對sd卡的操作是驅動通過sd controller來發相應的命令以達到讀寫等操作 的:發送命令通過SDICmdCon[7:0]的除了開始2bit:CmdIndex放置要發送的命令號;SDICmdCon[8]開始發送命令來完成的。

檢測卡的插入,直接用中斷引腳的電平來判斷。

判斷插入的卡是否是sd卡,用命令cmd55和cmd41,因為mmc卡對cmd55不做回應。

命令9 就是獲取sd卡中csd寄存器的值的,該值包括很多sd卡的信息,其中就有sd卡的容量。這個值在sd卡接收到cmd9之后會以response的形式存放在sd控制器的SDI Response Register[0,1,2,3]中。在執行cmd9,cmd10等這樣的命令的時候,卡的狀態應該是不選中的,或直接在執行它們之前發送 cmd7(0)不選中卡,不然的話會timeout。

用cmd17 來讀取單個block的數據,該命令要帶地址參數(該參數通過cmd3命令來獲取),然后根據SDIDSTA和SDIFSTA狀態值來從sd 控制器的SDIDAT寄存器中讀出要讀的數據。該命令與cmd9相反,在執行它之前要選中卡。讀完一個block之后要做一些善后工作,為下次讀取做好準備,不然的話checkcmdend就要一直循環了。因為用的是每次都讀一個block,并地址要以block對齊,這樣就要考慮要讀取的地址是否是 block對齊的,長度是否夠一個block。

SDIDCON這個數據控制寄存器也很重要,一些對數據的操作形式就是在這里設置的。

3)fat文件系統問題

根據MBR找到分區表,根據分區表找到該分區MBR[446B+4個分區表(每個16B)+2B結束符)

分區表中的第9-12字節為該分區的啟始地址(單位沒sector),第13-16字節為分區的長度(單位也是sector)

總結

以上是生活随笔為你收集整理的cmd52命令发送 mmc_乾坤合一~Linux SD/MMC/SDIO驱动分析(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。