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

来源:互联网 发布:程序员选什么机械键盘 编辑:程序博客网 时间:2024/04/29 08:49

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

上一篇中是讲到51单片机中程序存储器和数据存储器严格分开的模式

虽然两个存储器件是被分开轮流执行的,但是总结发现两者基本结构(数据,地址线的接口数和访问方式相同)和存储单元(存储数据的位数)相同。

如此:既然形式差不多,程序与数据两者为何要被分开存储?

答:

       程序存储器的硬件特性是掉电后存储的数据不丢失(好比硬盘)

       数据存储器的硬件特性是掉电后存储的数据丢失(内存的特性)

      程序存储器正常工作时只能读,不能写(第一篇讲过的烧制过程是在加21v电压的特殊情况下,正常工作电压一般为1.5或3v)

      数据存储器正常工作时能读能写。

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

假设我们有一种存储器正常工作电压下既能够读写,又能掉电后数据不丢失,那么程序存储器和数据存储器是否能共用?

答:理论上可以,但这种硬件成本过高,而且读写速度比不上内存,所以在节省成本为目的的嵌入式硬件中不采用。

E2PROM:电擦除可编程只读存储器:支持在线修改,断电情况下保持修改结果: 2864A

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

那接下来要讨论的就是程序存储和数据存储合并的模式

2864A与 8051的连接:采用外部数据存储器空间和程序存储器空间合并的方法《MCS-51系列单片机系统及其应用 》第二版 113页

2864A的特性使它即可作为程序存储器,又作为数据存储器

即便我们更改了硬件结构使取指令和数据读写都共用同一个存储器和地址及数据线,但仍先要解决几个问题。

1.在之前提到的程序和数据存储器的地址空间都是0x00000~0xfffff;既然数据和程序都存放在一个空间,如何来解决访问冲突?

答:像单片机和嵌入式一般默认的启动取指令地址都是0x00000,那么假设我们将执行的程序指令存放到0x0000~0x70000;而数据变量则存放在0x70001~0xfffff不就可以了。

          

      2864A的存储空间分配:

                                   0x0000

                                   0x.......       程序代码段

                                   0x7000

                                   0x7001

                                   0x........      数据段

                                   0xffff    

知识回顾:在上篇使用内存 int a =1的例子中说过:c语言中编译器能自动为变量a在数据段分配一个空间。如果有汇编语言基础,也能知道自己手动为a在0x7001~0xffff中分配一个地址。

2.即便分配了程序段和数据段,那我们怎么保证编写的程序不会越界将程序和数据存放位置搞混了?

答:首先这种错误很常见,比如我们乱使用指针将数据保存到程序段,结果就是我们的程序代码被数据代码覆盖,最后程序崩溃无法执行。

       幸运的是我们还有编译工具来帮助我们自动分配空间,正如我们写的int a =1一样,我们不需要自己去分配a变量的存储空间地址,编译器会自动识别帮我们分配好。

        如果编译器报警出现“段错误”我们就得好好检查自己所写的程序了。

3.上一篇中单片机似乎没有以上冲突问题?

答:上一篇中数据与程序存储器是严格分开,由于硬件特性我们无法对程序存储器(程序段)进行写操作,我们对它的读操作都是通过pc指针间接进行的。

4我们把两种存储器合并的好处是什么?

答:支持在线编程,试想我们每次开发单片机都得先关掉它,然后用21V电压去烧写程序存储器是不是很麻烦?假设我们的0x20000~0x30000存储的是一段蜂鸣器程序(包括相关硬件的初始化),而现在我们想让单片机运行led灯闪烁程序,我们是不是只要将计算机中的led程序复制过来覆盖掉原来的蜂鸣器程序,然后复位单片机就可以了。

5如何具体实现4中的功能

答:估计很麻烦,单片机与计算机之间要建立通信机制才行(串口通信用的多),这要求计算机中有发送程序,单片机中有对应的接收程序才能将数据传输成功(而且应该将程序代码传输到单片机的指定地址上,比如我们之前假设的0x20000~0x30000)。

          所以我们在开发中有很多开发工具,就是用来做这种传输的,如果觉得自己能写可以去尝试,至少能学到很多东西。(linux下的交叉编译开发也是应用了有传输协议的软件工具如nfs ,tftp)

6以上方式可以普及到其他嵌入式的学习和开发吗?

答:不能,2864A才8KB大小,而当人们编写的程序继续扩大到1M甚至1G的时候就装不下了,而我们却找不到类似这种功能的大容量存储器了(成本过高,或者还没有发明出来),于是只能用另一种折中的方式,下一篇将讲到。

总结:将程序与数据同时放到2864A存储器中带来很多方便,但但随着程序的扩大和对读写速度的要求提升,即便设计上理论可行,但对硬件的要求太高以至于无法普及实现,所以必须继续学习新的设计方式来了解嵌入式的启动方式。