MMCSD卡驱动程序设计40通信10123赵翔41.docx
- 文档编号:3526172
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:29
- 大小:2.54MB
MMCSD卡驱动程序设计40通信10123赵翔41.docx
《MMCSD卡驱动程序设计40通信10123赵翔41.docx》由会员分享,可在线阅读,更多相关《MMCSD卡驱动程序设计40通信10123赵翔41.docx(29页珍藏版)》请在冰豆网上搜索。
MMCSD卡驱动程序设计40通信10123赵翔41
ARM嵌入式系统课程设计
--MMC/SD卡驱动程序设计
班级:
通信1001
学号:
3100601023
姓名:
赵翔
指导老师:
曹清华
课程设计时间:
2013.6.24---2012.6.30
江苏大学
第一章引言
1.1课程设计目地1
第二章课程设计平台构建与流程2
2.1嵌入式系统开发平台构建2
2.2课程设计流程2
2.3课程设计硬件结构与工作原理2
第三章Bootloader移植与下载4
3.1源代码安装4
3.2源代码分析移植与编译4
3.3下载4
第四章Linux内核移植与下载6
4.1Linux内核源代码安装6
4.2Linux内核源代码分析与移植6
4.3Linux内核编译与下载6
第五章课程设计功能模块驱动程序设计15
5.1MMC/SD卡模块注册初始化:
15
5.2设备文件操作接口定义15
5.3MMC接口初始化16
5.4GPIO初始化函数16
5.5SD移除操作函数17
5.6读数据块操作18
5.7写数据块操作19
第六章根文件系统建立与文件系统下载20
6.1根文件系统分析20
6.2文件系统映像文件生成21
6.3文件系统下载22
6.4功能模块运行与调试23
第七章完成课堂上布置地三个思考题26
第八章课程设计总结与体会28
8.1课程设计中遇到地问题以及解决方法28
8.2总结和体会28
第一章引言
1.1课程设计目地
1)了解PXA27X微处理器GPIO地功能
2)了解MMC卡驱动程序地架构及编程方法
3)掌握MMC卡地使用方法
1.2课程设计任务与要求
1)理解基于Linux地嵌入式系统交叉开发环境,对嵌入式系统地开发流程有详细地了解;
2)掌握开发工具链地构建方法,能独立进行系统开发操作;
3)掌握Linux地常用命令,在linux系统下能熟练地使用这些常用命令;
4)熟悉linux内核地知识以及原理,掌握定制Linux内核地方法;
5)基于Linux操作系统,以及XSBase270ARM实验开发平台一套,把MMC存储卡挂载目标板上并进行文件地复制操作.
第二章课程设计平台构建与流程
2.1嵌入式系统开发平台构建
1)装有Linux操作系统地PC机一台;
2)XSBase270ARM实验开发平台一套
3)MMC存储卡一块
2.2课程设计流程
1)Bootloader移植与下载
2)Linux内核移植与下载
3)功能模块程序设计与交叉编译
4)根文件系统建立与文件系统下载
2.3课程设计硬件结构与工作原理
1)目标板地MMC卡硬件接口
目标板地MMC/SD卡地硬件接口如图1.1所示,根据PXA27x地MMC/SD/SDIO控制器地信号功能以及PXA27x地GPIO地功能分配,命令控制线MMCMD与GPIO112相连,此时引脚GPIO112必须配置成转换功能1(AlternateFunction1)地输入或输出方式(具体参考PXA27X开发手册),时钟端MMCLK利用了通用IO口GPIO32转换功能1输出方式,4位总线MMDAT0到MMDAT3分别与GPIO111、GPIO110、GPIO109和GPIO92相连,都时使用了通用IO口地转换功能1地输入或输出方式.图1.2为MMC/SD卡地供电电路图.
图1.1目标板地MMC/SD卡地硬件接口
图1.2MMC/SD卡地供电电路图
2)PXA270地MMC/SD/SDIO控制器
PXA270地MMC/SD/SDIO控制器在访问PXA270处理器地软件与MMC存储堆和支持MMC、SD及SDIO通信协议之间充当联结作用.PXA27x地MMC控制器协议规范遵守多媒体卡系统规范V3.2(MultiMediaCardSystemSpecificationVersion3.2);MMC/SD/SDIO控制器采用标准地MMC传输协议或串行通信接口SPI协议模式.访问PXA270地软件使用MMC传输协议或SPI模式作为与MMC控制器通信地协议.目标板地SD驱动程序采用了MMC通信传输协议.
3)MMC卡地通信协议
主机与MMC卡地所有通信都是由主机发起,主机发出广播和点对点两种类型通信命令,在广播通信命令中,主机发出地命令被所有地卡接受,只有部分命令需要响应;而在点对点通信命令中,命令被发送到具体地址地卡中,并由该卡对所接受地命令做出响应.
第三章Bootloader移植与下载
3.1源代码安装
先将D:
\emdor\EELiod_V4_SDK目录下地Linux-2.4复制到虚拟机里root地主文件夹中,然后用如下指令进行解压:
利用上述命令解压后,bootloader源代码解压到当前目录中Boot-XSBase270文件夹中.
3.2源代码分析移植与编译
在解压地目录里进行make编译.
[root@localhostBootLoader]$cdBoot-XSBase270
root@ubuntu:
Boot-XSBase270#makeclean
[root@localhostBoot-XSBase270]$make
编译完成后,在当前目录下会生成bootloader映象文件boot.
3.3下载
打开实验台电源,启动H-JTAG和H-Flasher,在H-Flasher中装载配置文件pxa270.hfc,点击Programming中地Check,ScrFile选择D:
\emdor\EELiod_V4_SDK\Linux-2.4\images\中地boot文件,点击Program,烧写成功后点击Verify校验.
第四章Linux内核移植与下载
4.1Linux内核源代码安装
内核解压
4.2Linux内核源代码分析与移植
Linux提供三个不同地命令进行Linux地配置,效果完全一样:
makeconfig控制台命令行方式配置命令
makemenuconfig文本菜单方式配置命令
makexconfigX窗口图形界面方式配置命令
其他部分命令:
Makemrproper命令清除所有地旧地配置和旧地编译目标文件等.
Makedep命令搜索Linux编译输出与源代码之间地依赖关系、并生成依赖文件.
Makeclean清除以前构造内核时生成地所有目标文件、模块文件和临时文件.
MakezImage编译Linux内核,生成压缩地内核映像文件.
4.3Linux内核编译与下载
1)内核解压
2)内核配置
Linux针对MMC/SD内核配置地步骤:
(1)在主菜单下选择Loadablemodulesupport--->[*]EnableLoadablemoduLeSupport
利用模块可将不常用地设备驱动或功能作为模块放在内核外部,必要时动态地调用.操作结束后从内存中删除,这样可以有效地使用内存,同时也可减小了内核地大小.模块可以自行编译并具有独立地功能,即使需要改变模块地功能,也不用对整个内核进行修改.文件系统,设备驱动,二进制格式等很多功能都支持模块.一定要选择[*].(按空格键)
[]SetversioninformationonallSymbolsformodules
利用这个功能能够让内核使用其它内核版本模块或没有包含在此kernel地特殊地模块.一般选择[N].
[*]KernelmoduleLoader
这个设置使kernel对模块处于常备状态.在不使用Insmod或rmmod命令情况下,kernel程序自动将需要
执行地模块调用到内存中,一定时间内不使用该模块时自动将其从内存删除,一般要选择[*].
(2)再回到主菜单下选择Generalsetup―――>选择“Supportforhot-pluggabledevices”,出现“MMC/SDdevicedrivers”:
点击“MMC/SDdevicedrivers”,进入下一页选择:
用向下地箭头,选择LoadanAlternaeConfigurationFile选项,
输入配置文件名arch\arm\def‐configs\xsbase270,退出并保存.
2)配置完成后,重新编译内核,需要输入以下指令:
生成地zImage存放路径为:
将zImage拷贝到tftpboot文件夹下:
3)内核烧写
重新打开一个终端,输入命令:
root@ubuntu:
~#minicom
然后重启开发板电源,
看到Boot启动信息后按任意键启动Boot地OperationMenu,我们需要用这个boot内嵌工具下载内核.
然后再提示信息Pleaseenteryourselection后面输入2,获取本地IP地址:
可以看到OperationMenu菜单上方显示:
Myipaddressis192.168.0.50,则表示板载Linux与Ubuntu服务器连接成功.
输入3,下载内核文件ZImage(在Ubuntu地文件系统地/tftpboot/目录中)下载成功后选择4,烧写内核.
第五章课程设计功能模块驱动程序设计
5.1MMC/SD卡模块注册初始化:
staticint__devinitmmc_pxa_module_init(void)
{
intret=-ENODEV。
#ifdefCONFIG_ARCH_RAMSES
RAMSES_MMC_ON()。
udelay(1000)。
#endif
host=mmc_register(MMC_REG_TYPE_HOST,&pxa_mmc_controller_tmpl_rec,
sizeof(pxa_mmc_hostdata_rec_t))。
//registertheSDdevice
if(!
host){
MMC_DEBUG(MMC_DEBUG_LEVEL0,"failedtoregisterwithMMCcore\n")。
gotoerror。
}
ret=0。
error:
returnret。
}
5.2设备文件操作接口定义
staticmmc_controller_tmpl_rec_tpxa_mmc_controller_tmpl_rec={
owner:
THIS_MODULE,
name:
"PXA250",
block_size_max:
PXA_MMC_BLKSZ_MAX,
nob_max:
PXA_MMC_NOB_MAX,
probe:
pxa_mmc_probe,
init:
pxa_mmc_init,
remove:
__devexit_p(pxa_mmc_remove),
update_acq:
pxa_mmc_update_acq,
init_card_stack:
pxa_mmc_init_card_stack,
check_card_stack:
pxa_mmc_check_card_stack,
setup_card:
pxa_mmc_setup_card,
stream_read:
pxa_mmc_stream_read,
read_block:
pxa_mmc_read_block,
read_mblock:
pxa_mmc_read_mblock,
stream_write:
pxa_mmc_stream_write,
write_block:
pxa_mmc_write_block,
write_mblock:
pxa_mmc_write_mblock
}。
5.3MMC接口初始化
staticintpxa_mmc_init(mmc_controller_tctrlr)
{
intret=-ENODEV。
pxa_mmc_hostdata_thostdata=(pxa_mmc_hostdata_t)ctrlr->host_data。
/*1.allocatebuffer*/
hostdata->iobuf.iodata=kmalloc(PXA_MMC_IODATA_SIZE,GFP_ATOMIC)。
//2K
if(!
hostdata->iobuf.iodata){
ret=-ENOMEM。
gotoerror。
}
/*2.initializeiobuf*/
hostdata->iobuf.blksz=PXA_MMC_BLKSZ_MAX。
/*currentblocksizeinbytes1024*/
hostdata->iobuf.bufsz=PXA_MMC_IODATA_SIZE。
/*buffersizeforeachtransfer*/
hostdata->iobuf.nob=PXA_MMC_BLOCKS_PER_BUFFER。
/*numberofblocks*/
/*3requestirq*/
if(request_irq(IRQ_MMC,pxa_mmc_irq,0,"MMC",ctrlr)){
MMC_ERROR("failedtorequestIRQ_MMC\n")。
gotoerror。
}
/*4initGPIOaboutMMC/SD/SDIO*/
init_gpio()。
CKEN|=CKEN12_MMC。
/*enableMMCunitclock*/
ret=0。
gotoout。
error:
kfree(hostdata->iobuf.iodata)。
out:
returnret。
}
5.4GPIO初始化函数
staticvoidinit_gpio(void)
{
GPCR1|=0x1。
//clearpin32
GPDR1=GPDR1|(1<<0)。
//configpin32asoutput
GAFR1_L=(GAFR1_L&0xfffffffc)|(2<<0)。
//)pin32isusedforfunction2->MMCLK
//MMDAT0PIN92
GPSR2|=0x10000000。
//pin92configuredasanoutput,setpinlevelhigh(one).
GPDR2|=0x10000000。
//pin92asoutput
//GPDR2=GPDR2&~(1<<28)。
GAFR2_U=(GAFR2_U&0xfcffffff)|(1<<24)。
//pin32isusedforfunction1->MMDAT<0>
//MMDAT1PIN109
GPSR3|=(1<<13)。
GPDR3|=(1<<13)。
GAFR3_L=(GAFR3_L&0xf3ffffff)|(1<<26)。
//MMDAT2PIN110
GPSR3|=(1<<14)。
GPDR3|=(1<<14)。
GAFR3_L=(GAFR3_L&0xcfffffff)|(1<<28)。
//MMDAT3PIN111
GPSR3|=(1<<15)。
GPDR3|=(1<<15)。
GAFR3_L=(GAFR3_L&0x3fffffff)|(1<<30)。
//MMCMDPIN112
GPSR3|=0x00010000。
GPDR3|=0x00010000。
//GPDR3=GPDR3&~(1<<16)。
GAFR3_U=(GAFR3_U&0xfffffffc)|(1<<0)。
//function1
GPSR3|=0x0000e000。
//PIN111-PIN109
GPDR3|=0x0000e000。
GAFR3_L=(GAFR3_L&0x03ffffff)|0x54000000。
}
5.5SD移除操作函数
//removetheMMCthenfreesystemresource
staticvoidpxa_mmc_remove(mmc_controller_tctrlr)
{
pxa_mmc_hostdata_thostdata=(pxa_mmc_hostdata_t)ctrlr->host_data。
kfree(hostdata->iobuf.iodata)。
/*1)freebuffer(s)*/
free_irq(IRQ_MMC,ctrlr)。
/*1)releaseirq*/
CKEN&=~CKEN12_MMC。
/*disableMMCunitclock*/
}
5.6读数据块操作
staticintpxa_mmc_read_block(mmc_controller_tctrlr,mmc_data_transfer_req_ttransfer)
{
intret=-ENODEV。
u16argh=0UL,argl=0UL。
/*sendCMD16(SET_BLOCK_LEN)whenrequestedblocksizeisnotthedefault
*forthecurrentcard*/
if(transfer->blksz!
=ctrlr->stack.selected->info.read_bl_len){
argh=transfer->blksz>>16。
argl=transfer->blksz。
if((ret=pxa_mmc_stop_bus_clock(ctrlr)))
gotoerror。
MMC_CMD=CMD(16)。
/*SET_BLOCK_LEN*/
MMC_ARGH=argh。
MMC_ARGL=argl。
MMC_CMDAT=MMC_CMDAT_R1。
MMC_DEBUG(MMC_DEBUG_LEVEL3,"CMD16(0x%04x%04x)\n",argh,argl)。
if((ret=pxa_mmc_complete_cmd(ctrlr,MMC_R1,FALSE)))
gotoerror。
}
/*CMD17(READ_SINGLE_BLOCK)*/
argh=transfer->addr>>16。
argl=transfer->addr。
if((ret=pxa_mmc_stop_bus_clock(ctrlr)))
gotoerror。
MMC_CMD=CMD(17)。
/*READ_SINGLE_BLOCK*/
MMC_ARGH=argh。
MMC_ARGL=argl。
MMC_CMDAT=MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN。
MMC_NOB=1。
MMC_BLKLEN=transfer->blksz。
MMC_DEBUG(MMC_DEBUG_LEVEL3,"CMD17(0x%04x%04x)\n",argh,argl)。
if((ret=pxa_mmc_complete_cmd(ctrlr,MMC_R1,FALSE)))
gotoerror。
/*transferthedatatothecallersuppliedbuffer*/
if((ret=pxa_mmc_read_buffer(ctrlr,transfer->blksz))<0)//transfer->blksz
gotoerror。
if((ret=pxa_mmc_copy_from_buffer(ctrlr,transfer->type,transfer->buf,ret))<0)
gotoerror。
transfer->buf+=ret。
transfer->cnt-=ret。
transfer->nob-=1。
pxa_mmc_set_state(ctrlr,PXA_MMC_FSM_END_IO)。
if((ret=pxa_mmc_complete_io(ctrlr,transfer->cmd,transfer->mode)))
gotoerror。
ret=0。
error:
returnret。
}
5.7写数据块操作
staticintpxa_mmc_write_block(mmc_controller_tctrlr,mmc_data_transfer_req_ttransfer)
{
intret=-ENODEV。
u16argh=0UL,argl=0UL。
/*sendCMD16(SET_BLOCK_LEN)whenrequestedblocksizeisnotthedefault*forthecurrentcard*/
if(transfer->blksz!
=ctrlr->stack.selected->info.read_bl_len){
argh=transfer->blksz>>16。
argl=transfer->blksz。
if((ret=pxa_mmc_stop_bus_clock(ctrlr)))
gotoerror。
MMC_CMD=CMD(16)。
/*SET_BLOCK_LEN*/
MMC_ARGH=argh。
MMC_ARGL=argl。
MMC_CMDAT=MMC_CMDAT_R1。
MMC_DEBUG(MMC_DEBUG_LEVEL3,"CMD16(0x%04x%04x)\n",argh,argl)。
if((ret=pxa_mmc_complete_cmd(ctrlr,MMC_R1,FAL
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MMCSD 驱动程序 设计 40 通信 10123 赵翔 41