【深度】 到底什么是嵌入式系统?
共 7661字,需浏览 16分钟
·
2020-08-24 03:52
ID:技术让梦想更伟大
作者:裸机思维
整理:李肖遥
【说在前面的话】
作为一个以“思维”为内容的讨论,我并不惧怕话题的庞大。毕竟思维并不是什么可以速成的快餐,俗语说冰冻三尺非一日之寒,着急不来;另一方面,“思维”是个颇为唯心的内容,不仅没有定论,针对每个人的具体情况也是不同的。所以,我并不害怕谈论思维的时候“歪了楼”,或者“缺乏客观性”——本来,装在一个皮囊里,我能谈论的也只是我自己的思维,供有兴趣的看官们消遣一二,如果还能有所启示或者是帮助,那就再好不过了。
模仿人的认知过程,我也将话题分为“自上而下”(对应Top Down Perception)和“自下而上”(对应Bottom Up Perception)两个方向。前者从较为宏观(但更贴近生活和概念的本来面目)出发,讨论一些裸机系统相关的嵌入式概念和看似高大上其实很实在的说法;后者则选择从具体的技术或者是设备出发,从小的问题开始,逐步引出更为复杂的问题。
最终,在某个时刻,你会在某个层面上发现两个认知方向的重合点,我可以保证的是,几乎对所有人来说,这个重合点都是不同的。排除智商的因素,起决定性的还是读者已经掌握的背景知识。
为用而专
【正文】
作为开篇,我们首先对"什么是嵌入式系统"的认识开始。那么什么是嵌入式系统呢?我首先保证,下面的定义已经非常精简,一个多余的单词都没有(请允许我在一个完整的句子中加入空格来强调每一个要素):
嵌入式系统是 面向应用 高度裁减的 专用 计算机系统
1、“专用”
首先我们需要牢记于胸的是这个“专”字(Dedicated),这是相对通用计算机系统的“通用”来说的。PC就是通用计算机系统;出乎很多人意料的是,智能手机也是“通用”计算机系统。这是因为,通用计算机系统拥有标准的硬件定义和操作系统,上层软件可以在一个统一的平台(对硬件和系统软件统一性)的一个假设上进行开发。这么说也许很抽象,实际的判断标准其实很简单,如果一个计算机系统的软件可以自由的直接在同类计算机的硬件上执行,那么这个计算机系统很可能就是一个通用计算机系统,例如,APP可以在不同的智能手机上执行(当然需要运行相同的操作系统,无论是Andriod还是iOS,具体你懂得,抬杠的同志请自动取消关注)
这个专用太重要了,如果说嵌入式系统是一个宇宙的话,那么这里的“专用”就是那个著名的宇宙大爆炸——嵌入式系统一切的特点都源自于此。
2、“面向应用”
光说专用,似乎缺少了什么——“专用”总需要面向点什么才能体现“专用”啊。因此,很自然的,“面向应用”的“专用”就成了嵌入式系统的根本立足点。那么你要问了,难道还有不“面向应用”的“专用”么?当然有了,有面向“科研”的,面向“宣传效应的”,有“面向自我实现”的……
--------------------------------------------
面向科研认真说来也算是面向应用了——科研应用嘛,但其实还是不同的,因为后面我们会说,嵌入式系统的开发是一个工程问题,而科研类的开发是一个学术问题,前者是用成熟的技术去实现一个明确的已知目标,后者是用已知的技术去探索未知的领域或者验证可能的结果
面向宣传,你懂得。没什么卵用,但是可以给人希望和信心。
面向自我实现,有多少人自己写一个操作系统是面向应用的?
--------------------------------------------
嵌入式系统是面向应用的专用计算机系统。那么应用又大体分两类:军用和民用。这么分有什么目的呢?
3、“高度裁剪”
前面我们说,专用是面向应用的专用,目标非常明确——实现某个具体的应用;相对目标不是那么明确的通用计算机系统来说,怎么做才能体现出“针对某个具体应用”而凸现出来的“专用”呢?当然是裁减——从能实现对应应用的通用计算机原形系统(Prototype)上进行裁减——去掉不必要的部分,从而成为某个应用的“专属”计算机系统。
那么问题来了,哪些东西可以裁减呢?如何裁减呢?这里实际上是有明确的标准的——面向应用的具体需求进行裁减。具体来说,虽然功能性(Functionality)、成本(Cost)、可靠性(Dependability / Reliability)、功耗(Power Consumption)、体积(Size)、性能(Performance)、安全性(Security)都是各类嵌入式系统所追求的,但当我们成本有限的时候(时间、金钱、人力资源),我们只能根据应用的偏好来分配资源,俗话说“好钢用在刀刃上”就是这个道理。
容易想象,军用在上述要素的优先级可能是(仅供参考):
功能性 〉可靠性 〉体积 〉性能 〉安全性 〉功耗 〉成本
——想象一下不差钱的军方会怎样考虑一套单兵作战系统
用在裁减的过程中则可能是另外一个样子:
功能性 〉性能 〉体积 〉成本 〉功耗 〉可靠性 〉安全性
——想象一下国产智能手机(粗粮、某族、某情怀)
【小结】
综上所述,我们可以简单的小结一下,嵌入式系统是一个面向应用高度裁减的专用计算机系统——是不是觉得都是废话了?哈哈哈哈,说明你理解了。下一篇,我们将更深层次的揭示隐藏在嵌入式系统名称下的产业秘密和规律。
真正的软硬件
【正文】
当被人问起“什么是嵌入式系统”时,无需看过我的文章,有一种狡猾的说法肯定是挑不出任何错误的——套用知乎上一类著名的问答体,“如何快速的假装/成为某个领域的专家”——你可以故作认真的说:
“嵌入式系统首先是一个计算机系统”,然后大谈你对软件和硬件的看法……
为了在几乎没有逼格的行业中让大家能够有机会装逼,下面我就教大家一种关于嵌入式系统软件和硬件的特别观点,绝对可以让所有的小师妹小师弟甚至是同龄人偷来“刮目相看”的眼光。当然首先你要真的理解这种说法。
为了引起更多人的注意,同时让话题更有冲击性,你应该非常肯定、神秘、恨铁不成钢而又愤慨的宣布一个观点:
“你知道么?嵌入式系统中几乎所有人关于软件和硬件的看法都是错误的……我们被教科书给坑了!”
1、传统计算机系统中的“软件/硬件”观
通常,我们提到计算机硬件,脑海里立马浮现的就是一台PC主机,当然这个时候你要特别小心,因为这个时候你举出的例子很可能是暴露年龄或者逼格的。比如,用台式机举例还是用笔记本举例显然暴露年龄,用Windows笔记本举例还是Mac举例将暴露逼格。当我们提到软件,脑海里浮现的差不多就是Windows上跑着的各类软件,当然,如果你能用APP,特别是iOS的APP来举例,显然就是很有面子的。
是的,细心的你注意到了,传统的软硬件观念直接来源于通用计算机。在后面的讨论中我们会发现,这种由通用计算机带来的思维定势是非常可怕的。
2、嵌入式系统中的“软/硬件”观
嵌入式系统中的软件和硬件并不是你想象的那么简单。这其实很好理解,你可以在大学校园里随便拦下几个学生,让我们来做一个采访,问问他们什么是软件什么是硬件:
屌丝A(计算机学院):你丫有病么?硬件就是你的电脑主机咯,主板、CPU、内存硬盘、显卡什么的;软件就是Windows程序咯
屌丝B(信息学院):硬件就是单片机啊,51、AVR、STM32之类的,对了,还有开发板也算吧?软件嘛,就是Firmware咯(固件),过去用汇编开发,现在都是用C了
屌丝C(信息学院):毛线!我还可以用VHDL和Verlog写一个内核呢,你说说VHDL和Verilog写出来的是不是软件?FPGA是不是硬件?
屌丝B:呃……那咋办?
屌丝D(计算机学院):你们别忘了,开发板上跑的虚拟机也是硬件哦,虚拟机上用Java写的程序也是软件。
大家可能注意到了,在嵌入式系统中,软件和硬件是一个不那么靠谱的定义方式——当人们用普通话发相同的声音说同一个词语的时候,描述的可能根本不是同一个东西。那么,嵌入式系统中,软件和硬件应该如何理解呢?
方案一. 要么,你可以假装从来没有看过这篇文章,只跟你用相同系统的人讨论问题,或者“自己根据语境”自动切换软件和硬件的意思。
方案二. 要么,我们重新定义一下软件和硬件的概念,只要这个概念兼容原有的理解方式就可以了。
真有一种兼容老概念的新定义么?答案是肯定的。让我们来首先找一找在不同层面上软件的共同点:大家都是用一种语言(Java、C、VHDL、甚至是原理图)来描述自己大脑中的逻辑(思维)。让我们来体会一下这个特点,是不是这么个特点?因此,我们重新郑重的定义一下软件:
软件:人们借助某种语言,“尝试”固化下来的,自己的思维
与之相对,硬件的概念可以修改为:
硬件:业已固化下来的逻辑,可以稳定的提供确定的服务和功能
可见,软件的本质是思维,是设计人员的思维,因而程序设计人员最重要的是自己根据任务的需求想通所有的逻辑,并借助一定的语言作为工具,把自己的思维"固化"下来。这个思维的过程叫做"设计(Design)"、这个固化的过程叫做"编码(Coding)"。简单的说,写代码只是一个思维翻译的过程,更重要的是首先写程序的人要想清楚,拥有清晰的思维,然后借助准确无误的语言表达能力(很遗憾,很多人语言表达能力非常有限——就是用C语言写不出自己想要实现的功能)才能写出正确的代码。
思维的设计有很多辅助工具,如大家熟知的流程图(Flow Chart)、UML图、还有大家不太用的数据流图(Data Flow Diagram)等等。然而,具体代码往往并不是一个好的辅助工具。进行思维设计的开发人员,叫做Programmer。
将Programmer的设计文档(各类图表)翻译成具体程序代码的人叫做Coder。
说残酷一点:Programmer设计,负责思考;Coder翻译,负责干苦力。如果你不服,我也没办法,哈哈哈哈……
硬件,本质上一个固化下来的逻辑。这个逻辑的前身当然是思维,只不过它被固化下来了,而且可以"稳定"可靠的提供"确定"的功能和服务。比如,FIFO是队列,在某些软件系统中把这种逻辑确定的模块叫做"构件"(Component),一种中性化的描述,并不强调它是软件还是硬件。因为构件的本质是一个模块,是一个可以提供"确定"的,大家都知道的功能的模块。它可以是硬件的,也可以是软件的。Who care?有的系统还会提供硬件抽象层,进一步模糊这类模块的软硬属性——反正你知道它是做什么的就行了,反正它很可靠,而且可以重复利用,所以你用就好了,是软的还是硬的,无所谓,反正都是同一个API。
当我们想凸显一个模块的逻辑、确定性和稳定性,而又不能或者不需要或者不关心它的软硬属性的时候,我们就干脆叫他构件(Component)。
重新定义软件和硬件的概念,不是一个文字游戏,而是一个行业内在心底里约定俗成已经默默在做的事情,只是,今天被明确的点破了而已。虽然你觉得被刷了三观(也许你没有),但仔细想想,其实的确和过去的认识没有本质上的区别?
不是么?其实你早就懂对么?哈哈哈哈——我没有重新发明软件或者硬件,我只是诚实的搬运工。
重力和沉淀
【正文】
不幸的是,嵌入式只是一门技术,而不是什么科学。嵌入式系统开发只是一个工程问题,而不是什么让人侧目的科学探索问题——除了针对越来越小的半导体工艺问题的研究。认清这个现实吧!趁我揭露另外一个事实之前,还来得及。
也许你还记得,嵌入式系统是专用计算机系统,是面向特定的应用需求而进行高度裁减的专用计算机系统。成本、体积、性能和可靠性对嵌入式系统来说都是敏感的?一个计算机系统如何才能在成本、体积、性能和可靠性上同时取得进步呢?
Bingo!你答对了,摩尔定律。换句话说——嵌入式系统使用的都是“成熟”的技术、都是“量产”的、“成本敏感”的——或者说过时的技术。如果你对这个结论有疑惑,请按照相反的顺序去理解这两段文字。
——“思维不是不可说,是不必多说,懂就是懂。”
现在的计算机技术差不多领先嵌入式技术大约20年,现在嵌入式系统无论在资源上、理论上还是方法论上,都与上世纪80年代的计算机前沿技术相当。举一个简单的例子,现在的Processor完成了从汇编开发到C语言开发的过渡,正在普及面向对象开发的概念——这是资源所决定的。而这一过程,正是上世纪80年代计算机工程师们所面对的环境。只不过这里的对应关系稍微有点不同:32位微控制器(Cortex-M为代表)对应当年的个人电脑,而32/64位的应用处理器(Cortex-A为代表)则对应当年的服务器。其它再无不同。
综上所述:嵌入式是一门技术,而不是科学,它的本质决定了它必然要使用成熟或者说过时的技术。成本是影响一门技术是否可以在嵌入式系统中应用的决定性因素——好东西现在很多都有,只不过太贵,不是做不出来。
在你那“一腔投入嵌入式系统开发的热血”被浇灭之前,有一个好消息要告诉你:因为嵌入式系统只是一门技术——和木匠活差不多——只要你肯花时间,你一定能成为高手,或者说成为熟练的工匠——别介意大师这个伪概念,相信我,只要你开源了足够的代码,帮助了足够多的人,大家都会尊你为大师——其实只有你自己知道,这帮人只不过是太懒,知识都在他们懒得翻开的书本上,你只不过坚持看完了,然后顺手把自己的笔迹贴在了网上。
感谢你有耐心读到这里,这说明你除了兴趣,对这门技术还有可贵的坚持,为了奖励这一点,我会介绍一个模型,通过它,你有能力掌握洞悉嵌入式行业发展规律的方法——我通常也总是把好东西留给真正热爱嵌入式技术的朋友。
沉淀模型
不知道有多少人还记得小学自然课上研究泥土成分的那个实验:取一块泥土,放入烧杯中,放入适量的水,用玻棒充分搅拌至悬浊液。将烧杯静置一小时后观察会发现:1)烧杯中的液体重新变清;2)泥土样本会出现分层,质量相似且较大的颗粒沉淀在底层,从底向上,沉淀层中的颗粒质量和体积都越来越小。——这就是沉淀模型。
在你吼出“什么gui”之前,让我们来讲一个故事,一个暴露年龄的故事。在MP3格式和算法刚刚公布的时候,市场被索尼的磁带随身听和CD播放机所统治,两者分别占据了高端市场和低端市场。在Flash存储器非常昂贵的背景下,MP3文件的高音质小尺寸的特性简直就是市场的明日之星——消费者迫不及待的想买到一个体积只有普通随身体几分之一,不用重复购买碟片或者磁带的次世代播放器——想想都很美是么?巨大的市场需求,推动厂商开发出第一代MP3播放器,这个时候,还没有所谓的硬件解码,MP3软件解码的运算需求使得工程师不得不选择一块价格昂贵的处理器,这使得MP3播放器的成本达到了历史的最高点,但是,WHO CARE?!消费者对这种小巧轻便的高科技产品的热情,决不亚于现在的iPhone——Oh,别忘记了,One thousand sounds in your poket,就是Apple推广iPod的经典广告。
高额的利润吸引更多的玩家进入这个蓝海市场,工程师们渐渐发现,既然MP3解码算法既然这么流行,我们就做成模块吧?卖给别的开发者?渐渐的,连开源的MP3解码模块也出现了——感谢开源,越来越多的厂商有能力制作和发布自己的MP3播放器——如同华强北的功能手机,销售一台MP3播放器的利润越来越低。在这一过程中,MP3解码从单纯的播放器应用中被第一次提取出来——从应用层沉淀到软件服务层,成为一个模块——这是发生在这一嵌入式系统应用中的第一次沉淀。
模块的出现进一步降低了产品开发的难度和成本,但同时也引入了更多的竞争对手压低了利润。工程师们开始面临从市场传导而来的成本压力,大家不得不动脑子。很明显的,用于软件解码的处理器太贵了。实际上,除了解码,其它应用并不需要这么强大的运算能力。于是,工程师们思考设计专门针对MP3解码的硬件DSP芯片来取代原有的通用处理器,显然的,逻辑确定,功能简单的MP3解码芯片相对"通用"的处理器,更容易进行裁减并最终降低成本。
——这是”专用”相对“通用”的最大优势,因为由于目的不确定的“通用“,必须保留大量的逻辑用于确保一定的灵活性,以应对各类不同应用的需求,因此很难对其进行有效的裁减——想想当你预算有限时,买手机或者电脑的时候是如何纠结的吧。而“专用”则目的明确,不需要的都可以大刀阔斧的砍掉,最终结果的轻巧简洁可想而知。便宜是自然的。
用硬件解码芯片配合一个低廉的处理器取代原本昂贵的器件是嵌入式系统设计中降低成本的常见手法。这也是MP3播放器这一嵌入式系统应用中第二次沉淀。值得注意的是,这次沉淀并不是整个软件模块都沉淀到硬件中,而仅仅是MP3解码所要用到的DSP算法被提取出来做成硬件加速器——这是在不增加硬件成本的边界条件下,尽可能提供通用性的典型实例——因为这些固化了DSP算法的芯片还有可能被别的嵌入式应用所使用。
总结
嵌入式系统中只有专用,以及严格规定了边界的通用——即在不增加成本或不增加过多成本的前提下,尽可能的实现通用。
对工程师来说,没有资源限制的通用不算本事,在有限资源范围内实现尽可能多的通用才是一项挑战!
这就是沉淀模型,在应用需求和成本的双重压力下,可重复利用或者可用更低廉成本实现的逻辑会被单独提取出来,沉淀到合适的系统层次中,以便用更便宜的方式加以实现,而在总体功能上保持不变或者改善。
如果你真的理解了沉淀模型,你会发现,沉淀的过程并不一定是单向的(从上到下:应用层到系统层、软件模块沉淀为硬件逻辑)。很容易理解,在运算能力普遍较强的今天,一个有能力作MP3软件解码的MCU几乎是白菜价——换句话说,由于性能的普遍提升,MP3软件解码几乎是白送的,用软件解码比用硬件MP3芯片解码更为便宜,因此,MP3播放器这一嵌入式应用完成了最后一次沉淀,MP3解码从硬件重新回到了软件的怀抱。——如果你真的懂了,就不会纠结沉淀模型的方向性问题了——因为你明白,物理世界中,沉淀的驱动力是重力,而嵌入式世界中,沉淀的方向由成本决定。
嵌入式编程专辑 Linux 学习专辑 C/C++编程专辑 关注微信公众号『技术让梦想更伟大』,后台回复“m”查看更多内容,回复“加群”加入技术交流群。 长按前往图中包含的公众号关注