以前在Windows开发的时候,我们使用ADS、Keil、MDK等,你直接写个main()函数,所有的细节都帮你实现了,谁来调用main()函数,有他帮你做了。这main()所生成出来的代码,怎么放入到内存里面,这工具也帮你做了,我们基本上只需要写main()函数,只需要写C语言就行了。但是这里掩盖了太多的技术细节,里面有个比较:
① Windows下的单片机学习,深度不够
- Windows下有很好的图形界面单片机开发软件,比如keil、MDK等。
- 它们封装了很多技术细节,比如:
- 你只会从main函数开始编写代码,却不知道上电后第1条代码是怎么执行的;
- 你可以编写中断处理函数,但是却不知道它是怎么被调用的;
- 你不知道程序怎么从Flash上被读入内存;
- 也不知道内存是怎么划分使用的,不知道栈在哪、堆在哪;
- 当你想裁剪程序降低对Flash、内存的使用时,你无从下手;
- 当你新建一个文件时,它被自动加入到工程里,但是其中的机理你完全不懂;
- 等等等。
② 基于ARM+Linux裸机学习,可以学得更深,并且更贴合后续的Linux学习。
- 实际上它就是Linux下的单片机学习,只是一切更加原始:所有的代码需要你自己来编写;哪些文件加入工程,需要你自己来管理。
- 在工作中,我们当然倾向于使用Windows下更便利的工具,但是在学习阶段,我们更想学习到程序的本质。
- 一切从零编写代码、管理代码,可以让我们学习到更多知识:
- 你需要了解芯片的上电启动过程,知道第1条代码如何运行;
- 你需要掌握怎么把程序从Flash上读入内存;
- 需要理解内存怎么规划使用,比如栈在哪,堆在哪;
- 需要理解代码重定位;
- 需要知道中断发生后,软硬件怎么保护现场、跳到中断入口、调用中断程序、恢复现场;
- 你会知道,main函数不是我们编写的第1个函数;
- 你会知道,芯片从上电开始,程序是怎么被搬运执行的;
- 你会知道,函数调用过程中,参数是如何传递的;
- 你会知道,中断发生时,每一个寄存器的值都要小心对待;
- 等等等。
- 你掌握了ARM+Linux的裸机开发,再回去看Windows下的单片机开发,会惊呼:怎么那么简单!并且你会完全明白这些工具没有向你展示的技术细节。
如果我们基于ARM+Linux,不使用这些Windows工具,你可以学得更深,并且单片机的大全Bootloader,他就是ARM+Linux开发的,他并不使用Windows下的工具。 你基于ARM+Linux学裸板、学单片机,你可以学得更多,因为我们一切都从零开始的。我们既管理这些代码,也可以知道芯片上电的时候做了什么事情,知道程序自己怎么把自己读到内存,且知道怎么去规划内存,知道怎么代码重定位……
我说的这些概念,你可能听都没听过,这是因为Windows下这些好用的工具把这些统统都给屏蔽了。 我们使用ARM+Linux进行裸板开发,一旦掌握了ARM+Linux开发这套机制,再回过头去看这些Windows工具、看STM32的话,你只需要几分钟就可以搞定。 并且你可以无缝进入后续的学习,因为你已经熟练掌握了Linux的操作环境,后面的Bootloader是在Linux下开发的,后面的Linux驱动也是在Linux下开发的。