亚洲精品久久久久久久久久久,亚洲国产精品一区二区制服,亚洲精品午夜精品,国产成人精品综合在线观看,最近2019中文字幕一页二页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

CS創(chuàng)世SD NAND在北京君正平臺和瑞芯微RK平臺的應(yīng)用

jim ? 來源:雷龍發(fā)展 ? 作者:雷龍發(fā)展 ? 2025-08-22 16:52 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

各位工程師,你們好,我是alan,今天就瑞芯微平臺和北京君正平臺下的linux系統(tǒng)中關(guān)于SD NAND的使用做一些經(jīng)驗的分享,如有不正,請聯(lián)系我們批評指正;

采用的開發(fā)板是RK3568和x2600e,ubuntu版本是20.04,交叉編譯工具鏈是aarch64-linux-gnu-和mips-linux-gnu-;

下面將從五個板塊來進行介紹,分別是操作SD NAND的常用命令、SD底層協(xié)議簡要介紹、對SD NAND進行讀寫操作的三大方式、SD的驅(qū)動框架介紹以及SD NAND啟動,前三個板塊沒有瑞芯微和君正平臺之分,只要是跑linux系統(tǒng),差別不大,第四塊以RK平臺為例,第五塊同時以君正平臺和RK平臺為例。

一:操作SD NAND的常用命令

1.查看SD設(shè)備:lsblk或fdisk -l,設(shè)備節(jié)點一般為/dev/mmcblkX或/dev/sdX,eg:mmcblk0;

2.掛載分區(qū):mount 設(shè)備分區(qū) 掛載點 eg:mount /dev/mmcblk0p1 /mnt/sdcard

3.卸載分區(qū):umount 設(shè)備分區(qū)/掛載點 eg:umount /dev/mmcblk0p1 或 umount /mnt/sdcard

4.分區(qū)管理:fdisk 設(shè)備節(jié)點eg:fdisk /dev/mmcblk0

進入交互頁面后常用命令:

p 打印分區(qū)表

n 創(chuàng)建新分區(qū)

d 刪除分區(qū)

t 更改分區(qū)類型

w 將更改寫入磁盤并退出

q 不保存更改退出

m 顯示幫助菜單

l 列出已知的分區(qū)類型

v 驗證分區(qū)表

g 創(chuàng)建新的空GPT分區(qū)表

o 創(chuàng)建新的空DOS分區(qū)表

在進行分區(qū)管理前請務(wù)必備份重要數(shù)據(jù),因為在更改生效后會丟失原來數(shù)據(jù);

5.格式化分區(qū):

格式化為FAT32:mkfs.vfat 設(shè)備分區(qū);eg: mkfs.vfat /dev/mmcblk0p1

格式化為ext4:mkfs.ext4 設(shè)備分區(qū);eg:mkfs.ext4 /dev/mmcblk0p2

6.簡單讀寫:cp,cat,echo等命令

eg:cp /usr/data/1.txt /mnt/sdcard/2.txt

cat /mnt/sdcard/test.c

echo "測試內(nèi)容" > /mnt/sdcard/test.txt

二:SD底層協(xié)議簡要介紹(由于SD NAND和SD卡遵守相同協(xié)議,并且標準協(xié)議中使用SD卡來描述,因此以下用詞使用SD卡代替SD NAND)

此處是為下面介紹讀寫方式準備協(xié)議的理論知識,僅做簡要介紹以及提醒一些需要注意的點,完整的協(xié)議內(nèi)容較多,詳細請參考SD2.0協(xié)議標準完整版(參考附件);

SD驅(qū)動中最重要的部分就是初始化,這里描述一下初始化流程,(需要區(qū)別四類卡,SDHC卡,SDSC卡,SD1.X卡,mmc卡)先是給SD卡上電,通常這一步在將卡插入卡槽就會自動完成,然后是發(fā)送CMD0進行軟復(fù)位,進入空閑模式,再發(fā)送CMD8,主機詢問SD卡是否支持電壓范圍,(SD1.X和mmc卡不會對CMD8產(chǎn)生響應(yīng),只有SDHC和SDSC卡會對CMD8回復(fù)R1響應(yīng));如果不響應(yīng)再區(qū)分SD1.X和mmc卡,發(fā)送ACMD41(先發(fā)送CMD55告訴SD卡接下來發(fā)送的是應(yīng)用命令),如果不響應(yīng)就說明是mmc卡(此時發(fā)送CMD1激活mmc卡,mmc卡響應(yīng)后即完成mmc卡的初始化),如果回復(fù)R1相應(yīng)就說明是V1.X卡;

收到R1響應(yīng)再區(qū)分SDHC和SDSC,然后發(fā)送ACMD41,主機告訴SD卡支持高容量,根據(jù)返回的R3響應(yīng)中的OCR寄存器來判斷是標準還是高容量,只有當busy位置1時CCS位才有效,CCS位為1是高容量V2.0卡(即SDHC卡),CCS位為0是標準V2.0卡(即SDSC卡),至此區(qū)分出了V1.X,標準V2.0,高容量V2.0卡,這三種卡接下來的步驟一致:

發(fā)送CMD2獲取CID寄存器的值,SD卡會回復(fù)R2響應(yīng),再發(fā)送CMD3,SD卡獲得相對地址,流程圖如下圖所示:

wKgZPGioL9SAVEviAAMo-VuNNpk144.png

然后是數(shù)據(jù)傳輸模式,初始化完成后進行數(shù)據(jù)傳輸就相對簡單了,只需要發(fā)送對應(yīng)的命令即可,流程圖如下:

wKgZO2ioL9WAYRtaAAKmxZ2lRR0695.png

下面附上常用命令以及響應(yīng)的圖:

wKgZPGioL9WAeHBRAAQFMYuz6Cs115.png

wKgZO2ioL9WAGkIMAAFeF_6RdjI376.png

最后提醒幾個需要注意的點:

第一是上電之后有一個時間段叫“供電上升時間”,這個是電壓上升到操作的總線電平以及等到能發(fā)送第一條命令的時間,這個時間需要在1ms,74個時鐘周期以及供電上升時間這三者中取最大值,其實這點在驅(qū)動源碼中也有體現(xiàn),在mmc_power_up函數(shù)(drivers/mmc/core/core.c)如下圖所示,同時在協(xié)議的6.4.1章節(jié)也有說明,這個時間如果沒有等待而直接開始發(fā)送命令進行初始化,可能也能通過初始化,但是在后面的數(shù)據(jù)傳輸階段就有概率會出現(xiàn)問題了,如果沒有注意到這個供電上升時間,那么其實出現(xiàn)了異常是很難定位問題的;

wKgZPGioL9aAASwkAALG7Avd4Cc894.png

第二是SD卡的兩種數(shù)據(jù)包格式,分別是常規(guī)數(shù)據(jù)和寬位數(shù)據(jù),常規(guī)數(shù)據(jù)是指普通的8bit字節(jié)數(shù)據(jù),發(fā)送規(guī)則是先發(fā)低字節(jié)再發(fā)高字節(jié),每個字節(jié)是先發(fā)高位后發(fā)低位;而寬位數(shù)據(jù)一般指SD卡存儲寄存器,規(guī)則是先發(fā)高位,后發(fā)低位, 這點在解析SD卡寄存器時需要格外注意,否則就會發(fā)現(xiàn)解析的數(shù)據(jù)明顯不符規(guī)范;

wKgZO2ioL9aAa_YqAAcIeYSQcZ4096.png

三:對SD NAND進行讀寫操作的三大方式

SD NAND作為一種存儲設(shè)備,不外乎就是讀和寫,同時這也是最重要的,熟悉讀寫方式對于使用SD NAND開發(fā)非常有幫助,因此在這一塊會詳細介紹;

第一:使用dd命令:

1.使用前先掛載分區(qū)的文件系統(tǒng)(常用于寫入普通文件)

sudo dd if=輸入文件 of=輸出文件 bs=塊大小 status=狀態(tài)信息 其他選項參數(shù)

eg:sudo dd if=/mnt/sdcard/test.doc of=backup.doc bs=1M count=1

//將/mnt/sdcard/test.doc的前1M字節(jié)寫入backup.doc;

2.使用前不掛載分區(qū)的文件系統(tǒng)(常用于寫入鏡像文件,備份或擦除整個SD NAND等)

sudo dd if=輸入設(shè)備 of=輸出設(shè)備 bs=塊大小 status=狀態(tài)信息 其他選項參數(shù)

eg:sudo dd if=sd_back_up.img of=/dev/mmcblk0 bs=4M status=progress

//將sd_back_up.img以4MB的塊大小寫入/dev/mmcblk0,同時顯示進度和速度

sudo dd if=/dev/mmcblk1p1 of=/root/zboot.img bs=4M status=progress

//將mmcblk1p1設(shè)備中的所有數(shù)據(jù)讀取到/root/zboot.img文件下

如果要對讀取的數(shù)據(jù)進行限制,只讀取部分數(shù)據(jù),那么使用參數(shù)skip或者count

sudo dd if=/dev/sdX of=/path/to/output.img bs=4M skip=10 status=progress

//skip:跳過前10個塊再開始讀取數(shù)據(jù)

sudo dd if=/dev/sdX of=/path/to/output.img bs=4M count=20 status=progress

//count:只讀取20個塊的數(shù)據(jù)

也可以結(jié)合skip和count,實現(xiàn)從特定位置讀取指定數(shù)量的數(shù)據(jù)

;

?。。∽⒁猓喝羰褂们安粧燧d分區(qū),那么在寫入之前請備份SD NAND內(nèi)重要數(shù)據(jù),因為不掛載是繞過文件系統(tǒng)對原始存儲設(shè)備直接操作,會完全忽略文件系統(tǒng)結(jié)構(gòu),很可能會覆蓋已有數(shù)據(jù),甚至可能會損壞文件系統(tǒng),嚴重的話只能重新格式化;

如果是先掛載了分區(qū),那么dd命令會通過文件系統(tǒng)進行操作,相對安全;

第二:使用塊設(shè)備的標準接口,通過文件io或標準io進行讀寫,無論是掛載文件系統(tǒng)還是不掛載文件系統(tǒng),都能使用文件io或標準io對SD NAND進行操作,區(qū)別是前者通過文件系統(tǒng)較為安全且效率稍低而后者直接操作硬件存儲設(shè)備效率更高同時對于數(shù)據(jù)的寫入需要更加注意防止覆蓋重要數(shù)據(jù),下面分別提供兩個示例;

第一個示例:使用標準io(fopen,fwrite,fread,fseek,fclose等)在已掛載文件系統(tǒng)的SD NAND上進行讀寫,總所周知,在linux里流傳著一句話,那就是“一切皆文件”,在這種情況下操作掛載點的文件其實與操作一般文件基本無異;示例實現(xiàn)的功能是在SD卡掛載目錄/mnt/sdcard/目錄下創(chuàng)建test_data.txt文件,然后再往里面寫入4次0~255,然后再將數(shù)據(jù)讀取出來驗證是否寫入成功并打印測試結(jié)果;

編譯命令是aarch64-linux-gnu-gcc test2.c -o test2,編譯成功后使用sftp root@ip將test2發(fā)送至開發(fā)板運行測試,運行結(jié)果以及程序見下面兩張圖;

wKgZPGioL9eACfLXAANxzLVKcBI354.png

wKgZO2ioL9eAQpjVAAOhAaFSduc780.png

第二個示例:使用文件io(open,write,read,lseek,close)對未掛載文件系統(tǒng)的SD NAND直接操作;實現(xiàn)的功能是從SD NAND的第1000塊開始寫入512字節(jié)數(shù)據(jù),數(shù)據(jù)內(nèi)容為0~255,0~255,寫入后再把數(shù)據(jù)讀取出來比較是否成功并打印結(jié)果;

編譯命令是:aarch64-linux-gnu-gcc test.c -o test,編譯成功后使用sftp root@ip將test2發(fā)送至開發(fā)板運行測試,運行結(jié)果和程序也如下面兩張圖所示

wKgZPGioL9eAJiClAASI_kkoIGM892.png

wKgZO2ioL9iATqnfAARoXEoCSr4885.png

第三:使用ioctl產(chǎn)生系統(tǒng)調(diào)用,陷入內(nèi)核進行處理,前兩種方式都容易實現(xiàn),而且不需要關(guān)注底層發(fā)送的命令,而ioctl可以對SD NAND進行精細的命令控制來約束NAND的行為,并且在ioctl使用過程中還有一些需要注意的點,如果想要對SD NAND進行最為底層的命令操作,那么ioctl必定是是首選,因此著重介紹這種方式;

使用ioctl來對SD NAND發(fā)送命令,其中最為重要的就是填充struct mmc_ioc_cmd結(jié)構(gòu)體,結(jié)構(gòu)體的詳細定義位于kernel/include/uapi/linux/mmc/ioctl.h,其中關(guān)于flags即命令標志位掩碼的定義位于/include/linux/mmc/core.h文件中的struct mmc_command結(jié)構(gòu)體中,下面對struct mmc_ioc_cmd結(jié)構(gòu)體的各成員作詳細介紹,如下圖所示:

wKgZPGioL9iAO1YaAAZfyOC4rO0615.png

介紹完struct mmc_ioc_cmd結(jié)構(gòu)體后細心的小伙伴會發(fā)現(xiàn)了這里面幾乎所有的參數(shù)都好填充,唯獨flags,命令標志位掩碼的定義在core.h中,如下圖所示:

wKgZO2ioL9mAedzsAAZX1myE8MM988.png

那么在編寫ioctl的程序時,填充flags需要用到core.h里面的內(nèi)容,總所周知,linux里面的隔離是很嚴重的,在應(yīng)用層調(diào)用內(nèi)核層的定義,這是不允許的,編譯會報錯,之前剛開發(fā)的時候因為這個編譯報錯還折騰了不少時間,最終的解決辦法就是把這些標志位的宏定義復(fù)制到自己寫的應(yīng)用程序中,這樣就沒有報錯了,下面提供一份程序

程序較長,文件名是init.c(見附件),編譯命令是:aarch64-linux-gnu-gcc init.c -o init,編譯成功后使用sftp root@ip(若有adb功能也可使用adb push)將可執(zhí)行程序init發(fā)送至開發(fā)板進行運行測試,文件中包含ioctl使用的詳細解釋,下面三張圖是運行結(jié)果截圖(前兩張)以及使用邏輯分析儀抓取的命令(第三張圖),波形文件名是:init.TLW,見附件,兩者都與程序一致,運行過程中沒有報錯,這就是使用ioctl向SD NAND發(fā)送底層命令的詳細過程;

wKgZPGioL9mASTL7AAmVk6pYw9I256.png

wKgZO2ioL9qAM-iqABzl20O1uhU368.png

wKgZPGioL9uAcoisAARf0z7anas569.png

關(guān)于ioctl的使用,有下面幾點需要格外注意,這些都是小編親身走過的坑,所謂前人栽樹,后人乘涼, 也算方便大家“乘涼”了哈哈;

第一是如果進行的是寫操作,例如發(fā)送CMD24,CMD25等命令,那么struct mmc_ioc_cmd結(jié)構(gòu)體的write_flag必須要賦值為非零值,如果是0值,那么很容易導(dǎo)致發(fā)送命令失敗,得到“errno=110 (Connection timed out)”的錯誤信息,這個錯誤信息相對常見,意為連接超時,分析函數(shù)調(diào)用鏈可知:在__mmc_blk_ioctl_cmd(drivers/mmc/core/block.c)函數(shù)中有

wKgZO2ioL9uAM6pcAABFDcDBpCw393.png

根據(jù)write_flag的值會進一步增加MMC_DATA_WRITE或MMC_DATA_READ的標志再傳到驅(qū)動中,因此發(fā)送寫命令時請務(wù)必給write_flag賦非零值;

第二是在SD卡初始化完成后,開始數(shù)據(jù)傳輸前,需要發(fā)送ACMD6定義數(shù)據(jù)總線的寬度,分析源碼可知:在mmc_sd_init_card(drivers/mmc/core/sd.c)函數(shù)中有如下圖所示部分

wKgZPGioL9yAZ1L3AAFOzWiSpbg888.png

SD和主機通常都是同時支持4位數(shù)據(jù)總線寬度的,在不修改SD驅(qū)動的情況下,主機控制器是4位總線寬度,所以如果不發(fā)送ACMD6,那么卡會保持默認的1位總線寬度,此時主機和NAND的總線寬度不一致,就會出現(xiàn)“errno=84 (Invalid or incomplete multibyte or wide character)”的錯誤信息,含義是無效或不完整的多字節(jié)或?qū)捵址鉀Q辦法有兩種,一種是修改驅(qū)動源碼,將主機控制器的總線寬度固定為1位,此時可以不發(fā)送ACMD6,主機和 SD NAND都使用1位數(shù)據(jù)總線通信,第二種是發(fā)送ACMD6通知卡改變總線寬度為4位,兩者都用4位總線傳輸數(shù)據(jù),ACMD6的參數(shù)說明如下圖,很明顯要第二種方式更簡單,因此如果遇到errno=84的錯誤碼,檢查一下主機和SD NAND的總線寬度是否一致;

wKgZO2ioL9yAS0qVAAEs-AHUd04192.png

第三是頻率問題,如果使用ioctl發(fā)送cmd時,檢查了命令和各項參數(shù)都沒有錯,也沒犯上面兩種錯誤,但是運行程序發(fā)現(xiàn)就是會報各種錯,例如下圖(運行的是示例程序init)

wKgZPGioL9yAVOi7AAp2sWly10Q380.png

那么很大概率就是頻率太高,SD NAND接受不了,此時需要降頻,如下圖

wKgZO2ioL92AewE3AAUPheNzJ3o395.png

降低頻率后再次運行,運行結(jié)果見下圖

wKgZPGioL92Aez5jAA2d5T-upfc632.png

只要多加注意以上三點,相信使用ioctl就沒有什么大問題;

四:SD NAND的驅(qū)動框架介紹(以瑞芯微平臺的RK3568驅(qū)動源碼為例)

第一:MMC/SD驅(qū)動在linux中的結(jié)構(gòu)層次

通常在linux系統(tǒng)中,MMC/SD設(shè)備都是被抽象成塊設(shè)備來處理,在kernel的頂層目錄下的drivers/mmc目錄下通常有三個文件夾分別是core、card和host,有些驅(qū)動會將core和card合并成一個core,例如RK3568就是只有core和host,這個驅(qū)動框架就是以RK平臺的SD驅(qū)動來介紹的,下面解釋三個文件夾的作用;

1.card層:要把操作的數(shù)據(jù)以塊設(shè)備的處理方式寫到存儲設(shè)備上或從存儲設(shè)備上讀??;因為SD NAND屬于塊設(shè)備,那么必然要提供塊設(shè)備的驅(qū)動程序,這部分就是解決了一個問題,即如何將你的SD NAND實現(xiàn)為塊設(shè)備的。

2.core 層:則是將數(shù)據(jù)以何種格式,何種方式在 MMC/SD主機控制器與MMC/SD卡的記 憶體(即塊設(shè)備)之間進行傳遞,這種格式、方式被稱之為規(guī)范或協(xié)議.

這部分完成了不同協(xié)議和規(guī)范的實現(xiàn),抽離出不同SD主機控制器的共性,并為HOST 層的驅(qū)動提供了接口函數(shù)

3.host 層:是這個文件夾屬于 Linux 內(nèi)核中 MMC/SD 子系統(tǒng) 的 硬件驅(qū)動層,直接負責與 MMC/SD 主機控制器(Host Controller) 的硬件交互。它的核心作用是向上提供統(tǒng)一的接口供 Core 層 調(diào)用(如發(fā)送命令、讀寫數(shù)據(jù)),向下為不同廠商的 Host 控制器提供驅(qū)動實現(xiàn),將上層(Core 層)的協(xié)議請求轉(zhuǎn)換為具體的寄存器操作、時鐘控制、DMA 傳輸?shù)扔布袨椤?/p>

core層根據(jù)協(xié)議規(guī)范來構(gòu)造各種命令,那么命令是怎么發(fā)送給SD NAND呢?通過主機控制器。

主機控制器通過設(shè)置SD需要的gpio資源,注冊中斷資源,使能控制器等等,然后再向上面的核心層增加一個host,這樣核心層就能調(diào)用具體的硬件操作函數(shù)來和SD卡通信了;

card和core是封裝好的共性以及規(guī)范,通常是不需要修改的,而host層是直接與硬件打交道,需要控制底層寄存器的,不同的host控制器硬件資源也不一樣,因此驅(qū)動SD NAND,host層才是應(yīng)該需要修改開發(fā)的,MMC/SD驅(qū)動在linux中的結(jié)構(gòu)層次見下圖:

wKgZO2ioL96AOQGDAADojQIT9MY176.png

第二:SD驅(qū)動中核心的數(shù)據(jù)結(jié)構(gòu)舉例(SD NAND和SD卡在驅(qū)動中使用的數(shù)據(jù)結(jié)構(gòu)和調(diào)用的函數(shù)是一致的,并且有不少數(shù)據(jù)結(jié)構(gòu)命名或函數(shù)功能注釋翻譯過來用SD卡描述更貼切,因此下面描述用詞使用SD卡代替SD NAND,不再贅述)

1.struct mmc_host

功能:表示一個MMC/SD卡主機控制器,它是驅(qū)動程序和內(nèi)核MMC子系統(tǒng)之間的主要接口;

重要成員:

const struct mmc_host_ops *ops:包含操作該主機的各種函數(shù)指針,包括發(fā)送命令,設(shè)置時鐘和電源,請求操作等,用于和硬件交互

struct device class_dev:代表該主機控制器的設(shè)備對象,可用于設(shè)備模型的注冊和管理

unsigned int f_min:主機控制器支持的最小時鐘頻率

unsigned int f_max:主機控制器支持的最大時鐘頻率,對于SD卡的操作頻率非常重要

struct mmc_card *card:指向插入該主機的SD卡設(shè)備

struct mmc_ios ios:包含了當前IO的狀態(tài)信息,例如時鐘頻率,電壓范圍,電源模式等

const struct mmc_bus_ops *bus_ops:指向struct mmc_bus_ops結(jié)構(gòu)體,定義了和MMC卡通信的操作集,例如讀寫,卡檢測等;

u32 ocr_avail:存儲MMC主機可用的操作條件寄存器OCR的值,

u32 caps:表示MMC主機的能力和特性,通過不同的位來標記主機的各種模式;

2. struct mmc_card

功能:表示一個插入到MMC主機控制器的SD卡設(shè)備

重要成員:

struct mmc_host *host:指向SD卡所連接的主機控制器

unsigned int rca:相對卡地址,是SD卡的重要標識符,用于在總線上唯一標識該卡

unsigned int type:卡類型,例如MMC,SD,SDIO等,用于區(qū)分不同的設(shè)備類型

u32 ocr:操作條件寄存器,包含了SD卡的操作條件信息,例如支持的電壓范圍,電源模式等;

struct mmc_cid cid:包含卡的CID信息,例如制造商id,產(chǎn)品名稱等;

3. struct mmc_ios

功能:包含SD主機控制器的IO狀態(tài)信息

重要成員:

unsigned int clock:當前的時鐘頻率,驅(qū)動可以根據(jù)需要調(diào)整此時鐘頻率,來滿足不同操作的需求;

unsigned char power_mode:電源模式,例如MMC_POWER_OFF,MMC_POWER_UP,用于控制SD卡的電源狀態(tài)

unsigned char bus_width:總線寬度,可以選擇1線,4線,8線,根據(jù)SD卡的能力和操作需求進行調(diào)整

4. struct mmc_host_ops

功能:包含了操作MMC主機控制器的一系列函數(shù)指針,是驅(qū)動程序與硬件交互的接口;

重要成員舉例:

void (*request)(struct mmc_host *host, struct mmc_request *req):函數(shù)指針,用于將一個操作請求添加到主機控制器的請求隊列中

void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios):用于設(shè)置主機控制器的IO狀態(tài),例如調(diào)整時鐘頻率,電源模式和總線寬度等等;

int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios):在需要切換SD卡的操作電壓時調(diào)用此函數(shù);

int (*get_ro)(struct mmc_host *host):檢查MMC/SD卡是否被寫保護了;

int (*get_cd)(struct mmc_host *host):檢查SD卡的插入和拔出;

5. struct mmc_request

功能:表示一個對SD卡的操作請求,通常包括命令,數(shù)據(jù)傳輸?shù)刃畔ⅲ?/p>

重要成員:

struct mmc_command *cmd:指向要執(zhí)行的命令;

struct mmc_data *data:指向要傳輸?shù)臄?shù)據(jù)對象,用于數(shù)據(jù)塊的讀寫操作;

第三:host層函數(shù)調(diào)用關(guān)系解析

wKgZPGioL96AV2qUAAUMMlMHUHw255.png

這里主要做了兩件事,其一是mmc_alloc_host分配一個mmc_host,其二是mmc_add_host添加一個mmc_host;

第四:卡的檢測

wKgZO2ioL96AZrPSAAJOxs7W5A4283.png

我們用的SD卡只是一張卡,要操作卡還得通過主機控制器才行,因此會有struct mmc_card,struct mmc_host之分,截至這里再回憶一下dw_mci_init_slot做的事情,大概就是準備一個 mmc_host 結(jié)構(gòu),然后添加一個主控制器設(shè)備到內(nèi)核,最后又調(diào)用了一下 mmc_rescan 來檢測是不是有卡插入了,有人會問如果此時卡沒有插入呢,那么不就是白白調(diào)用一次mmc_rescan,那下次卡插入又是怎么檢測到的呢,很明顯,這種不能確定觸發(fā)時間的完全未知的動作,肯定是需要通過中斷機制來處理,檢測到卡插入,觸發(fā)中斷,掃描卡,開始初始化等流程,檢測到卡拔出觸發(fā)中斷,清理各類資源,釋放空間;

第五:掃描流程

wKgZPGioL9-AaIiEAAIxWOPDd-U376.png

wKgZO2ioL-CAO8viAAEf3Hjdb0s654.png

struct mmc_card 結(jié)構(gòu)里面包含了一個 struct device 結(jié)構(gòu), mmc_alloc_card 不但申請了內(nèi)存,而且還填充了 struct device 中的幾個成員,尤其 card->dev.bus = &mmc_bus_type; 這一句要重點對待,mmc_bus_type的定義如下圖

wKgZPGioL-CACDQzAACR65eCLOs264.png

申請一個 mmc_card 結(jié)構(gòu),并簡單初始化后, mmc_init_card 的使命就完成了,然后再調(diào)用 mmc_add_card 將這個 card 設(shè)備添加到內(nèi)核。 mmc_add_card 其實很簡單,就是調(diào)用 device_add 將 card->dev 添加到內(nèi)核當中去;

device_add 里面,設(shè)備對應(yīng)的總線會拿著你這個設(shè)備和掛在這個總線上的所有驅(qū)動程序去匹配( match ),此時會調(diào)用 match 函數(shù)(如下圖),如果匹配到了就會調(diào)用總線的 probe 函數(shù)或驅(qū)動的 probe 函數(shù);

wKgZO2ioL-CAKNFbAAA_O1TB9j8066.png

所以match永遠不會失敗,匹配成功就會執(zhí)行mmc_bus_probe(定義見下圖)

wKgZPGioL-GAO_HWAABt3f-qQQA014.png

追蹤到這里,probe由調(diào)用了drv->probe(),這就需要知道drv的定義了,struct mmc_driver*drv=to_mmc_driver(dev->driver);match 函數(shù)總是返回 1 ,說明掛在這條總線上的 driver 都有可能跑到這里來了,事實的確也是這樣的,不過好在掛在這條總線上的 driver 只有一個,定義見下圖:

wKgZO2ioL-GAIJyAAABm6MVDWGE936.png

因此跳轉(zhuǎn)到mmc_bllk_probe函數(shù)執(zhí)行,函數(shù)定義如下:

wKgZPGioL-GAJu1VAANwb-tAgbg167.png

mmc_blk_probe是 MMC 塊設(shè)備驅(qū)動的核心探測函數(shù),負責將 MMC/SD 卡注冊為塊設(shè)備,使其能夠被系統(tǒng)訪問,看到這里已經(jīng)把core,host目錄下的文件都牽扯進來了,慢慢再捋一下就能看出從host到core的聯(lián)系了;


第五:數(shù)據(jù)的讀寫

在驅(qū)動中,向SD卡發(fā)送cmd都是通過請求隊列來完成的,所有的cmd都會被封裝成請求,然后由內(nèi)核的I/O調(diào)度器統(tǒng)一排序,合并或拆分,再下發(fā)給硬件驅(qū)動,這樣避免了驅(qū)動直接操作硬件,而是通過標準接口解耦,增強了安全性和可維護性,所以分析cmd的發(fā)送首先要定位到request請求隊列,關(guān)鍵函數(shù)調(diào)用流程如下圖:

wKgZO2ioL-KAODfPAAKzrej0reg669.png

順便附上上圖中提到的兩個ops操作集合的賦值:

wKgZPGioL-KACoWoAAB5dBGPzoo455.png

wKgZO2ioL-KAf3urAAEqCuH-aJA002.png

分析到這里,整個SD驅(qū)動框架做的事情說簡單一些其實就干了兩件事,一是卡的掃描檢測,而是數(shù)據(jù)的讀寫,不過這個過程中涉及到的數(shù)據(jù)結(jié)構(gòu)和函數(shù)調(diào)用確實相對復(fù)雜,捋清楚驅(qū)動框架還是需要靜下心來花費時間的;

五:SD NAND啟動

相同的板卡廠商一般SD NAND啟動的流程固定,大致講一下流程,首先是要制作SD啟動卡,即將啟動鏡像燒錄進SD NAND,一般板卡廠商都會有專門的制作工具,只需按照使用方法來制作啟動卡即可,如果沒有制作工具,那么一般使用dd命令將系統(tǒng)鏡像寫入卡內(nèi)(寫入時可能有地址參數(shù)要求,需要咨詢板卡廠商的技術(shù)支持),然后是選擇啟動方式,一般是有幾個boot引腳,啟動時系統(tǒng)會根據(jù)boot引腳的電平組合來選擇啟動方式,有些開發(fā)板可能在選擇SD NAND啟動時還需要配置其他內(nèi)核參數(shù),只需咨詢對應(yīng)的技術(shù)即可,最后就是驗證系統(tǒng)是否能正常從SD啟動,數(shù)據(jù)讀寫是否正常;


首先是君正平臺,開發(fā)板是x2600e,SD NAND是采用CS256G-AOW;

第一:制作SD啟動卡

君正的燒錄工具支持將啟動鏡像燒錄到SD NAND,先編譯準備好啟動鏡像,然后按照下圖順序進行制作啟動卡;

wKgZPGioL-OAGg55AADaw9g45GQ975.png

wKgZO2ioL-OAEUS6AAC69rPuLaQ880.png

wKgZPGioL-OAe6UtAADmUg8u3TM130.png

wKgZO2ioL-OAelh8AAB-yzA6ZHs093.png

wKgZPGioL-SAbGreAACpQ8d5_38259.png

第二:選擇啟動方式

查詢芯片手冊得知啟動方式的選擇依據(jù)如下圖

wKgZO2ioL-SAScCoAAKi_L6bKgc426.png

再查看原理圖如下:

wKgZPGioL-SAcabHAAB21KiRc4Q086.png

可知目前的電平組合是001,即選擇的是SFC@PD06_3.3V(默認從SPI NAND FLASH啟動),現(xiàn)在需要改為從SD啟動,那么就要將BOOT_SET0即PD14接低電平,使得電平組合為000,然后就是查看PCB,找到PD14的gpio,再修改硬件將其接地即可;

第三:驗證SD啟動

wKgZO2ioL-SASCSIAAPkkeAsvnQ346.png

通過上圖可知,系統(tǒng)成功從SD NAND啟動,然后使用一些簡單的讀寫命令驗證是否正常即可,一般而言只要能正常啟動系統(tǒng)讀寫就沒問題,因為啟動過程中本身就已經(jīng)包含了對SD進行讀寫。

然后就是瑞芯微平臺,開發(fā)板是RK3568,SD NAND采用CS256G-AOW,也采取相同步驟;

第一:制作SD啟動卡

首先編譯準備好鏡像文件,并將其拷貝到windows端(可以將鏡像放置共享目錄下),然后打開瑞芯微的制作工具SDDiskTool,按照下圖所示進行配置:

wKgZPGioL-WAXsnnAADBgR-jees763.png

wKgZO2ioL-WAYn7eAAB9MUkqJZg785.png

wKgZPGioL-WAXfvGAADVOCr8tZU930.png

正常來說制作過程是2~3分鐘,但是也遇到過十分鐘左右的,這個可能因SD NAND而異,但是只要沒報錯,就耐心等待制作完成;

第二:選擇啟動方式

由于咨詢技術(shù)支持得到的答復(fù)是RK對于啟動引導(dǎo)不開源,原理也是靠硬件選boot腳,然后在芯片手冊上也沒找到有關(guān)boot引腳配置的部分,所以說明在RK上我們不需要修改硬件,額外配置boot引腳來選擇啟動方式,后面在rockchip-common.h文件中找到了關(guān)于啟動方式的優(yōu)先順序,如下圖:

wKgZO2ioL-aAWZzVAACUUPNWuXQ404.png

因此只要啟動時在卡槽檢測到SD NAND,那么就會優(yōu)先從SD啟動;

第三:驗證SD啟動

wKgZPGioL-aAc85nAAQ4JWzuyKE821.png

wKgZO2ioL-aAXsbWAAHgX8tuIIY143.png

從上面兩張圖中可以相互印證,系統(tǒng)成功從SD啟動;

啟動卡的分區(qū)情況如下圖:

wKgZPGioL-eAbLdZAAZC9ZtM_4o796.png

從mmcblk1p1至mmcblk1p6共6個分區(qū),依次是uboot,misc,boot,recovery,backup和rootfs,前面5個分區(qū)一般存儲特定數(shù)據(jù),不建議用戶將數(shù)據(jù)寫入,而mmcblk1p6是根文件系統(tǒng)分區(qū),存儲所有系統(tǒng)文件、應(yīng)用程序、用戶數(shù)據(jù)等,進行用戶操作時就是基于這個分區(qū),因此進行讀寫測試或者存儲用戶數(shù)據(jù)建議在此分區(qū)進行。

最后分享一些使用的軟件:

串口工具:Windows下:MobaXterm;Ubuntu下:Minicom

分析內(nèi)核源碼:sourceinsight4

邏輯分析儀:ATK-Logic 或Acute TravelLogic Analyzer

除了軟件,硬件上的邏輯分析儀,示波器萬用表也可輔助調(diào)試驗證。

附件:

wKgZPGioL-eABOFvAABdKaaa-mU235.png

親愛的卡友們,歡迎光臨雷龍官網(wǎng),如果看完文章之后還是有疑惑或不懂的地方,請聯(lián)系我們

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • SD
    SD
    +關(guān)注

    關(guān)注

    1

    文章

    172

    瀏覽量

    35329
  • 瑞芯微
    +關(guān)注

    關(guān)注

    26

    文章

    671

    瀏覽量

    53231
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    這幾年為啥那么火?

    自己畫板子淘寶賣,他當時選用的主控,大多都是全志的芯片(也有三星處理器的方案)。 我接觸CPU的時間比較晚,大概是2018年的時候
    發(fā)表于 10-20 15:50

    CS創(chuàng)世SD NAND北京平臺RK平臺的應(yīng)用

    各位工程師,你們好,我是alan,今天就平臺北京
    發(fā)表于 08-22 17:01

    CS SD NAND AI領(lǐng)域的應(yīng)用和注意事項

    隨著ChatGPT,DeepSeek等AI模型的火熱,AI的應(yīng)用硬件也發(fā)展迅速。很多廠商針對特定市場推出了AI產(chǎn)品。研發(fā)這些產(chǎn)品的時候,有不少客戶選擇了CS SD NAND作為AI產(chǎn)
    的頭像 發(fā)表于 08-15 17:56 ?492次閱讀

    RK3576與RK3576S有什么區(qū)別,性能參數(shù)配置與型號差異解析

    第二代8nm高性能AIOT平臺RK3576家族再添新成員-RK3576S,先說結(jié)論:相較主
    的頭像 發(fā)表于 08-14 23:57 ?1448次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b><b class='flag-5'>RK</b>3576與<b class='flag-5'>RK</b>3576S有什么區(qū)別,性能參數(shù)配置與型號差異解析

    揭秘算力協(xié)處理器,RK3576/RK3588強大算力搭檔

    算力協(xié)處理器-Gongga1(簡稱“貢嘎”),是針對旗艦芯片
    的頭像 發(fā)表于 07-17 10:00 ?663次閱讀
    揭秘<b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b>算力協(xié)處理器,<b class='flag-5'>RK</b>3576/<b class='flag-5'>RK</b>3588強大算力搭檔

    有獎丨米爾 RK3562開發(fā)板免費試用新增名額!

    米爾與合作發(fā)布的新品基于RK3562應(yīng)用
    的頭像 發(fā)表于 06-13 08:04 ?750次閱讀
    有獎丨米爾 <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b><b class='flag-5'>RK</b>3562開發(fā)板免費試用新增名額!

    米爾多核異構(gòu)低功耗RK3506核心板重磅發(fā)布

    近日,米爾電子發(fā)布MYC-YR3506核心板和開發(fā)板,基于國產(chǎn)新一代入門級工業(yè)處理器RK3506,這款芯片采用三核Cortex-A7+單核Cortex-M0多核異構(gòu)設(shè)計,不僅擁有
    發(fā)表于 05-16 17:20

    創(chuàng)世CS SD NAND 8GByte產(chǎn)品特性介紹#芯片 #SDNAND #8GB #CS創(chuàng)世 #存儲

    NAND
    深圳市雷龍發(fā)展有限公司
    發(fā)布于 :2025年04月24日 17:50:09

    CS創(chuàng)世SD NAND【貼片式sd卡】的測試使用說明

    今天收到了來自深圳市雷龍發(fā)展有限公司寄來的存儲卡,它是一款自帶壞塊管理的貼片式NAND Flash,適用于嵌入式系統(tǒng)。SD NAND尺寸小巧,支持SPI/SD接口,兼容各大MCU
    的頭像 發(fā)表于 02-17 15:45 ?667次閱讀
    <b class='flag-5'>CS</b><b class='flag-5'>創(chuàng)世</b><b class='flag-5'>SD</b> <b class='flag-5'>NAND</b>【貼片式<b class='flag-5'>sd</b>卡】的測試使用說明

    CS創(chuàng)世SD NAND【貼片式sd卡】的測試使用說明

      今天收到了來自深圳市雷龍發(fā)展有限公司寄來的存儲卡,它是一款自帶壞塊管理的貼片式NAND Flash,適用于嵌入式系統(tǒng)。SD NAND尺寸小巧,支持SPI/SD接口,兼容各大MCU
    發(fā)表于 02-12 15:05

    全新芯片平臺RK3506優(yōu)勢詳解,高集成低功耗,為工業(yè)而生 深圳觸覺智能評測

    RK3506是Rockchip2024年第四季度全新推出的Arm嵌入式芯片平臺,三核Co
    的頭像 發(fā)表于 12-28 10:23 ?2167次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b>全新芯片<b class='flag-5'>平臺</b><b class='flag-5'>RK</b>3506優(yōu)勢詳解,高集成低功耗,為工業(yè)而生 深圳觸覺智能評測

    平臺Android系統(tǒng)串口測試方法,觸覺智能RK3562開發(fā)板演示

    方案主板Android系統(tǒng)串口測試方法,通用RK3568、RK3566、RK3588、
    的頭像 發(fā)表于 12-24 11:51 ?1297次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>芯</b><b class='flag-5'>微</b><b class='flag-5'>平臺</b>Android系統(tǒng)串口測試方法,觸覺智能<b class='flag-5'>RK</b>3562開發(fā)板演示

    關(guān)于SD NAND 的概述

    。   雷龍科技旗下的CS創(chuàng)世品牌自2016年成立以來,一直專注于采用國際先進的芯片設(shè)計和技術(shù),結(jié)合本地化的生產(chǎn)和制造優(yōu)勢,為客戶提供高品質(zhì)的產(chǎn)品和服務(wù)。眾多產(chǎn)品中,CS
    發(fā)表于 12-06 11:22

    微電子與BlackBerry QNX合作開發(fā)汽車數(shù)字座艙平臺

    近日,中國創(chuàng)新型AIoT芯片解決方案供應(yīng)商微電子有限公司(以下簡稱為)宣布,基于
    的頭像 發(fā)表于 11-30 14:07 ?1939次閱讀

    RK3568 USB驅(qū)動

    RK3568 USB驅(qū)動程序
    發(fā)表于 11-11 14:18 ?18次下載