# 深入理解 烧录模式 和 在线模式

阅读提示

如果你对 BlocklyScratch 的概念还比较模糊,你可以先看阅读这一篇文章 uCode 和 Blockly、Scratch 之间的关系

# 烧录模式

烧录模式,核心功能就是用到了 Blockly 里面的转代码 Generating Code (opens new window)功能,它可以把每个积木块转成对应的目标语言的代码

# 烧录模式概念

烧录模式最重要概念就是,宿主不一样,烧录模式的宿主是:硬件设备,就是代码是在硬件设备上执行的。

烧录模式有好几种叫法:

  • 烧录
  • 上传

烧录有时候叫,“上传” 模式,那为什么叫 “烧录”“上传”,很多开发同学习惯翻译为 Burn 或者 Upload,实际上烧录/上传模式更像 FlashFlash 的意思也可以理解为 “刷机”,刷机大家都知道了,就是通过 PC/Mobile 就是程序提供者,术语称为上位机,把程序,通过一定的方式刷进一个硬件设备里面,术语成为下位机。

因此烧录模式的意思就是说,我们需要把当前积木块转换的代码,写进硬件设备中,对应 uCode 这里,我们只要把积木转换成对应硬件需要的代码,例如 Arduino 是 C++, Microbot 是 Python。

实际上,实现烧录模式的话,我们只需要 Blockly 就可以满足了,这也是目前 uCode 的版本实现方式,虽然我们使用的 Scratch 版本的 Blockly,但实际上我们只用了 Blockly 的功能,并没有使用其他功能(至少 VM 是没有用)

# 烧录模式优点

  • 脱机运行

    烧录模式的优点就是,它可以脱离编程的环境执行,就是说烧录的程序之后可以离开电脑,或者手机脱机执行,这对部分场景,例如:竞赛,有强烈的应用需求

  • 延迟低

    积木块的前后上下文(就是两个积木之间的运行延迟)是在硬件内部,省去了中间的通信延迟,因此,一大段的程序运行起来会比较连贯

# 烧录模式缺点

  • 性能弱

    硬件性能比起电脑,手机,功能丰富性都比较弱,有很多不支持

  • 不能支持多设备,开发难度大

    和其他硬件设备联动比较麻烦,要单独开发

  • 无法实时预览

    上面也说过,Blockly 的功能特点,Blockly 不具备预览功能,每次更改都要把整段代码烧录到硬件再运行才能看到效果,特别对于 Arduino 需要完整编译的过程,每次时间预览需要将近半分钟到一分钟的时间,这对于编程调试来说是一个非常低效的行为。

# 在线模式

# 在线模式概念

在线模式最重要的概念是,执行的宿主是在电脑或者手机端(就是 IDE 编程的环境)

在线模式也有好几种叫法:

  • 在线
  • 舞台
  • 实时
  • 联机

实际上这些都差不多一个意思,主要看实际场景 (有没有舞台,之类)

当然在线模式也有两种区分:

  • 基于 Blockly 转代码的在线模式,Arduino 设备 的在线模式
  • 基于 VM 虚拟机的在线模式,以 Scratch 为首的在线模式

# Blockly 转代码

上面提到过,Blockly 实际上只是一个编辑器,是不提供运行环境的,所以用 Blockly 实现的在线模式其实有点弱,你只能转换成代码,例如 JavaScript 代码,或者 Python 代码,然后扔给浏览器,或者 Python 解析器执行。如果单纯使用 Blockly 还需要管理整套的运行状态,例如,积木能不能停止,各个 Branch 之间的是否要开多线程还是单线程使用队列执行,都是手动开发,并且需要有大量的调试。

所以就算可以用 Blockly 开发在线模式,它的运行状态管理是比较弱的。所以通常我们说的在线模式是基于有 VM 模式的在线模式。

# Virtual Machine 虚拟机

因此很多 Blockly 的二次衍生品都会有一个 VM(Virtual Machine) 虚拟机的概念

例如:Scratch 有 Scratch-VM,编程猫也有 它自己研发的 VM

VM 通常会抛弃掉原来 Blockly 的转代码功能,而是把积木块当做每个执行的最小单位,它会把积木块上的各种参数,当做函数的参数运行,当运行了整个项目的时候,其实是由 VM 去调动各个积木块依赖的函数功能,至于是队列,还是多线程还是其他,这些与 VM 的整个设计理念有关

那基于 VM 模式的在线模式有什么优缺点:

# 在线模式优点

  • 预览模式

    由于由 VM 来管控,因此粒度可以非常细,可以单个积木运行,实现预览功能非常简单

  • 跨平台,对硬件依赖小

    对硬件的依赖非常小,不需要处理各种语言问题

  • 支持多设备联动,开发容易

    由于运行在电脑或者手机上,它很容易和其他设备联动,也非常容易扩展

# 在线模式缺点

  • 延迟大

    由于所有的运行都是 VM 托管,每个积木之间的延迟是很大的,特别是无线,蓝牙之类的通信方式,会更大

  • 对通信有要求

    需要专门开发通信协议去适配(例如,蓝牙,串口,websocket)

  • 对宿主环境有要求

    通常只能运行在电脑手机等功能强大的设备上

# 硬件的烧录模式和在线模式

图形化的编程区分模式,为什么硬件也要区分模式。

# 硬件烧录模式

主要是这两个模式下,硬件的处理是不一样的,烧录模式实际上只需要有几个简单的指令就可以实现(发送文件具体的硬件不一可能会不一样)

Arduino 并不需要开发协议解析,因为 Arduino 有整套工具链,ESP32 或者 micro:bit 则需要另外写指令解析,发送文件,运行脚本,停止脚本,删除文件等基本指令

硬件烧录模式示意图

# 硬件的模式切换

那为什么硬件会有模式切换呢?

上面介绍了两种模式,整个通信和执行方式都是不一样的,硬件处于烧录模式下,是以执行离线的脚本的为主,受制于硬件的性能,这些硬件的性能都比较弱,都是单核,没有多线程的概念,如果它正在运行离线的脚本,它就没有办法再去实时响应在线模式的指令,因此 优必选这边的软件嵌入式设计都会有一个模式选择,来告诉它优先处理哪些问题。

例如:

  • uCode 团队内置的硬件 uKit Explore 就会有两种模式,要通过复位,或者发送指令来切换模式
  • uCode 团队内置的硬件 uKit AI 则需要发送特定的停止指令,来停止当前的离线脚本执行

# uCode 的 烧录模式 和 在线模式 特色

虽然 烧录模式 和 在线模式 分别是两个东西,uCode 里面,我成功的把它做到了一块,积木块可以互相转换,只是需要注意的是

当 uCode 切换到 烧录模式的时候,VM 是处于停止状态的,意思就是,整个项目会被停止,所有的积木块都不会被执行,而且预览效果是处于关闭的,这样设计的目的为了保证各个角色色状态一致

当有一些积木不支持烧录模式的,会被置灰,这样可以保证烧录模式转代码之后功能正常