JavaScript 也可以搞定嵌入式开发? | 硬创公开课

简介:
     嘉宾介绍:郑晔,Ruff CTO,Oracle Duke选择奖获奖作品Moco的作者,目前投身于 IoT 领域,致力于简化 IoT 应用的开发方式。他多次在各种媒体上发表文章,在各种技术大会上做过演讲,对敏捷软件开发、软件设计、领域特定语言等方面,有着深刻理解,愿意分享自己对于软件开发的理解,也愿意吸收新的知识,更愿意与人畅聊软硬件开发。

JavaScript 也可以搞定嵌入式开发? | 硬创公开课

【Ruff CTO 郑晔】

IoT(Internet of Things)是大家公认的未来。但让人尴尬的是,这些代表未来的炫酷产品似乎只存在于业内人士的 PPT 中。真正走进普通人生活的,大多只是一些“带有 Wi-Fi 的普通硬件”。和大多数生态普及过程中遇到的问题相同,IoT 缺少一个关键的系统——应用。应用缺失,自然难以营造用户生态。然而这并不完全是开发者的责任,大多数情况下,开发者都处在臣妾做不到的状态,因为涉及硬件的“嵌入式开发”需要非常多的底层硬件代码基础,这让广大的软件程序猿望而却步。

“Ruff”的目标就是解决这个问题。简而言之,Ruff 可以允许开发者用普及的 JavaScript 语言进行嵌入式开发,他们究竟是怎么做到的呢?且听 Ruff CTO 郑晔慢慢道来。

何谓 Ruff?

Ruff 是一个硬件应用开发平台。简言之,通过 Ruff,开发者可以使用 JavaScript 开发硬件应用。

从行业发展趋势可以看到,IoT(Internet of Things)是大家公认的未来。大家也知道,我国目前在生产制造的水准也是世界级的。但是,从趋势到现实中,中间还欠缺了什么呢?我们看到的是:应用。

我们都在说智能硬件。实际上,所谓智能硬件是一个“硬件应用”,是把硬件和应用场景结合起来。应用的成功本质上是个概率问题,我们之所以还没有看到很多成功的硬件应用,主要是应用的总体数量太少。很多人都能看到这是一片蓝海,但问题是,并不是每个人都有能力进入到这个领域,因为硬件应用的门槛太高了。

这一点类似于 Nokia 手机的时代,很多人都想编写手机应用,但只有很少量的程序员有能力编写手机应用,我自己就曾经希望买 Nokia 手机来做开发,但最后放弃了,也是因为开发太麻烦。后来有了 iOS 和 Android,开发门槛一下子降了下来,大量的程序员涌了进来,才有了我们看到的移动互联网的兴起,也才有了微信、滴滴等爆款应用。

所以 Ruff 就是要在硬件应用开发领域解决同样的问题,降低硬件应用开发的门槛,让更多有应用开发能力的人进入到这个领域里。

有一个前端开发者,他拿到 Ruff,很快就写了一个小应用:用打火机点亮网页上的一盏灯。因为有了 Ruff,这个从来没写过硬件的开发者,就有机会开始编写硬件应用了。这就是 Ruff 降低门槛起到的作用。总结起来,Ruff 就是要降低硬件应用开发门槛,让开发者能够创造出更多有创意的硬件应用。

硬件应用开发的门槛有多高?

从现状来看,硬件和应用完全就是两套词汇表,比如,做硬件的人关心的是,GPIO、I2C、时序、驱动等,而做应用的人关心的是,需求、用户体验、高可用性、系统架构等。我问过应用开发者什么是 GPIO,他们的表情就像见了鬼一样;我也曾让硬件开发者讲讲什么是 SOLID 设计原则,很少有人能讲清楚。

这就是软硬件之间的鸿沟,让一个人同时具备硬件和应用两套技能,这是很高的要求。其实,即便是只在硬件开发领域,除了应用以外,做系统的和做硬件的也是不同的话语体系,有人关注进程,有人关注晶振;有人关注嵌入式系统,有人关注 PCB。

让一个人掌握好所有的东西,难度系数会直线上升。即便有这样的人,价格也会非常高,而且能找到的人数量也有限。另外,在硬件领域,重复造轮子的现象是很严重的。很多东西即便开发者再熟悉,到了一个新的环境可能就要重新做一遍,比如,常见的网络协议要移植,常见的驱动要编写。我的这些印象,全部来自一个有20年硬件开发经验的老法师,他将其称为血泪史。

与应用的对接中,硬件开发的过程,基本上是一个瀑布式开发的过程,或者说一个自顶向下的过程,也就是说,把需求确定好了,然后,进入一个开发过程,这个过程往往会持续很长一段时间。从软件工程的实践来看,这是一种低效的做法,因为做产品,最重要的是快速反馈,一年前的市场需求和现在的市场需求是不同的。

所以,在软件领域有了敏捷、精益等方法论,改善这个过程,最重要的就是迭代的思想,不断地对产品进行改进。目前市面上很多有想法的人来自互联网领域,他们习惯了与软件应用开发者协同工作,所以,他们也更习惯采用迭代的思想进行工作,但同样的工作逻辑拿到硬件领域几乎没办法行得通。

举个例子,

产品经理希望迭代地看到产品进展,因为他的想法需要反复验证,而硬件开发者希望确定好需求再来做开发,因为在他的逻辑里,硬件是一旦制成就很难改变了。

造成这种现象更根本的原因是,是硬件制造商在编写应用。而应用开发根本就不是硬件制造商擅长的。当我们可以把硬件和应用两个概念分开之后,我们就会发现,同样的硬件,在不同的场合下,可以有不同的应用。

举例来说,

  • 同样的饮水机,如果你买了回家,它的应用是统计你家的饮水状况,提醒你多喝水;

  • 如果把饮水机租回家,它会提醒你按时缴费,保证正常使用。

硬件上是一样的,但应用是不同的。解决这个问题最好的办法就是分工,让应用开发者只关注应用,硬件制造商只关注硬件。将二者联系起来,这就是 Ruff 要做的事情。

为什么是 JavaScript?

对程序员来说,语言的选择永远是宗教战争。我们把 Ruff 定位成一个应用开发平台,所以,选择做技术选型的时候,尽可能考虑应用开发者熟悉的东西,所以 Ruff 选择了 JavaScript。 

首先,我们排除了硬件开发者最熟悉的 C/C++,因为 C/C++在多数程序员眼里是系统语言,一旦使用 C/C++,程序员们就会回到系统开发的思路上。

再次,我们排除的是目前最流行的语言 Java。从受众的角度考虑,最该考虑的是 Java,这就是 Android 的做法,但在资源受限的硬件上,Java 太重了。

JavaScript 是一个恰当的语言,原因如下:

首先,它是一门真正的全平台语言,可以运行在所有系统上,包括浏览器、手机、服务器、客户端,都有。

其次,随着 Node.js 的流行,JavaScript 的社区越来越活跃,许多新想法都是在这个社区内涌现出来的。

再次,JavaScript 有很多不错的运行时实现,方便我们开展工作。套用软件开发社区里的一个 说法:Atwood 定律,所有能用 JavaScript 写的应用,最终都会用 JavaScript 写就。

然而,根因是受众面,不需要从头教育市场。所以,Ruff 选择了 JavaScript。事实上,很多大厂也下水做这个领域,大部分人的选择也是 JavaScript。

JavaScript 比 C 语言更有优势吗?

从个人的角度来说,我更愿意比较的是抽象层次,而非简单的语法。从技术的发展趋势,我们已经非常清楚地看到,应用开发的抽象层次是越来越高的。

比如:最开始大家是用机器码,因为记忆不方便有了汇编,又因为汇编对于不同机型差异太大,而产生了 C 这样的程序设计语言,再往后,C++提供了面向对象程序设计,给程序组织提供了一种良好的方案。越高的抽象,意味着编写同样多的内容用的代码越少。

我曾经对比过一个大厂出的 C/C++的硬件应用开发框架,点亮一个板载灯,它写了大约50行左右的代码,用 Ruff,我写了3行代码,还有2行是框架代码。

$.ready(function() {

  $('#led-r').turnOn();    

});

通过这段代码大家就可以感受到差异,真正的核心代码只有1行,这就是抽象的价值。

只使用 JavaScript 能做到怎样的开发深度?

JavaScript 语言社区已经提供了许多好的抽象,比如,基于事件的模型。

Ruff 还建立了自己建立的抽象。比如划分了驱动开发者和应用开发者,只有驱动开发者需要关心硬件细节,而应用开发者只要关注应用逻辑就好了。

刚才给大家展示的这段代码就是一段应用代码,你根本看不到硬件参数这些东西,这就是分层架构的力量,抽象的力量。此外,Ruff 在设计之初,就考虑了应用测试的问题。用 Ruff 开发的代码可以在开发机器上把逻辑测试好,再部署到具体硬件板子上。这样可以防止因为一些低级错误,反复烧板子,造成时间上的浪费。

Ruff 还配套了命令行工具,简化应用开发和板卡部署,另外还有一个软件仓库,可以让驱动开发者上传自己的驱动,与社区分享。

至于实现JavaScript的硬件编程,道理上很简单:运行一个 JavaScript 引擎,在上面跑 Javascript 的程序。

从具体的实现上来说,

第一步:选择了一个嵌入式 JavaScript 引擎;

第二部,在一个操作系统上把它运行起来,在其基础上构建 Ruff,这也是目前对外发行的版本。

简单来说,这是从打造最小可行产品(MVP)的思路来做的。Ruff 内部正在研发基于 MCU 的版本,也就是将 JavaScript 引擎直接跑在硬件上。这样可以更好地解决功耗、实时性等问题。

Ruff 的未来

现在,开发者能看到一些开发板,例如:树莓派、Ardunio 和 Intel Edison。而 Ruff 提供了一个开发框架。另外 Ruff 本身也提供了一套开发套件,这么做的原因是为了让人尽快上手 Ruff。

更关键的差异在于,这些开发板只能做小应用或是原型,当然,这也是 Ruff 开发套件的现状。不同的是,我们做 Ruff 的目的不限于此,我们是希望将 Ruff 将来打通到生产环节中。也就是说,一个硬件应用在软件代码完全不用修改的情况下,把它用在更真实的设备上,比如 MCU 上。我们很清楚,Ruff 的终点不是开发板,这与其它的开发板目标是截然不同的。

坦白来讲,让应用开发者意识到自己能够编写硬件应用会是比较困难的。很多软件程序员思考问题的边界就是硬件,根本不敢想这方面的问题。就像 Android 和 iOS 之前,应用开发者不会觉得自己能写手机应用一样。这里面是一个意识的鸿沟,大多数应用开发者并不觉得硬件开发和他们有什么关系。正因为他们觉得硬件应用开发太困难,才会退避三舍。

对于 Ruff 而言,这是一个教育市场的过程。其实,硬件应用开发其实很简单:控制你家的电视很简单,点亮家里的灯也没那么难。跨越了意识上的鸿沟,再来了解硬件,就不那么困难了。当我们的正式版发布之后,我们会在开发者社区方面投入大量的精力,让开发者们意识到,他们能做的事情其实更多。


于Ruff的最新动态

在1月份,Ruff 推出了少量的公测版套件,定向地发给了一些有兴趣的用户,软件 SDK 随公测版发布。大致一个月左右会有一次新的发布。郑晔表示,正式版在内部的备货基本上已经完成,五一之后,就会正式开始销售,更多的开发者就可以尝试新的开发体验了。

  
 
  本文作者: 史中

本文转自雷锋网禁止二次转载, 原文链接
目录
相关文章
|
30天前
|
开发框架 JavaScript 安全
js开发:请解释什么是Express框架,以及它在项目中的作用。
Express是Node.js的Web开发框架,简化路由管理,支持HTTP请求处理。它采用中间件系统增强功能,如日志和错误处理,集成多种模板引擎(EJS、Jade、Pug)用于HTML渲染,并提供安全中间件提升应用安全性。其可扩展性允许选用合适插件扩展功能,加速开发进程。
|
1月前
|
缓存 JavaScript 前端开发
js开发:请解释什么是Webpack,以及它在项目中的作用。
Webpack是开源的JavaScript模块打包器,用于前端项目构建,整合并优化JavaScript、CSS、图片等资源。它实现模块打包、代码分割以提升加载速度,同时进行资源优化和缓存。借助插件机制扩展功能,并支持热更新,加速开发流程。
20 4
|
1天前
|
JavaScript 前端开发
js开发:请解释事件冒泡和事件捕获。
JavaScript中的事件处理有冒泡和捕获两种方式。事件冒泡是从子元素向上级元素传递,而事件捕获则从外层元素向内层传递。`addEventListener`的第三个参数可设定事件模式,`false`或不设为冒泡,`true`为捕获。示例代码展示了如何设置。
15 2
|
1天前
|
JavaScript 前端开发
js开发:请解释this关键字在JavaScript中的用法。
【4月更文挑战第23天】JavaScript的this关键字根据执行环境指向不同对象:全局中指向全局对象(如window),普通函数中默认指向全局对象,作为方法调用时指向调用对象;构造函数中指向新实例,箭头函数继承所在上下文的this。可通过call、apply、bind方法显式改变this指向。
7 1
|
1天前
|
JavaScript 前端开发
js开发:请解释同步和异步编程的区别。
同步编程按顺序执行,易阻塞;异步编程不阻塞,提高效率。同步适合简单操作,异步适合并发场景。示例展示了JavaScript中同步和异步函数的使用。
11 0
|
9天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
1月前
|
Web App开发 JavaScript 前端开发
js开发:请解释什么是Node.js,以及它的应用场景。
Node.js是基于V8的JavaScript运行时,用于服务器端编程。它的事件驱动、非阻塞I/O模型使其在高并发实时应用中表现出色,如Web服务器、实时聊天、API服务、微服务、工具和跨平台桌面应用(使用Electron)。适用于高性能和实时需求场景。
18 4
|
1月前
|
JavaScript 前端开发 编译器
js开发: 请解释什么是Babel,以及它在项目中的作用。
**Babel是JavaScript编译器,将ES6+代码转为向后兼容版本,确保在旧环境运行。它在前端构建中不可或缺,提供语法转换、插件机制、灵活配置及丰富的生态系统,支持代码兼容性和自定义编译任务。**
17 6
|
1月前
|
JavaScript 前端开发
js开发:请解释什么是ES6的async/await,以及它如何解决回调地狱问题。
ES6的`async/await`是基于Promise的异步编程工具,能以同步风格编写异步代码,提高代码可读性。它缓解了回调地狱问题,通过将异步操作封装为Promise,避免回调嵌套。错误处理更直观,类似同步的try...catch。
|
1月前
|
JavaScript
js开发:请解释什么是ES6的Generator函数,以及它的用途。
ES6的Generator函数是暂停恢复的特殊函数,用yield返回多个值,适用于异步编程和流处理,解决了回调地狱问题。
16 6