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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

uboot环境下mmc操作_【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程

發(fā)布時間:2024/10/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uboot环境下mmc操作_【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【記錄】將Uboot 2011.06中mmc驅(qū)動移植到uboot 1.1.6的過程

時間:2011-8-14

作者:crifan

聯(lián)系方式:green-waste (at) 163.com

附上代碼:

【背景】

硬件:

(1)TQ2440,CPU是S3C2440,帶SD/MMC控制器。

(2)自己的金士頓的1GB的SD卡

軟件:

(1)TQ2440的uboot 1.1.6

(2)自己已經(jīng)移植舊的mmc的驅(qū)動成功,可以實現(xiàn)mmcinfo, fatls mmc 0, fatload mmc 0 addr file,但是舊的mmc中檢測出來的sd卡的容量不對,原因是由于READ_BL_LEN是15,大于12了,用的計算方法是錯誤的。

詳情參見:

【記錄】在TQ2440的uboot中添加SD/MMC支持+添加USB Mass Storage支持+解決fatls亂碼問題

【目的】

想要實現(xiàn)正確檢測我的1GB的SD卡的容量,所以要把正確的mmc驅(qū)動移植過來。

而目前最新的uboot 2011.06版本的中,已經(jīng)有最新的mmc驅(qū)動,但是和uboot 1.1.6比,mmc的整個架構(gòu)都變了,需要把mmc部分,整個都改了,再添加對應(yīng)的底層函數(shù),才可以。

【將Uboot 2011.06中mmc驅(qū)動移植到uboot 1.1.6的全過程】

1.添加文件,修改makefile等準(zhǔn)備工作

先是把mmc最直接相關(guān)的cmd_mmc.c,整個替換了

這樣就支持了更多的mmc相關(guān)的命令了:

mmcinfo

mmc rescan

mmc part

mmc list

mmc dev

fatls mmc 0

fatload mmc 0 addr filename

同時,替換了最新的mmc.h頭文件,該文件包含了對應(yīng)的sd/mmc所有的命令等定義。

由于舊的uboot中在board.c的start_armboot()中沒有mmc初始化部分,所以也要填上對應(yīng)內(nèi)容:#ifdef CONFIG_GENERIC_MMC

puts(“MMC:“);

mmc_initialize(gd->bd);

#endif

而后再去添加對應(yīng)的makefile等,使得編譯通過,不多細說。

2. s3c_mmc_init()

用beyondcompare,將uboot 2011.06和uboot 1.1.6相比較,發(fā)現(xiàn)新的mmc驅(qū)動框架中,主要實現(xiàn)幾個核心函數(shù)即可,此處我的sd/mmc控制器是三星的S3C2440的,所以簡稱為s3c,對應(yīng)的第一個要實現(xiàn)的函數(shù)為:/* this is a weak define that we are overriding */

int board_mmc_init(bd_t *bd)

{

return s3c_mmc_init(bd);

}

中的:s3c_mmc_init()

其中,主要是初始化mmc中一些核心的參數(shù),主要代碼是:mmc->send_cmd = s3cmmc_send_cmd;

mmc->set_ios = s3cmmc_set_ios;

mmc->init = s3cmmc_init;

將掛上發(fā)送命令,設(shè)置總線寬度/頻率等,初始化三個函數(shù)的指針

mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS;

告訴sd host支持4bit模式 即High Speed即50MHz模式

mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;

此處電壓是參考其他驅(qū)動寫上的,具體含義沒有深入去了解

mmc->f_max = get_PCLK();

mmc->f_min = 400*1000;

設(shè)置所支持的最大和最小頻率

mmc->block_dev.part_type = PART_TYPE_DOS;

設(shè)置sd卡分區(qū)的類型是DOS,即常見的FAT分區(qū)

mmc->b_max = 0;

設(shè)置最大的block數(shù)目,0為沒限制,mmc系統(tǒng)會自動初始化

都設(shè)置好了,再去調(diào)用

mmc_register(mmc);

上述內(nèi)容都設(shè)置好了,然后就是分別去實現(xiàn)上述三個核心的函數(shù):

3. s3cmmc_init()

init函數(shù)中,主要就是初始化sd的硬件相關(guān)的部分

其主要代碼和之前舊的差不多,只是把blocksize設(shè)置,頻率設(shè)置,等等,都放到了setios函數(shù)或者send_cmd函數(shù)中了而已,沒有太多需要解釋的,參考之前代碼即可。

4. s3cmmc_set_ios()

set_ios中,主要就是兩個:

(1)當(dāng)傳入的參數(shù)中clock不為0時候,去根據(jù)所需要的頻率去設(shè)置對應(yīng)的SDIPRE寄存器即可;

(2) 根據(jù)傳入的總線寬度,此處即1或者4,1就是最開始的默認的,4就是對應(yīng)的wide bus,設(shè)置對應(yīng)的SDIDCON寄存器即可。

5. s3cmmc_send_cmd()

發(fā)送命令,這個函數(shù)可以個大頭,需要花不少精力的。

通過看uboot 2011.06中其他mmc驅(qū)動的實現(xiàn),大概看懂了此處,mmc發(fā)送命令的函數(shù),其實處理了兩個事情,一個是發(fā)送普通命令,二是對于數(shù)據(jù)的讀寫,其實也是通過發(fā)送對應(yīng)對應(yīng)的命令,然后讀寫對應(yīng)數(shù)據(jù)的。

即普通的發(fā)送命令,只需要發(fā)送命令即可;

而包括數(shù)據(jù)讀寫的命令,參數(shù)是放在data中的,data不為空的時候,就不僅僅要發(fā)送對應(yīng)的命令,還要接著讀寫數(shù)據(jù)的。

此處暫時不去實現(xiàn)數(shù)據(jù)的write,只考慮read的情況,目的是實現(xiàn)相關(guān)的命令fatls mmc 0和fatload mmc 0 addr file。

(1)單純的發(fā)送命令

關(guān)于發(fā)送命令,之前也已經(jīng)有了對應(yīng)的函數(shù)send_cmd,把舊函數(shù),拿過來,改一下,也基本就實現(xiàn)了。

【關(guān)于發(fā)送命令之后的response】

另外需要提及一點的是,如果發(fā)送命令需要反饋response的,對于

cmd->resp_type中有MMC_RSP_PRESENT的,那么至少要返回一個response,而如果是長的response,即MMC_RSP_136,是需要返回四個response的,詳情參考代碼。

【使用readl/writel時候,需要傳入寄存器的地址而不是寄存器的值】

另外還有點要說明的,對于用writel/readl,readb/writeb等函數(shù)來代替直接寄存器操作的,傳入的寄存器地址,是需要是地址的,而不能是寄存器的值,即:

原先讀一個寄存器:csta = sdi->SDICSTA;

現(xiàn)在用readl時,要傳入寄存器的地址,要這樣調(diào)用:csta = readl(&sdi->SDICSTA);

而不能是csta = readl(sdi->SDICSTA);

關(guān)于這點,也是參考了別的代碼和調(diào)試,才發(fā)現(xiàn)這點的。

【詭異問題:S3C2410_SDICMDCON_SENDERHOST的含義】

不過,這里在調(diào)試代碼過程中,發(fā)現(xiàn)一個有點詭異的問題,那就是,對于設(shè)置command control寄存器的時候,原先代碼是:

ccon |=S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;

其中

#define S3C2410_SDICMDCON_SENDERHOST(1<<6)

但是對應(yīng)的S3C2410和S3C2440的datasheet中,都沒有提到這一點,而只是網(wǎng)上這些S3C2410和S3C2440的sd卡驅(qū)動的參考代碼,包括uboot和kernel中的,卻有這個位的設(shè)置,而如果去掉這一位的設(shè)置,命令就無法正常發(fā)送。

雖然看名字S3C2410_SDICMDCON_SENDERHOST知道大概是host是sender,但是對于這一位的具體含義是什么,還是不懂,希望如果有知情的可以解釋一下。

(2)帶讀數(shù)據(jù)的命令的發(fā)送和之后的數(shù)據(jù)讀取

但是對于帶讀數(shù)據(jù)的命令的發(fā)送,包括MMC_CMD_READ_MULTIPLE_BLOCK=CMD17讀塊數(shù)據(jù)和MMC_CMD_SEND_EXT_CSD=CMD8讀擴展CSD等等,就不僅僅要先發(fā)送命令,還要接著讀對應(yīng)的數(shù)據(jù)才可以的。

對于read block等命令,其處理的時候,要先設(shè)置好datasize寄存器,

再根據(jù)之前設(shè)置的SDIDCON中的bus width是1還是4,決定設(shè)置數(shù)據(jù)控制寄存器中是S3C2440_SDIDCON_DS_WORD還是S3C2440_SDIDCON_DS_BYTE,

等設(shè)置好了SDIDCON之后,接著再去發(fā)送對應(yīng)的帶數(shù)據(jù)讀的命令,然后接著處理的流程和之前舊的代碼是一樣的,即先去fifosta中找到fifo中有多少個數(shù)據(jù),然后一個個讀取,每次讀取1個字節(jié)還是4個字節(jié),由之前的bus width決定。

等讀完當(dāng)前fifo了再去重復(fù)讀取fifosta,再去判斷有多少個字節(jié)數(shù)據(jù)需要讀取,

這樣一點點把數(shù)據(jù)讀出來即可。

讀數(shù)據(jù)的過程中,需要通過讀取SDIDSTA得知數(shù)據(jù)的狀態(tài)是否正常,如果有錯誤,比如超時,CRC錯誤等,就退出。

此部分流程,基本和舊的代碼沒太大區(qū)別。

但是代碼調(diào)試過程中,這部分代碼,在讀取數(shù)據(jù)部分,始終出錯,讓我調(diào)試了很久,最后找到原因,竟然是自己不小心,在讀取了SDIDCON的值后,忘了把原來的bus width那一位給設(shè)置回去,所以再之前去設(shè)置bus width=4=word之后,此處還是用bus width=1=byte的模式來讀數(shù)據(jù),所以出現(xiàn)第一次讀SDIFSTA而獲得的FIFO中的字節(jié)數(shù),竟然是有奇數(shù)的,比如0x1c7,而不是期望的64啊之類的,應(yīng)該是4的倍數(shù)的,最后加上對應(yīng)的正確的設(shè)置后,后面的讀取數(shù)據(jù)就都對了。

【未解決的疑問:CMD8和CMD13超時】

在最后可以成功讀數(shù)據(jù)之后,卻也還是發(fā)現(xiàn)有兩個命令會超時:

MMC CMD8 Timeout

MMC CMD13 Timeout

具體原因未知。有待后期再去找原因,或者哪個高手告知一下原因。

最后貼上可以成功檢測出我的1GB的SD卡的log信息:EmbedSky> help mmc

mmc read addr blk# cnt

mmc write addr blk# cnt

mmc rescan

mmc part – lists available partition on current mmc device

mmc dev [dev] [part] – show or set current mmc device [partition]

mmc list – lists available devices

EmbedSky> mmcinfo

MMC CMD8 Timeout

MMC CMD13 Timeout

Status Error: 0x002D0032

Device: TQ2440 SD/MMC

Manufacturer ID: 2

OEM: 544d

Name: SD01G

Tran Speed: 25000000

Rd Block Len: 512

SD version 1.10

High Capacity: No

Capacity: 982.5 MB

Bus Width: 4-bit

EmbedSky> mmc rescan

MMC CMD8 Timeout

MMC CMD13 Timeout

Status Error: 0x002D0032

EmbedSky> mmc part

Partition Map for UNKNOWN device 0—Partition Type: DOS

PartitionStart SectorNum SectorsType

124320119176

EmbedSky> mmc dev

mmc0 is current device

EmbedSky> mmc list

TQ2440 SD/MMC: 0

EmbedSky> fatls mmc 0

MMC CMD13 Timeout

512nikon001.dsc

misc/

dcim/

3701fisrttest.html

2 file(s), 2 dir(s)

總結(jié)

以上是生活随笔為你收集整理的uboot环境下mmc操作_【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。