#vm #hot-reloading #smart-leds #javascript #pixelblaze

nightly no-std trenchcoat

适用于嵌入式、LED、热代码重载等的 JavaScript 风格虚拟机

9 个版本 (4 个破坏性更新)

0.5.1 2022 年 11 月 14 日
0.4.4 2022 年 10 月 31 日
0.3.0 2022 年 10 月 30 日
0.2.0 2022 年 10 月 30 日
0.1.0 2022 年 10 月 29 日

#106 in 模拟器

每月 28 次下载

自定义许可证

1MB
2K SLoC

Rust 1.5K SLoC // 0.1% comments JavaScript 386 SLoC // 0.2% comments Python 38 SLoC // 0.2% comments Shell 2 SLoC // 0.5% comments

深层涂层中有 3 种语言

JavaScript(在语法上)、FORTH(在精神上)和 MicroPython(在范围和混合奇特的酷炫特性上)的疑问组合。

亲爱的 $deity,为什么?

  • 在嵌入式设备上进行热代码重载,而无需闪存整个新的二进制文件:特别是在 esp32-idf 映像大小和因此周转时间可能是一个障碍。
  • Pixelblaze 端口移植到 Rust。

看看它的实际效果

这是实时代码编辑器(观察最后一行中 hsv(...) 调用的更改)+ 浏览器内的渲染,以及发送到 no_stdno_alloc 微控制器的热代码重载。

功能

  • 非常 快速的周转,代码更改与网络应用程序/微控制器更新之间没有明显的延迟

  • 已经注意保持运行时平台、语言和语言方言的通用性。这意味着

    • 运行时:您可以在 PC、微控制器或浏览器上运行 trenchcoat
    • 语言方言:Pixelblaze 特定的 JavaScript 扩展已分离开来,并且不会污染标准 JS 命名空间
    • 语言:实际执行代码的虚拟机是一种与语言无关的堆栈机器,恰好有一个 JavaScript 解析器 在附近。如果您想添加,例如,Python 语法支持,您完全可以!我不会!(欢迎提交拉取请求)

限制

  • 由于一些原因,目前需要 nightly Rust。
  • 只支持极小部分的JavaScript和Pixelblaze功能。您想要for循环?或许在下一个版本中...
  • 非常未优化!此外,基本上没有考虑先前的艺术,所以可能充满了傲慢的新手™错误。
  • 在微控制器上不可进行解析(因此,没有设备上的REPL)。架构允许实现它。
  • 没有堆,我们被迫使用heapless集合,这对于trenchcoat的使用案例来说很浪费。因此,从版本0.5开始,即使是no_std STM32F4应用也使用分配器。可能会在某些时候删除对no_alloc的支持,但现在仍然保留。
  • 需要通过律师处理许可。

说够了,我怎么运行这个?

目前的主要目标是使Pixelblaze支持成熟,因此这些说明也将专注于这一点。

一般方法如下

  1. 选择一个运行时(控制台/网络/嵌入式)并将JavaScript/Pixelblaze源代码编译成字节码。Pixelblaze示例可以在res/中找到,尽管截至版本0.5,只有rainbow melt.js被验证为可以工作 - 仍有很多实现细节缺失!
  2. 仅嵌入式:选择一个更新路径 - 网络应用使用内联编译 + HTTP到UART更新以实现热代码重新加载,但如果不需要这些,也可以使用捆绑的console-compiler将字节码编译到磁盘(建议的文件扩展名是.tcb,表示“TrenChcoat 字节码”)并“ somehow”让固件访问它,例如通过include_bytes!。如果您想通过HTTP更新,但MCU通过UART连接(例如,捆绑的stm32f4-app),则以桥接器启动http-to-serial.py /dev/YOUR-SERIAL-DEVICE
  3. 生成一个Executor,只需调用一次start(),然后根据需要多次调用do_frame()来生成LED颜色。在no_std上,需要手动从某个计时器源(例如示例应用重新使用帧任务的时间间隔)更新“当前时间”。Executor::exit()是可选的。

要选择的特性标志集

  • 桌面:["full"]
  • 网络应用/wasm:["compiler", "log", "use-std"]
  • 嵌入式:["defmt"]或者当您有一个分配器时,使用["defmt", "alloc"]
    • ESP32带IDF支持(std支持):["log", "use-std"]

(注意:目前日志功能完全失效,直到我修复了宏)

WeAct STM32F4x1即“USB-C药丸”、“黑色药丸”

  • 您需要一个正常工作的硬件探头和probe-run设置。
  • 示例应用使用PB15上的SPI2和16个WS2812 LED。大部分LED处理都在相邻的f4-pericrate中完成;您也可以通过使用spi特性而不是默认的spi_alt来使用SPI1+PB5。如果更喜欢更稳定的LED,f4-peri还支持SK9822/APA102协议。
cd console-compiler
cargo run -- -f pixelblaze -i ../res/rainbow\ melt.js -o "../res/rainbow melt.tcb" 
cd ../stm32f4-app
# probe-run is required
cargo rrb app

此时,您可以发送.tcb数据,通过cat ../res/rainbow melt.tcb > /dev/<USB UART>,或者启动网页代码编辑器及python网页到UART桥接器进行实时编辑!

帮助,应用崩溃说堆栈太满了!

尝试在src/bin/app.rs中增加HEAP_SIZE

Espressif C3

包目录:esp32-c3-app

您需要一个正常工作的Espressif本地工具链安装 - 更多详细信息这里

config.toml.example复制到config.toml并编辑您的WiFi和LED设置。当前固件支持WS2812和APA102/SK9822 LED协议,分别通过ws2812(数据引脚)和apa102(时钟和数据引脚)特性实现。

使用cargo espflash --release --monitor /dev/<ESP UART HERE> --features WS_OR_APA进行构建、擦写和运行。设备加入WiFi网络成功后,会打印出站(设备)IP。将此IP放入网页应用config.tomlendpoints=列表中,并启动网页应用(或使用console-compilercurl将新字节码POST到http://<station ip>/)。

Espressif S2

由于C3应用使用esp-idf,移植工作应该不会太多,有谁愿意尝试吗?

Raspberry Pi Pico

待办事项,即将推出!

浏览器/实时代码编辑器

一只酷熊从相邻的宇宙中诞生

酷熊:浏览器?意思是…你在浏览器中运行一个原始的JavaScript虚拟机…在浏览器中…

作者,穿着紧身衣:你完全说对了。没有任何性能提升的卸载支持!

另一方面,我们不需要在构建过程中单独编译。因为编译器也在浏览器中运行,哈哈哈

配置

每次对代码编辑窗口的更改,Web应用程序都会尝试将源代码编译成字节码,并将其广播到所有配置的端点。复制 web-app/config.toml.exampleweb-app/config.toml 并设置

  • endpoints:字节码接收者列表 - http://127.0.0.1:8008/http-to-serial.py 的监听地址,以防您的目标没有自己的Web服务器。注意:如果您构建自己的Web服务器,它必须至少提供最小CORS支持(有关更多详细信息,请参阅 http-to-serial.py
  • pixel_count:浏览器中渲染的LED数量
  • initial_js_file:编辑窗口的初始内容,通过 build.rs 填充

运行中

  • 您可能需要先为Rust安装“wasm stuff”。
  • Web应用程序是用 Dioxus 编写的,这是一个Rust中的类似React的框架。它需要 dioxus-cli 来运行。
cargo install --git https://github.com/DioxusLabs/cli # their stable version seems broken atm
cd web-app
dioxus serve
$browser http://127.0.0.1:8080/

致谢

资源

Pixelblaze表达式语言

依赖关系

~4–14MB
~167K SLoC