您的位置:首页 > 其它

嵌入式启动方式-从Nand启动cpu .下(2)(学习整理笔记)

2013-04-12 22:49 387 查看
嵌入式启动方式-从Nand启动cpu .下(2)(学习整理笔记)

上一篇中我们借助2864A成功合并了数据与程序存储空间

但受硬件的限制,我们无法再用这种设计结构来应对大容量的程序存储运行

----------------------------------------------------------------

虽然找不到大容量2864A的替代品时,而市面上普通计算机的内存却从256M飙升到了8G,硬盘也上升到以T来计算,程序代码也越来越大,那他们是怎么解决问题的?

首先分析硬盘:它存储空间大,可读写,掉电不丢失,与2864A的特性很像,似乎能加以改造,但致命的是它的读写速度慢,严重拖累cpu的取指令,也就拖累了程序的执行。所以不可用来代替。

再分析内存:它的存储空间也很大,可读写,但是掉电数据丢失,可它的读写速度快,而且数据地址接口和之前的设计模式中差不多(其实它就是数据存储器的扩容和速度提升),所以选用它非常合适,但必须解决数据丢失的问题。

---------------------------------------------------------------------

一 ,先假设内存能够保存数据,假设它掉电不丢失

那么毫无疑问,之前的合并模式不需做太多改动,直接用个几G的内存代替2864A就可以了。

可事实是内存掉电丢失数据:但我们可以用一个折中的办法。

1既然内存保存不了数据,那我们就添加一个存储设备A来保存内存中程序段的数据。

所以每次通电启动的时候,只要让cpu从这个存储器A中把程序数据复制到内存中制定的代码段中,机器就能正常执行了。

启动前:

存储器A 内存

程序指令区 代码段(无数据)

启动中:
存储器A 内存

程序指令区 -> 代码段(从A复制多条指令数据过来 术语:程序加载)

启动后: 1
存储器A 内存

程序指令区 代码段(pc指针->地址->运行)

(等待状态) 数据段

2
存储器A 内存

程序指令区 代码段( 继续执行)

数据存储区 <- 数据段 (需保存的运行结果返回到A存储器)

掉电后: 存储器A 内存

程序指令区 (已保存 ) 代码段( 数据丢失)

数据存储区 (已保存 ) 数据段 (数据丢失)

类似于电脑启动:

做好硬件的初始化工作,然后将要运行程序从硬盘复制到内存中,pc指向内存的地址,cpu从内存的代码段取指令(内存的数据读写速度快),执行过程中将要保存的数据又可以保存到硬盘里,掉电就不会丢失了。

(这里没有考虑到内存映射及高速缓存等,由简单的讲起)

-----------------------------------------------------------------------------------------------------------

综上所诉,内存完全充当了程序和数据存储器,正如单片机的在线仿真开发一样,我们既然借助传输协议能够从计算机硬盘复制数据到单片机的2864中,同样的我们在用内存代替了2864以后,也同样可以从计算机硬盘复制数据到单片机的内存中。

而再进一步的升级是:我们不借助计算机硬盘,而是直接给单片机加装一个类似硬盘的寄存器B(掉电不丢失),这样这个单片机即有了自己的硬盘和内存,也同样能执行指令,就相当于一台小计算机了,而继续扩张它的其他功能比普通单片机强,比计算机体积小,也就是一种嵌入式结构了。

设计结构是由简入繁,计算机中很多东西并没有用到完美的解决方式,看似很傻瓜的解决办法就是计算机的最好解决办法。计算机的软件和硬件变的复杂化,那是因为即便我们有很好很简单的设计结构,但硬件达不到要求也就无法实施,如果内存能存储数据又能无限扩大容量,而且掉电不丢失,那还用硬盘做什么。如果内存的读写速度和cpu一样快就不需要高速缓冲区了,如果内存能直接对存储的数据做运算,那连cpu也省了。因为没有这些如果,所以我们只能按实际的硬件来学习和分析。

-----------------------------------------------------------------------

二 ,接着看嵌入式的启动如何结合硬件实现

《嵌入式linux应用开发完全手册》142页 图8.15 97页 图6.4 88页 图6.1 都展示了启动过程

预习知识:

总线:数据,地址,控制线等

BANK:笼统的来说bank0~bank7就是8个存储器,用总线来连接和控制它们,就像火车的8节车厢一样(一节装不下就用多节),连接到一起就组成一个大的连续的存储空间。它们分别有不同的空间地址,其中有一部分是做内存空间,有一部分是特殊寄存器空间,还有其他功能。



NAND:一种存储器,掉电不丢失数据,相当于计算机的硬盘。

--------------------------------------------------------------------------------------------------

先从已知结构入手:BANK 的地址及空间

BANK0: 0x0000-0000



BANK1: 0x0800-0000

............



BANK6: 0x3000-0000



BANK7: 0x3800-0000

特别注意0x0000-0000和0x3000-0000这两个地址。

在NAND启动方式下,再做对比

steppingstone: 0x0000-0000 ~4096 这里128M容量的BANK存储器被一个4Kb的

存储器替换掉了。



BANK1: 0x0800-0000

............

BANK6: 0x3000-0000

BANK7: 0x3800-0000

依照之前的说法:一般启动后cpu从0x0000-0000地址取指令,也就是原来BANK的地址0位开始取值 可是从NAND启动有所差别。

分析:

首先:BANK0 和steppingstone应该不是同一个存储器,BANK有128M而steppingstone只有4kb。

其次:根据单片机中内部程序存储器的启动原理:51单片机出厂时内部附带了一个程序存储器0x0000~0x0FFF,正好也是4kB,这让我们有理由怀疑嵌入式的steppingstone也是一个4kb的内部程序存储器

关于内部程序存储器之前可能没有提到过:一直在讲的是外部扩展的程序和数据存储器。

先看51单片机

cpu 外部程序存储器(一般都称为程序存储器,内部存储器的存在被忽略)

0x0000 0x000000

......... ..............

0x0FFF ..............

0xFFFFFF

可见cpu内部固定的程序存储器比外部扩展的容量要小的多,用到大的程序时,我们便会扩容使用外部程序存储器,前面所讲都是针对外部程序存储器。

在内,外两者中存在一段4k的地址重复冲突。

解决办法:

书中一段原话——对于有内部ROM的单片机,在正常运行时,应把EA‘引脚接高电平,使程序从内部ROM开始执行。当pc值超出内部ROM 的容量时,会自动转向外部程序存储空间。(这里pc加到0x1000就是外面的地址了)

转篇很不错的:http://www.elecfans.com/emb/danpianji/2009032938911.html

补充:原文:因为现在单片机都有内部ROM了,所以始终接高。但是似乎还有东西要考虑,比如下文中提到c编程还得考虑一段程序有可能一部分在内部存储器,另一部分在外部存储器,在写程序的时候得控制好地址(事实上在看过linux开发完全手册后,学过嵌入式启动后,很多疑问也能解决)

转: http://blog.csdn.net/slj_win/article/details/7416616

再看如果将EA接低,那么就等于是屏蔽了内部程序存储器,全部都从外部存储器开始执行。(这样看上去地址更像一个连续整体了,但对于复杂的单片机你不使用内部存储器已有的的引导及初始化程序,而是自己在外部存储器中重写个,那得有好的硬件功底,或者直接复制粘贴吧)

就网上的资料来看,部分单片机的复杂程度和嵌入式有的一拼了(远不是我们以前学的51那么简单),而嵌入式在功耗和体积上也在朝单片机靠拢,两者界限已不是那么分明了。

-------------------------------------------------------------------------------------------------

综合上述分析,我们大致可以认为嵌入式的NAND启动方式类似单片机的内部程序存储器启动方式。

1 单片机中pc指到内部程序存储器的0x0FFF地址,再加1就自动跳到外部存储器的地址0x1000了。

(也就是说外部存储器的0x000~0x0FFF段被内部屏蔽掉了,这就类似于嵌入式中BANK0被内部steppingstone屏蔽掉了)

值得注意的是,BANK0地址0x0000-0000~0x0800-0000都被屏蔽了,而不是只屏蔽4kb(嵌入式处理方式等于是直接把BANK0整块存储器屏蔽了)

2 单片机中从内部地址跳到外部地址是非常自然的连续的pc+1

(而嵌入式中内部程序存储器steppingstone的结束地址是0x0000-1000,0x0000-1000和BANK1的0x0800-0000可不连续,这就得在steppingstone程序的最后加跳转命令)

3 嵌入式还有一点不同,在2中,steppingston最后跳转的地址是BANK6 地址0x3000-0000,而不是BANK1的0x0800-0000.

在NAND启动方式下,再比较

steppingstone: 0x0000-0000 ~4096 这里128M容量的BANK存储器被一个4Kb的

存储器替换掉了。

从0x0000-0000执行第一条指令

.................

最后跳转到 0x3000-0000 (程序别超过4kb)



BANK1: 0x0800-0000

............

BANK6: 0x3000-0000

BANK7: 0x3800-0000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐