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的系统上运行的程序与逻机程序的不同,裸机程序不会有动态链接,有的只是静态链接。 |