×

NAND Flash的系统构建资料下载

消耗积分:3 | 格式:pdf | 大小:133.04KB | 2021-04-17

张静

分享资料个

  达芬奇(Davinci)系列嵌入式处理器是TI公司的具有高速处理能力的新一代嵌入式设备[1],它同时具备了DSP和精简指令级计算机技术的优点。它集成了一个高性能的DSP核心与一个ARM9内核,被广泛应用于嵌入式图片、视频处理中[2]。在Davinci平台下,通常以ARM核为基础构建,但是目前经常采用一片NOR Flash加上一片NAND Flash作为外部存储设备,并且通常都是256 B/页或者512 B/页的小页面NAND Flash,本文旨在只以一片2 KB/页的大页面NAND Flash(Samsung K9K8G08U0A)作为外部存储设备、Davinci TMS320DM6446作为处理器的硬件结构下,阐述构建稳定可靠的系统需要解决的问题。   1 问题概述   F是用来连接Flash、SRAM等多种存储设备的外设端口。TMS320DM6446的EMIF端口支持每路32 MB总共4路可寻址的片选空间,支持8 bit以及16 bit的数据总线宽度,具有可编程的建立、选通以及保持时间,还具备NAND Flash ECC校验数据生成功能等[5],因此可以方便灵活地与外部NAND Flash芯片通信。在本文的硬件系统中,即采用TMS320DM6446的EMIF的CS2空间与Samsung K9K8G08U0A NAND Flash相连。   由于本系统只有一片NAND Flash作为外部的存储设备,因此所有的引导程序、操作系统内核以及根文件系统均需要存储在这上面,系统也就需要从NAND Flash启动。TMS320DM6446具有多种启动方式,具体由哪种方式启动,由系统复位时引脚BTSEL[1:0]电平决定,当BTSEL[1:0]被置为“01”时,TMS320DM6446的ARM核从EMIFA的EM_CS2存储空间开始执行(地址为0x0200 0000),这种情况下EMIF连接的是具有线性地址的非易失存储器,通常是NOR Flash。当BTSEL[1:0]不为“01”时,TMS320DM6446内部的ROM BOOT LOADER(简称RBL)开始运行,RBL再根据BTSEL[1:0]的不同值决定从何处加载用户的引导程序UBL(USER BOOT LOADER)。当BTSEL[1:0]为“00”时,RBL将从连接到EMIF的CS2空间的NAND Flash中加载UBL。由于RBL的加载过程是将UBL拷贝到ARM的内部RAM中,因此对于UBL的大小限制在14 KB以内,但是在嵌入式环境常用的U-BOOT、ViVi等的大小都远超过这个限制,因此需要多级加载,一级引导程序主要做系统的初始化,然后将二级引导程序(在本系统中采用U-BOOT,本文后面提到的UBL均指一级引导程序)从NAND Flash中读取到RAM中,然后启动它,由U-BOOT负责操作系统的引导[4]。于是整个NAND Flash上系统构建的关键问题包括如何移植UBL,以使其能够正常初始化系统,正常加载二级引导程序U-BOOT到RAM中,U-BOOT的移植使其满足大页面NAND Flash的读写要求以及裸机时引导程序的烧写。   2 UBL移植   UBL为TI公司提供的对于Davinci系列处理器通过内部的ROM BOOT LOADER启动时的一级引导程序。其工作流程如图1所示。      UBL的移植主要针对本系统中硬件板的结构修改系统初始化过程以及增加对Samsung K9K8G08U0A NAND Flash的支持,以下分别阐述。   2.1 系统初始化   2.1.1 设置CPU、DDR工作频率   TMS320DM6446具有两路PLL,其中PLL1通过分频供系统的主时钟及大部分外设的时钟,PLL2供DDR2使用。DSP时钟频率为SYSCLK1=27 MHz×(PLL1_PLLM+1),使用固定一分频,本系统中DSP工作在正常频率594 MHz,因此需设置PLL1_PLLM=21,即设置寄存器0x1C4 0910为21。   本系统使用两片K4T1G164QQ-HCE6 DDR2 SDRAM作为系统内存,该芯片为DDR2 667芯片,时钟频率为333 MHz。TMS320DM6446中DDR2使用PLL2的PLLDIV2分频作为时钟频率,计算公式为(27 MHz×(PLL2_PLLM+1))/(PLL2_PLLDIV2→RATIO+1)。因此设置PLL2_PLLM=23,PLL2_PLLDIV2→RATIO=1,PLL2_PLLDIV2的第15位为分频允许位,应置为1,所以PLL2_PLLDIV2为0x8001,即寄存器0x1C4 0D10=23,0x1C4 0D1C=0x8001。   2.1.2 配置EMIF接口   根据Samsung K9K8G08U0A NAND Flash的读、写时序要求,TMS320DM6446的EMIF用于与NAND Flash连接时,配置寄存器各字段值需满足如下要求:   RSETUP≥tCLR(m)/tCYC-1=0   RSTORBE≥max((tREA(m)+tSU)/tCYC,tRP(m)/tcyc)-1=1.5   R_SETUP+R_STROBE≥(tCEA(m)+tSU)/tcyc-1=2   R_HOLD≥(tH-tCHZ(m))/tcyc-1=-4   R_SETUP+R_STROBE+R_HOLD≥tRC(m)/tcyc-3=-0.5   TA≥max((tCHZ(m))/tcyc,(tRHZ(m)-(R_HOLD+1)tcyc)/(tcyc))-1≥2   W_SETUP≥max(tCLS(m)/tcyc,tALS(m)/tcyc,(tCS(m)/tcyc)-1=1   W_STROBE≥tWP(m)/tcyc-1=0.2   W_SETUP+W_STROBE≥tDS(m)/tcyc-1=0.2   W_HOLD≥max((tCLH(m))/(tcyc),(tALH(m))/tcyc,(tCH(m))/(tcyc),(tDH(m))/(tcyc))-1=-0.5   W_SETUP+W_STROBE+W_HOLD≥tWC(m)/(tcyc)-3=-0.5   其中tSU是EMIF数据建立时间,取值5 ns,tH数据保持时间取0,EMFI时钟为系统6分频,所以tcyc=1/(27×(21+1)/6)≈10 ns,根据EMIF连接NAND的取值要求,设置EMIF CS2的配置寄存器值为0x842429c。   2.2 支持Samsung K9K8G08U0A NAND Flash   UBL通过数据结构struct _NAND_DEV_STRUCT_来表示一个型号的NAND Flash,具有devID、numBlocks、pagesPerBlock、bytesPerPage几个字段。通过struct _NAND_   DEV_STRUCT_类型的数组gNandDevInfo[]来记录所有支持的NAND Flash。UBL在从NAND Flash读取数据之前,首先通过读取设备号命令0x90得到NAND Flash的设备号,然后从数组gNandDevInfo[]中查找具有相同设备号的记录,从而得到NAND Flash的详细信息,以确定NAND Flash的读方式。   因此,需要UBL支持特定的NAND Flash,只需要将其信息添加到数组gNandDevInfo[]中即可。本系统中用到的Samsung K9K8G08U0A NAND Flash设备号为0xD3,具有8 192个存储块,每个块具有64个页面,每页具有2 048 B数据存储区域以及64 B的Spare区域,在数组gNandDevInfo[]中添加{0xD3,8192,64,2048+64}即可。   3 U-BOOT移植   本系统中使用的U-BOOT引导程序由TI公司提供的支持Davinci平台以及NAND Flash启动的U-BOOT1.1.3移植而来。   3.1 NAND Flash读写时序   U-BOOT1.1.3不支持2 KB/page的大页面Flash,因此移植过程主要是增加NAND Flash的读写、擦除。2 KB页面NAND Flash与普通读写擦除最主要的区别在于地址构成不同,本系统中用到的Samsung K9K8G08U0A NAND Flash总共存储空间1 GB=230,每页大小为2 KB=211,因此总的地址长度30 bit,从A0~A29,页地址长度为11 bit,从A0~A10,本系统采用8 bit的地址数据宽度连接NAND Flash,页地址和块地址需要分不同的地址周期,因此NAND的地址需要5个周期送出,前两个周期为页地址,依次为地址的A0~A7、A8~A10,后三个周期为块地址,依次为地址的A11~A18、A19~A26、A27~A29,页地址和块地址的最后一个周期不足8位,不足的高位均为0。   Samsung K9K8G08U0A的读过程如下:写0x00命令、分5个周期写地址、写0x30命令、读数据、根据读出的数据生成ECC校验数据、生成的ECC数据与读出的ECC数据比对以确定数据是否有误以及能否校正。   写过程如下:写0x80命令、分5个地址周期写地址、送出数据(包括ECC校验数据)、写0x10命令、读取状态直到busy信号无效、检查是否出现写错误。   擦除过程如下:写0x60命令、分三个地址周期写块地址、写0xD0命令、读取状态直到busy信号无效、检查是否出现擦除错误。   3.2 YAFFS2文件系统烧写   YAFFS2镜像烧写与U-BOOT下普通写NAND Flash区别在于spare区域的数据不需要程序根据数据存储区的数据生成,spare区域的数据在制作YAFFS2镜像时,已经由镜像制作工具生成并写入了镜像文件。因此在nand命令的write中增加.yaffs2选项,当使用nand write.yaffs2命令时,直接从指定地址中读出2 048 B/页数据以及数据后紧跟的64 B的spare区域数据,并将其写入NAND Flash中。   U-BOOT在Flash的读写过程中需要检查坏块情况,在开始读写每个块的时候首先检查该块第一页以及第二页的spare区域的第一个数据是否为0xFF,如果不为0xFF则当前块为坏块,需要跳过它。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'NAND Flash的系统构建资料下载',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);