我们都知道,单片机在上电的那一刻,mcu的程序指针会被初始化为上电复位时的地址,从那个地址处读取将要执行的指令,由此程序在mcu上开始执行。当然,在调用程序的main之前,还有一系列其他的初始化要做,比如堆栈的初始化,不过这些我们很少会去修改。
pc在上电时,其实和mcu差不多,不过读取的是bios,有它完成了很多初始化操作;最后,调用系统的初始化函数,将控制权交给了操作系统。于是,我们就看到了windows,linux系统启动了。
如果将操作系统看作是在处理器上跑的一个很大的裸机程序(就是直接在硬件上跑的程序,因为操作系统就是直接跑在cpu上的,这样看待是可以的,不过这个裸机程序功能很多很强大),那么操作系统的启动很像mcu程序的启动。前者有一个很大的初始化程序完成很复杂的初始化;后者有一段不长的汇编代码完成一些简单的初始化。从这一点看,它们在流程上是很相似的。
那么,如果是系统上的程序启动呢?
它们是由系统来决定的。linux上在shell下输入。/p后,首先检查是否是一个内建的shell命令;如果不是,则shell假设它是一个可执行文件(linux上一般是elf格式),然后调用一些相关的函数,将在硬盘上的p文件的内容拷贝到内存(ddr ram)中,并建立一个它的运行环境(当然,这里还有内存映射、虚拟内存、连接与加载等一些其它东西),准备执行。
由以上可知,单片机上的程序和平时在系统上运行的程序,在启动时差异是很大的(如果将程序调用main以前的动作,都抽象为初始化的话,程序的启动可以简化为:建立运行环境+调用main函数,这样程序的执行差异是不大的)。因为单片机上跑的程序(裸机程序)是和操作系统一样跑在硬件上的,它们属于一个层次的。过去之所以没有区分出单片机上的程序和pc机上的程序的一些差异,就是没有弄明白这一点。由此,以前的一些疑惑也就解开了。
为什么单片机上的程序不怎么使用malloc,而pc上经常使用?
因为单片机上没有已经写好的内存管理算法的代码;而在pc上操作系统里运行的程序,libc已经把这些都做了,只需要调用就可以了。
如果在单片机上想用动态内存也可以,但这些代码要自己去实现,并定义一个相应的malloc。有时候一些公司会给提供一些库函数可能会实现malloc,但因为单片机上ram内存十分有限,如果不知道它的运行方式,估计会很危险。同样,因为在pc的系统上运行的程序与裸机程序不同,裸机程序不会有动态链接,有的只是静态链接。
至于程序在执行时,从哪里读取指令,哪里读取数据,也曾因为没有弄清楚系统上的程序和裸机程序之间的区别,而疑惑了很久。虽然在《微型计算机原理》课上知道程序运行时,从内存中读取指令和数据进行执行和回写。但是,单片机上只有几k的ram,而flash一般有几十k甚至1m,这个时候指令和数据都在内存中吗(这里的内存仅指ram,因为pc上我们常说的内存就是ddr ram memory,先入为主,以至于认为单片机上也是这样,还没有明白其实ram和flash都是内存)?
这不可能,因为课上老师只说内存,但pc上内存一般就是ddr ram,不会是硬盘,因为硬盘是保存数据的地方。由此类比时,自己把自己弄晕菜了,单片机的ram对应于ddr ram,那么flash是不是就对应于硬盘了呢?
在csapp上明白了,pc上之所以都在ddr ram上,是速度的因素。硬盘的速度太慢,即使是即将到来的ssd比起ddrram,还是差着几个数量级,所以拷贝到ddrram中。这时,一个程序的代码和数据是连续存放的,其中代码段是只读区域,数据段是可读写区域(这是由操作系统的内存管理机制决定的)。运行时,再将它们拷贝到速度更快的sram中,以得到更快的执行速度。
而对于单片机而言,工作频率也就几m、几十m,从flash中与从ram中读的差异可能并不明显,不会成为程序执行的瓶颈(而对于pc而言,flash的速度太慢,ddr ram的速度也是很慢,即使是sram也是慢了不少,于是再提高工作频率也提高不了程序的执行速度,所以一个瓶颈出现了。为了提高cpu的使用率,换个角度想一下,既然不能减少一段程序的执行时间,就在同样的时间执行更多的程序,一个核执行一段程序,两个核就可以执行两段程序,于是多核cpu成为了现在的主流)。
所以,裸机程序指令就在flash(flash memory)中存放,而数据就放在了ram中(flash的写入次数有限制,同时它的速度和ram还是差很多)。更广泛地说,在单片机上ram存放data段、bss段、堆栈段;rom(eprom、eeprom、flash等非易失性存储设备)存放代码、只读数据段。
本质上说,这和pc上程序都在ram中存放是一样的。pc上是操作系统规定了可读与可写;而单片机上是依靠不同的存储设备区分了可读与可写。当然,现在的flash是可读写的,如果flash没有写入次数限制,速度又可以和ram相差不多,单片机上是不是只要flash就可以了呢(直接相当于pc上的ddrram)?这样成本也会比一个ram、一个flash低,更节省成本,对于生产商更划算。
对于单片机程序执行时指令和数据的存放与读取,理解如下:
对单片机编程后,程序的代码段、data段、bss段、rodata段等都存放在flash中。当单片机上电后,初始化汇编代码将data段、bss段复制到ram中,并建立好堆栈,开始调用程序的main函数。以后,便有了程序存储器和数据存储器之分,运行时从flash(即指令存储器,代码存储器)中读取指令 ,从ram中读取与写入数据,ram存在的意义就在于速度更快。
无论是单片机,还是pc,存在的存储器金字塔都是一致的。速度的因素、成本的限制,导致了一级级更快的存储器的更快速度与更高的成本。应该说,对于程序执行的理解,就是存储器金字塔的理解。
那么,什么是ram、rom和flash呢?
尽管他们都是计算机内存的一种形式,但ram、rom、flash它们三个都以各自的方式和他们存储的数据进行交互。
下面,将对每种内存有一个简短的说明。
ram:表示随机访问内存(random access memory):微处理器可以读写访问的内存。当我们创建一些东西时,它是在内存中完成的。ram是内存,反之亦然。
rom:表示只读内存:微处理器可以读rom,但是不能写入或修改。rom是永久性的。rom芯片经常保存一些重要且永不改变的特殊计算机指令。无论何时,微处理器都可以访问到存储在rom上的信息。因为这些指令不可被擦出,所以他们保存在rom中。
flash memory:是一种兼具ram和rom二者性质的特殊内存。我们可以像操作ram一样,向flash 内存写入数据;但是它又像rom一样,数据在掉电时不丢失。悲剧的是,flash 内存没有ram那么快,所以任何时候都不要指望它能取代标准的计算机内存。
采用PIC16F877单片机的汽车电动助力转向系统
桁架机器人-减少工伤事故发生
探究新型银纳米点增强非晶硅薄膜的光吸收
如何在Ubuntu中安装IDLE Python IDE
三星挤走台积电联电 抢下苹果iPad订单
为什么单片机上的程序不怎么使用malloc?
电源谐波电压系数一般是多少?
一文看懂超声刀
今年下半年全球硅晶圆市场销售或呈两大走向
怎样抓住ISO 20000的管理轴心
这样讲解SD-WAN,你总该掌握这门技术了吧!
中国电信积极推动eSIM在泛智能终端以及物联网领域的应用
5G、AI等新兴技术的融合,加速智慧城市的创新变革
笔记本防盗保护器电路图分享
iphone8什么时候上市?iphone8最新消息:十周年的iphone8必将大火,四大亮点提前看
代码保护之道——混淆的艺术
福布斯公布全球企业2000强榜单:50家半导体企业入围
如何为大众带来更加智能的健身体验
探究华为云数据库战略,分析其市场的发展前景
电流探头进行校准的具体操作步骤