4 IoT 平台衡量标准
在讨论 IoT 平台之前,我们需要知道有哪些衡量标准来判断一个 IoT 平台的优劣。下面是我提出的三个衡量标准
• 现代程序设计语言
• 面向应用的抽象
• 提供生产支持
4.1 现代程序设计语言
鉴于摩尔定律的存在,在现代软件开发中,开发的效率比代码执行的效率要重要。所以,一个好的 IoT 平台,需要有一门现代的程序设计语言。
我们不妨先看看 C/C++ 这个传统的嵌入式开发语言在现代程序设计语言所需特性上的表现,如表1。
表1 C/C++在现代程序设计语言所需特性上的表现
再来看看 Ruff 选择的 JavaScript 在这些特性上的表现,如表2。
表2 Ruff 选择的 JavaScript 在这些特性上的表现
通过对比,不难发现,虽然 C/C++ 依然战斗力十足,但作为“现代程序设计语言”,它们显得不那么“现代”了。或许你会好奇,Ruff 为什么选择其它的“现代程序设计语言”,主要有下面几点考量。
4.2 面向应用的抽象
什么是面向应用的抽象?对比两段代码,我们便不难发现,这两段代码完成是同样的工作,点亮一盏灯。
先是传统嵌入式风格,简单起见,我们用了 Python 代码做示例:
GPIO.output(11, GPIO.HIGH)
再是 Ruff 的代码,用的是 JavaScript 语言
$(‘#led’).turnOn();
我们为什么需要硬件抽象呢?因为我们看到整个软件开发的趋势就是抽象度越来越高,从汇编到 C 语言,再到Java,今天还会有各种各样的 DSL (Domain Specific Language,领域特定语言)。早年间,编写代码,我们可能会质疑编译器是否正确,手写汇编效率会更高,但今天,我们肯定不会这么做,开发效率太低,因为有了抽象,底层的东西可以不断优化,越做越好。之所以抽象程度能不断提升,还要拜摩尔定律所赐,硬件能力越来越强,一些执行上的性能损失,我们是可以承受的。
那我们需要怎样的抽象呢?从发展趋势可以看出,抽象的趋势一定是越来越接近问题领域。对于 IoT 平台而言,一定是越来越接近于应用开发。在 IoT 平台的尝试中,我们看到了几种不同的抽象。
• 无抽象
传统的嵌入式开发按照这个标准,就是无抽象的,其特点是面向硬件接口编程。
GPIO.output(11, GPIO.HIGH)
• 编程接口抽象
诸如 Ruff、Tessel、Jonny-Five、Cylon.js 等一些 IoT 平台开始提供面向应用的编程接口抽象,让开发者无需关注底层的实现细节。
board.on(“ready”, function() {
var led = new five.Led(13);
led.strobe();
});
但在这里,我们不难发现,我们依然要对底层的接口有了解,否则,你便不知道,这段代码中的13是做什么用的。
• 隔离硬件配置的抽象
Ruff 在提供面向应用的编程接口抽象基础上,更进了一步,将硬件配置隔离出去。在 Ruff 代码中,我们甚至看不出硬件配置是什么样的。
$.ready(function (error) {
$(‘#led’).turnOn();
});
Ruff 之所以要提供隔离硬件配置的抽象,主要是为了提供生产支持。
4.3 提供生产支持
大家对于新出现的 IoT 平台,普遍有一个误解,这些平台只能用在原型研发上,因为它们看到的是,采用 JavaScript 的硬件要求都很高,与现在普遍的硬件开发状况不符。现在 JavaScript 已经可以运行在一些资源有限的系统上,比如 MCU,Ruff 就有自己的 MCU 版本,支持了几款不同的 MCU。
Ruff 所做的事情更进了一步,它将硬件配置与应用本身分离开来,这样的做法带来一些好处是
• 应用开发者无需关注硬件如何配置,可以将更多的将注意力放在应用逻辑本身
• 硬件具体的配置方式可以在具体的部署时决定
一旦硬件配置可以在部署时决定,便出现了另外一种可能,也就是,同一个应用可以运行在不同的硬件上,也就是跨硬件应用就出现了,这也就让前面提及的“重复造轮子”的情况得到一定程度的缓解。
伴随跨硬件应用的出现,还会有一个额外的作用:测试。以往硬件测试一定要在硬件上完成,因为前面提及的种种原因,硬件测试往往要部署一个包括系统在内的应用,所以,效率是极低的。而我们知道,应用开发中,大量的测试实际上是应用逻辑的测试,属于软件测试的部分,理论上是可以在开发机上完成的。因为有了硬件隔离,Ruff 就提供了在开发机上做软件测试的能力,开发的效率由此得以提升。
下面是一个 Ruff 测试代码的例子,可以在开发机上运行:
var runner = require(‘ruff-app-runner’);
var verify = require(‘ruff-mock’).verify;
exports[‘test should call turn on while application is ready’] = function() {
runner.run(appPath, function() {
verify($(‘#led’)).turnOn();
});
};
require(‘test’).run(exports);
评论
查看更多