为嵌入式系统创建软件的程序员对脚本并不陌生。他们选择脚本是因为它们是解决问题的最快方法。脚本用于自动化构建和运行验证测试。解释性语言——一种使编程语言成为脚本语言的通用定义——例如 Forth 已经使用了几十年,以减少代码的内存占用,同时以可移植的方式提高可维护性。
从玩具到工具
JavaScript 于 1995 年作为网页编程语言首次出现。由 Brendan Eich 通过将类似 C 的语法应用于基于原型的继承而创建的 JavaScript 并未被视为为任何环境创建商业软件的可行工具。这种看法慢慢地改变了。在幕后,JavaScript 通过 ECMA International 成为标准,现在正在进行第 6 次重大修订。
雅虎的 Douglas Crockford 富有洞察力的工作创建了数据交换格式 JSON(JavaScript 标准对象表示法)作为 JavaScript 的严格子集。JSON 已迅速取代 XML,成为 Web 客户端和服务器之间通信的首选数据格式,因为它简单易用,尤其是 JavaScript 软件。
2009 年,Ryan Dahl 推出了 node.js,这是一种使用 Google 闪电般快速的 V8 JavaScript 引擎在 JavaScript 中构建 Web 服务器的高效方法。node.js 已被迅速采用,带来了强大的开发人员生态系统和大量开源模块。
O‘Reilly Media 的创始人 Tim O’Reilly 曾对 JavaScript 从业余爱好者的玩具转变为专业工具的转变发表了著名的评论:“过去学习 JavaScript 意味着你不是一个认真的软件开发人员。今天,不学习 Javascript 意味着同样的事情。”
JavaScript 现在广泛用于网页、Web 服务器和移动应用程序。但还没有在嵌入式系统中。这有望改变。
熟悉的语法
今天的大多数嵌入式编程都是用 C 完成的。与许多需要 C 程序员学习不同语法和编程风格的脚本语言不同,JavaScript 的语法与 C 非常相似。有经验的嵌入式开发人员可能只需要一个下午在他们能够阅读、理解和成功修改 JavaScript 代码之前。
当然,有效地使用任何编程语言都需要学习。许多 JavaScript 书籍都专注于构建网页,但 David Flanagan 的优秀 JavaScript:权威指南介绍了独立于 Web 的语言。Crockford 颇具影响力的 JavaScript: The Good Parts 是一本面向有经验的 JavaScript 程序员的固执己见、务实的风格指南。
但是脚本很慢
嵌入式开发人员对性能保持警惕。脚本语言天生就比 C 慢。因此,任何优秀的嵌入式开发人员的第一个冲动就是对任何脚本语言都抱有极大的怀疑。然而,提供卓越性能的可靠方法是可用的:
利用内置函数和对象。JavaScript 语言具有复杂的内置对象,支持数组、JSON、正则表达式和其他字符串操作。这些实现通常在 JavaScript 引擎中得到了很好的优化。花时间了解这些,以避免在您的脚本中重复它们的功能。
仔细编码。因为脚本比本机代码慢,所以优化良好的代码对于性能至关重要。JavaScript 的动态特性意味着 JavaScript 引擎通常无法像 C 编译器那样有效地优化代码。
不要试图在脚本中做所有事情。本机代码更快,因此将其用于计算复杂的功能。没有一种语言适合所有情况,所以选择最适合工作的语言,而不是试图“100% 纯正”。每个 JavaScript 引擎都提供了一种从脚本调用本机代码的方法。如果不确定性能,请先在 JavaScript 中实现,因为它更容易实现。之后,对系统进行概要分析。如果存在性能瓶颈,请在 C 中重新实现该函数。
JIT 呢?
提高解释代码性能的常见解决方案是即时编译器 (JIT)。JIT 将脚本代码编译为目标设备上的本机代码。JIT 的使用在现代 Web 浏览器的 JavaScript 引擎中很常见。但是,在嵌入式设备上使用 JIT 是有问题的,因为 JIT 本身需要额外的代码空间,因为除了原始脚本代码之外,本机代码还需要消耗内存,并且因为运行 JIT 需要 CPU 周期。
与 Web 浏览器相比,嵌入式设备具有一个显着优势:虽然浏览器必须能够高效地运行数十亿网页中的任何一个,但嵌入式设备只需要高效地运行其内置软件。这使嵌入式开发人员可以选择直接用 C 语言编写性能关键的脚本,而不是依赖 JIT。
Mozilla 的一个项目 asm.js 中出现了使用 C 的有希望的替代方案。asm.js 定义了一个严格的 JavaScript 子集,它更容易转换为本机代码或 C 源代码。asm.js 利用 C 和 JavaScript 之间的语法相似性来简化翻译。嵌入式开发人员可以在 asm.js JavaScript 子集中编写性能关键代码,并将其编译为本机代码作为构建过程的一部分,而不是依赖于 JIT。asm.js 的初始开发工作显示性能约为最佳本机实现的一半,预计其他开发将缩小这一差距。
记忆
内存空间是嵌入式开发人员的另一个关键问题。JavaScript 既有优点也有缺点。一个明显的缺点是用于执行脚本的 JavaScript 引擎,这是一个不小的大小——从几十千字节到几兆字节不等,具体取决于引擎。因为 JavaScript 使用动态类型,变量有一些额外的内存开销。作为最坏情况的示例,布尔值可能使用 16 个字节。
积极的一面是,JavaScript 使用垃圾收集器,无需显式释放内存。通过这种简化,嵌入式开发人员有时间专注于开发的其他方面。此外,通过自动释放未使用的内存,垃圾收集器消除了许多缓慢的、小的内存泄漏,这些泄漏会导致长期不稳定,隔离和修复可能极具挑战性。仅这一点就使得必须可靠运行数月或数年的嵌入式系统变得非常重要。此外,在某些情况下,研究表明垃圾收集器的 CPU 要求低于显式释放内存。
垃圾收集器的一个风险,尤其是在内存受限的环境中,是抖动——垃圾收集器运行得太频繁以至于对系统性能产生不利影响。这个问题可以通过 JavaScript 编程风格来避免,这种风格在很大程度上限制了对嵌入式设备或应用程序中主要状态变化的新对象的创建。这种方法可以使内存使用保持稳定,因此垃圾收集器不需要经常运行。
用户脚本
使用 JavaScript 的嵌入式设备可以选择由最终用户启用脚本。由于 JavaScript 是一种托管执行环境,因此可以通过安全地沙盒化脚本来确保最终用户的脚本能力。通过允许消费者、爱好者和专业程序员编写设备脚本来实现的定制将创造新的机会,就像智能手机上的应用程序革命一样。
今天的嵌入式 JavaScript
嵌入式设备不再是孤岛。它们通过云中的网络服务、网络浏览器以及手机和平板电脑相互连接。JavaScript 是唯一可用于为所有人开发软件的语言,以及他们使用 JSON 交换的数据。
JavaScript 在嵌入式设备上为嵌入式程序员简化开发工作——并为客户提供更可靠、更可定制的产品——的潜力是巨大的。通过采用 JavaScript,嵌入式设备的创建者将能够利用许多活跃的 JavaScript 程序员的创新。
作为一个行业,我们正处于 JavaScript 在嵌入式设备中成为现实的风口浪尖。幸运的是,已经有三种开发系统可供开发人员开始使用嵌入式 JavaScript:
Espruino 是一个单芯片开发板,标榜为用于微控制器的 JavaScript。它运行开源的 Espruino JavaScript 引擎,该引擎支持 JavaScript 标准的一个子集。
Tessel 将集成的 Wi-Fi 引入以 JavaScript 为中心的微控制器解决方案。Tessel 提供了与 node.js 兼容的 API,便于 node.js 开发人员采用。Tessel 将 JavaScript 翻译成 Lua(另一种脚本语言)来执行。翻译实现了 JavaScript 标准的一个子集。
Marvell Semiconductor 的 Kinoma Create 是一款“基于 JavaScript 的物联网构建工具包”,运行 Marvell Semiconductor 的 XS JavaScript 引擎,支持完整的 JavaScript 第 5 版标准。
这些开发系统中的每一个都是在嵌入式设备上开始 JavaScript 开发的好工具。尽管 JavaScript 在近 20 年前首次引入,但它才刚刚开始用于嵌入式计算。毫无疑问,这将有许多令人兴奋的方式将进一步发展。通过现在开始,您可以帮助塑造 JavaScript 在未来嵌入式系统中的使用方式。
审核编辑:郭婷
-
嵌入式
+关注
关注
5068文章
19008浏览量
302968 -
物联网
+关注
关注
2903文章
44240浏览量
371022 -
JAVA
+关注
关注
19文章
2956浏览量
104531
发布评论请先 登录
相关推荐
评论