/news/detail/65026
作为典型的嵌入式开发,物联网应用的开发与互联网应用从硬件配置到运行环境有巨大的不同。本文介绍了当前物联网开发者面临的挑战,并分析IoT时代完整的开发平台至少需要具备的特征。
1969年10月29日晚上10点30分,雷纳德•克兰罗克(Leonard Kleinrock)在洛杉矶向在斯坦福的比尔·杜瓦利的计算机发送了两个字符“Lo”,它们是单词“Login”的一部分,只发送了“Lo”,传输系统就崩溃了。这是一个伟大的事件,标志着世界上第一次计算机网络互连的开始,也标志计算机编程由单机向网络发展。
物联网(IoT)是个新名词,顾名思义,就是把物体用网络连接在一起。却是一个新瓶装旧酒的新名词,它不是一个新事物。看官你说,当年克兰罗克和比尔.杜瓦利手中的互相连接的两台计算机,算不算物联网设备,他们的确是用通信介质连接在一起的“物体”啊,谁说计算机不算物体的?
今天的物联网通信,与40多年前传输的两个字节,并没有本质的不同,说来也就是通信速度、通信成本、设备体积和功耗方面,逐步进化而已。然而,量变引起质变,上世纪末计算机网络通信的发展,引发了互联网革命,现在,随着通信成本的降低,功耗的减小、无线通信的普及,又引发了物联网革命。
互联网时代,承载网络应用的是通用计算机或者个人终端数字助理,例如手机、iPad等。通信主要关注的是数据流量,也就是带宽,应用主要关注的是界面的友好性、丰富性、个性化。同时,CPU功能比较强大,内存配置等也比较丰富,并不强调实时性,也不特别强调可靠性,开发平台也很一致,功能丰富。
物联网应用开发的挑战
物联网应用,与互联网应用有着巨大的不同,物联网应用开发是典型的嵌入式开发,从硬件配置到运行环境等等,都千差万别。
谈到开发平台,很多人第一反应就是编程语言,从汇编、C、C++、Pascal、VB、VC等编译型语言,到Java、JS、Python、Lua等脚本语言,说得上名字的、说不上名字的,可以罗列出成百上千种,著名的TIOBE,每年都要为各种编程语言排座次。其实要谈物联网开发平台的发展,还得从早期嵌入式系统说起。曾几何时,嵌入式MCU很多只有几十字节的内存,几百自己就算多的了,那时候,汇编语言是嵌入式编程不二的选择。那时候,也没有编程平台的说法的,也没有Shell之类的调试工具,更没有标准IO系统,总之,程序员就像在一堆沙土上盖房子,没有地基,也没有房梁,更没有混凝土,就是用泥浆砖头石块慢慢糊。及后来,出现了单片机前后台C语言(俗称裸机C)开发工具,典型的是keil,同时,也出现了RTOS,例如vrtx、pSOS、VxWorks等,但裸机C语言开发长期占主导地位。早期的C语言开发平台,从平台角度,其实没比汇编年代进步多少,同样的没有Shell、没有标准IO系统,没有异常处理系统,除了编码语言外,差不了太多。虽然代码的可移植性比汇编强,但仍然是跟硬件平台紧耦合的,它要求软件工程师了解硬件的每一个细节,了解CPU每一个寄存器的含义,硬件平台稍有变动,软件就懵逼了。
在裸C时代,首先出手改进开发平台的是MCU厂商,ST、ATMEL、Freescale、NXP等知名MCU厂家,都推出了越来越完善的固件,使用这些固件,尽可能地抹平不同型号CPU之间的差异,使用户的应用程序更加通用。同时,他们还推出了越来越完善的IDE,利用他们的IDE,可以自动化地生成一部分跟CPU相关的代码,减轻了工程师的工作。但是,所有这些工作,都仅限于同一厂家的不同型号MCU之间,甚至只在同一厂家的同一系列MCU之间,才能体现出其价值。为什么MCU厂家要做这些工作呢?因为他们要卖东西,他们的客户,大多数还使用裸机C开发,而不像系统级CPU那样有完善的开发平台支持。他们的客户,迫切需要一个开发平台,来规避晦涩难懂的硬件驱动开发,使应用和驱动相分离。一个非常典型的现象是freescale,它主要为MCU产品线提供驱动固件,而对于PPC产品线,原厂提供的驱动就是垃圾,谁用谁知道。
在物联网时代,也许某一天,牧场跑的每一只羊,农场里的每一株黄瓜,我们喝水的杯子,都是IoT的一个节点,里面都有一颗MCU,都有一套嵌入式程序,如此爆炸性发展的网络规模,使我们面临什么挑战呢?
首先我们面临的是人的问题,海量增加的物联网软件工程师队伍,你再象过去要求嵌入式工程师那样,要求他们掌握大量MCU底层技能,根本不现实,他们需要的是一个开发平台,类似PC上编程的开发平台。而裸机C语言编程,则无论如何也摆脱不了“要求程序员掌握MCU底层编程”这一现实。因此,在物联网时代,RTOS成了必须品,裸机C语言平台,必然会被RTOS环境所替代。这并不是说,物联网时代的嵌入式产品有多复杂,非RTOS不可,可是,再过几年,裸机C编程,会像现在的汇编编程那样,成为“高端技能”。现在,许多嵌入式学科的大学生,在校时就已经基本掌握了RTOS下编程技能,裸机C反倒不懂了。结果是,5年后,你将越来越难于找到能够驾驭裸机C编程的人,即使找到了,其人力成本也必然居高不下,年龄大概也会在30岁以上,你能找一个只有1~2年经验的毕业生干的事情,为什么要花更高的薪水,请“老”工程师干呢。同时,虽然摩尔定律在高性能CPU上已经失效(这个有争议),但在MCU领域,还是符合得很好,硬件的发展,使RTOS带来的额外开销,在成本上显得微不足道。
由于IoT产品必然涉及到网络编程,也就注定了不能使用太低端的处理器配置,硬件成本持续下降,运行RTOS所需要的额外硬件成本,占总成本的比例,直接可以无视之。人力成本持续上升,RTOS甚至更高级的开发平台,将会占领IoT开发领域。
一定会有人问,裸机C不是比RTOS更简单么?我问你,如果只是点个灯,用C简单还是用汇编简单?你也许会毫不犹豫地回答,用C简单。为什么呢?因为开发工具已经完成了大量的工作,有厂家的固件,完成GPIO的驱动,IDE自动生成的代码,完成了main函数之前的大量环境初始化工作。所以,你只需要3分钟,在main函数里放一个循环改变GPIO状态的代码,一个C语言的闪灯程序就完成了。事实上,如果从0开始做,汇编完成闪灯,不知比C简单多少倍。
裸机C取代汇编语言的过程,正在裸机C和RTOS编程之间重演着,不信么?我出个“简单”的题,写一个“hello world”的嵌入式程序看看。
很快,你写出来了,UartSend(“Hello World”);
别急,我的题还没出完呢,我需要输出“你好,欢迎你第xxx次光临”。
这就难一些了,聪明的,就写一个MyPrintf吧,谁知道这道题还有什么变化呢(注意这里,你不能用printf作为函数名的,下面有解释)。
花了一个星期时间,把MyPrintf弄出来了,效率够高吧?
好吧,你牛,I 服了 You,现在请你把输出重定位到板载的LCD上。
什么,玩我啊,这涉及到IO重定向呢,爷不干了。
光重定向一个输出就不干了,还没有要你把输入重定向一下呢,板子上不是有按键嘛!
IO重定向,是C语言的基本要求,然而,在裸机C环境下,这个基本要求,却让一个裸机C高手望而生畏。
IO服务,只是一个基本需求,它只是C Runtime的一部分,而C Runtime,是IoT开发所需要的进阶工具的基础,恰恰是,裸机C都是很难实现完整的、通用的、可移植的C Runtime。
先爆点料,绝大多数嵌入式RTOS,都没有fopen、fwrite、fread、printf函数,有部分RTOS会有xxx_fopen、xxx_fwrite、xxx_fread、xxx_printf之类的API,即使是一些老牌的商业RTOS也是如此,这里我就不点名了。
没有IO体系的RTOS也就罢了,那些有IO体系的RTOS,为啥要在API前加个xxx呢?你知道加上那个xxx,会给用户添加多少麻烦吗?IoT时代,许多嵌入式软件工程师,原来可能是Windows或者Linux下编程的,他们熟悉c标准函数;嵌入式设备网络化、应用程序通用化的倾向,许多IoT开发会涉及到开源软件或者第三方库,这些开源软件或者库,许多是遵循C语言标准写的,也就是说,里面很可能会大量调用fopen之类的C标准函数。你要用这些开源软件或者第三方库,就必须修改它的源码,把调用C标准IO函数的地方,全部改掉。改就改呗,改了不就行了嘛,有什么大不了的。好吧,如果是二进制的库呢,怎么改?即使是开源软件,维护方升级了,修正了bug,你是不是要再改一次?既然这么多坏处,为啥还要加哪个“xxx”前缀呢?问题就出在标准C库上,因为编译器所带的C库,实现了那些函数,OS如果要自己实现这些函数,就必须先实现C库,而C库,而许多RTOS,并没有实现自己的C库,而是借用编译器提供的C库,自然就不能使用跟C库重名的函数了。
IoT时代的嵌入式开发平台
从完整开发平台的角度,看看几十年来涌现的数以百千计的RTOS,能不能算合格的IoT开发平台呢?答案恐怕是否定的,即使有些非常知名的RTOS,也是如此,有许多RTOS,充其量是一个调度器。有意思的是,从开发平台完整性来看,目前流传的绝大多数嵌入式操作系统,甚至比不上Industrial Programming Inc(IPI)公司在上世纪70年代的MTOS。
那么,IoT时代完整的C开发平台,至少需要具备哪些特征呢?
只有调度器内核是不够的,按今天的标准,它甚至不能称作RTOS,这种系统,权且叫它“裸核”吧,并不比裸机C开发高明多少。用户使用操作系统,目的是为了省事,并没有在操作系统下能干成而裸机C干不成的事情。然而在“裸核”下开发,没有标准驱动框架,没有Shell,没有IO系统,没有C Runtime支持,真的没省多少事。
在“裸核”的基础上,起码,要提供C Runtime,提供C库,使之成为完整的C开发平台,让标准的c程序能编译运行。所谓的标准C程序,不仅仅指符合C语法的程序,C库函数也是标准的一部分,调用标准C库的程序都不能运行,不能算完整的C支持平台吧。要支持完整的C Runtime,你就必须有文件系统,有IO驱动架构,有协议栈等。有了C Runtime,才能支持C++,才能实现Python、Lua、JavaScript等更高级的开发语言,实现IoT设备的快速开发。
即使有了完整的C支持平台,在IoT时代,还是不够的。我要访问一个云服务器,还要自己写Socket通信,从最底层的http编解码开始;我要在设备间交换点数据,或者配置一下设备功能,起码JSON之类的解析器要提供吧。还有,诸如WiFi、蓝牙、ZigBee等,是IoT中最常用的无线协议,也是必须支持的。进一步地,较为复杂的设备,还需要有图形系统支持,一个完善的GUI也是非常受欢迎的了。
总之,IoT时代,需要的是能快速开发IoT设备的平台,而不仅仅是提供一个符合C语法规范的开发平台。
作者:罗侍田,都江堰操作系统(DJYOS)创始人,长期从事嵌入式系统开发。个人博客:/djyos。
责编:周建丁(IoT投稿请联系zhoujd@,CSDN嵌入式技术交流群请搜微信号jianding_zhou,由管理员加入)