本文涉及的内容较多,个人知识水平有限,如有不当之处欢迎指正。
特别鸣谢:嵌入式大神 @tofulee ,@woshizmxin 对本文给出了一些很好的意见。
何为嵌入式
嵌入式是一个比较模糊的概念,也没有很准确的解释,其实也没必要一定找出个准确的解释来,并不影响学习。
参考了网上的资料,根据我的认识,可以认为嵌入式系统是一种完全嵌入到设备内部、解决特定问题的专用计算机。我们常用的电脑被认为是通用计算机,能安装各种软件,从而解决各种不同问题;而嵌入式系统是专用计算机,只负责解决特定问题,例如控制洗衣机、控制路由器等;其软件被称为固件,一般不会经常进行变动。
一般认为智能手机也是嵌入式系统,但是现在手机功能越来越强大,可以装各种软件,和电脑之间的界限也比较模糊了。例如平板电脑,既可以当成电脑,又可以当成大屏幕手机……当然,没必要过多的去纠结这些。
从上面的这个定义来看,单片机一般也属于嵌入式系统。
典型嵌入式系统的设计流程
这里举一个使用ARM9的CPU和Linux操作系统的、典型的嵌入式系统的设计流程。整个设计过程有点组装电脑的感觉,就是拼接各种模块,包括软件模块和硬件模块。
需要注意的是,嵌入式的范畴非常广。这里要举的例子,作为典型的嵌入式设备,也是近几年很流行的智能硬件设备;其设计重点在软件系统和硬件电路上,和IT类专业的关系非常密切。本文也是以这种典型的嵌入式设备为主进行介绍的。
实际上还有很多不一样的情况。例如一台全自动洗衣机,智能化程度不高,运算量小,往往只需要简单的单片机就可以控制,也不依赖操作系统,这时设计重点就放在了机电控制、力学、外观等方面。
方案确定
现在要做一个产品,人脸识别的门锁。人脸识别的算法实现,需要用到较高运算能力的器件。如果使用一台常规电脑执行算法,并和门锁连接,那样成本太高,体积大,不实用,还很费电。这时最佳选择就是使用嵌入式系统了。
硬件方面,根据算法的运算量和响应时间,可以选择一款合适的CPU,例如三星的一款ARM9芯片;容量合适的存储器,包括RAM、ROM芯片等;给它配备摄像头负责获取人脸图像;电机之类的装置负责开门;可能还有一些指示灯和控制按钮;以及USB接口,用于连接电脑进行更多操作。确定硬件器件时,往往需要考虑很多因素,例如器件的体积,成本,批量制造时是否便于采购,是否易于使用,等等。
软件方面,为了开发方便,考虑直接使用Linux操作系统。Linux系统和Windows类似,但是Linux是开源的,可以看到源代码,可以按需要修改。在Linux的基础上,利用OpenCV图形库编写应用程序,实现人脸录入、识别等功能。
嵌入式软件
Linux操作系统是开源的,可以找到它的源码,按需修改。基于Linux的操作系统很多,例如电脑上用的Ubuntu,手机上的Android。
整体方案考虑好之后就有问题来了,产品方案已经确定,不需要显示器、声卡、网卡等硬件设备。如果把一个完整的Linux操作系统装进去,上面就会有很多多余的东西,不仅对有限的CPU配置来说浪费运算能力,而且浪费存储空间,又费电。
Linux开源免费,可以按需要修改,带来了巨大的好处。实际上只要把需要的设备驱动和Linux内核一起编译就可以了(操作系统和常见的C语言编程一样,也是从源码编译成可执行文件)。而显卡、声卡等设备驱动程序就不需要了。另外还有负责引导操作系统启动的BootLoader程序,也可以直接用成品。
Linux的资源非常丰富,需要的摄像头驱动程序往往都能找到,通常摄像头的硬件厂商也会提供配套的驱动程序。有些情况下或许会有特殊需要,这个时候才需要有人专门负责给这个摄像头写驱动程序,也就是嵌入式驱动开发(这里是从产品研发厂商的角度来考虑的。如果从摄像头厂商的角度考虑,他们提供的摄像头产品配套驱动程序,也是需要有人来写的)。
针对挑选好的CPU等硬件的型号,配置好各种参数,将这些软件模块进行编译,就成了经过裁剪的专用操作系统。在这个操作系统上开发好人脸识别程序(嵌入式应用软件)。最后固件开发完成,下载进硬件中就可以了。
嵌入式硬件
硬件方面,首先是电路设计,一般各种硬件设备和芯片,例如摄像头、CPU等都会有它的接口,就像单片机的IO口、各种芯片的接口一样,按照一些规则进行连接就可以了。
然后是PCB的设计,根据电路设计PCB,PCB设计的过程中可能要考虑到布线、产品外观等问题(实际上还要设计产品外观,可以利用3D打印技术;大概是工业设计什么的,不太了解,也不细说)。
产品原型与量产
设计好以后,进行产品原型的制造,制造的量很少。例如外壳可以用3D打印实现,3D打印非常适合原型的制造,免除了模具设计等复杂的工艺;硬件电路方面,可以申请公司样片,人工焊接到电路板上;然后烧写固件并组装产品。将软硬件整合成产品原型进行测试,如果有问题则需要再修改设计,重复这些步骤。完成后,产品的研发阶段就差不多了,也就是产品原型已经能用了。
产品原型实现了,就可以进行批量生产了。批量生产又会涉及很多问题,例如元器件采购要考虑成本和供应量,PCB、外壳的批量制造,焊接、装配、包装等。
嵌入式开发的特点与难点
还是以上面的典型嵌入式系统为例,可以看出,嵌入式系统涉及的东西很多,从最底层的硬件电路,一直到上层的应用程序。通常说的嵌入式开发,最主要的就是软硬件结合的部分;在其上是应用程序开发了,例如安卓App的开发,对于底层原理不需要有太多的了解;而在其下如PCB设计之类,一般认为是纯硬件,也不算嵌入式的内容了。
软件方面,利用了很成熟的Linux操作系统,整个过程中大部分软件模块都有成品,只需要合理的选用,然后进行拼接、编译就可以了。这些软件模块早就有人写好了,往往不需要去写,但是要能大致理解写好的程序,并根据需要做一些小的修改调整。而对于一些特殊和极端情况,才有必要对程序进行较大改动,甚至自行实现。很多时候就是在移植驱动和系统,程序方面常用成品,更多的是小规模的修改调整;写程序相对少,难度较大,往往也没必要重复发明轮子。看懂代码最简单,修改次之,自己写最难。
嵌入式系统设计时,如果使用的都是现成的代码,难点在哪呢?有大神给我解释,嵌入式开发入门比较难,学着学着,发现很多现成的驱动都摆在那儿,而难题在于怎么将这些驱动移植到系统中,怎么去调试了。因为调试的时候,涉及整个linux系统,非常庞大,要考虑的地方非常多,所以显得比较难了。但是只要在繁杂的linux系统中找到问题所在了,往往就只需要修改那么一两个地方即可。另外,在设计一个系统时,需要考虑开支,技术难度等各种因素,选取合适的芯片、模块,也比较难。
如何学习
嵌入式涉及的东西非常多,学起来也不容易。我本人只做过单片机系统设计,和学嵌入式的同学聊过一些,没有具体的去学嵌入式,所以这里简单提一些看法。嵌入式方面我研究的不多,所以也没办法推荐太多的书籍,知道的就顺便推荐下。
根据网上的招聘信息,嵌入式常分为嵌入式硬件和嵌入式软件两个大的方向,硬件方向负责电路设计之类;嵌入式软件常常是底层的驱动程序移植、开发之类;而嵌入式软件再往上层一点,差不多就是操作系统之上的应用开发了。
首先C语言几乎是嵌入式各种岗位必备的基础知识,并且要求很高(很多公司给出的要求是精通)。在嵌入式的底层,C语言大量被使用,特别是多维指针、结构体等,还有很多上层C编程中不常用的知识,例如volatile关键字。另外C++在有些公司的招聘要求中也有提到,稍上层一点的编程可能会用C++。《The C Programming Language》《C++ Primer》这两本书比较经典。
单片机作为嵌入式的重要基础,有必要学习一下,对于提高动手能力等也很有好处。微机原理也是基础知识,学习单片机对于理解微机原理有帮助;汇编语言则是微机原理中的重点知识,在嵌入式最底层的程序中会用到。数字电路是微机原理的基础,在单片机/嵌入式的硬件电路设计时,也会经常用到。如果做偏硬件方面,可能还需要一定的模拟电路和PCB设计知识。
Linux的操作也是一个很基础的知识,嵌入式用Linux系统很多,编译很多时候也是在Linux环境下进行的。由于嵌入式往往涉及操作系统,所以操作系统也有学习的必要。网络方面的知识也经常会涉及。推荐书籍:《鸟哥的Linux私房菜》《现代操作系统》《计算机网络》。
然后推荐一本韦东山的《嵌入式Linux应用开发完全手册》,里面涉及了嵌入式系统移植方方面面的知识。如果想学的再深入一些,可以去看嵌入式驱动开发,还有BootLoader、Linux的原理以及代码实现等等。Linux操作系统非常庞大,能把里面的原理都弄明白,需要很多的知识,也需要很长时间的积累。编程方面还可能涉及数据结构,设计模式等学科内容。嵌入式的编程一般是在Linux系统下进行的,所以熟悉Linux系统下的代码编辑器、熟悉程序的编译、工程的管理、Makefile的编写等也很必要。
Android作为一个新兴的优秀开源嵌入式系统,也在越来越多的被用到,安卓智能手机的设计也少不了嵌入式方面的研发工作。例如有安卓内核与驱动开发方面的岗位;专门的安卓ROM移植工程师,负责安卓系统的定制移植等工作。《Android内核剖析》这本书不错。通常所说的嵌入式方向,不包括安卓应用程序的开发。
总得来说,嵌入式涉及的东西特别多,软件、硬件都有,其中很多东西对理论要求倒也不高,但是不好理解。知识太多需要长期坚持和积累。初级的嵌入式工程师,主要是移植驱动和系统之类,看懂已有的程序,做一些小的调整;而高级的嵌入式工程师,则能对代码进行大规模的调整,甚至自己写代码。这一点非常不容易,因为嵌入式的程序往往很难写,每一行代码都可能包含了大量的背景知识(所以待遇肯定也不会差)。