MicroLua – RP2040 开发板上的 Lua 语言

Lua 是一种小型的嵌入式语言,它易于学习且速度相当快。RP2040 是一款小巧而强大的微控制器,具有一组漂亮的外设和活跃的开发人员社区。除了 Raspberry Pi 的官方 Pico 和 Pico W 板外,还可以购买各种形状和配置的各种廉价模块。

MicroLua 允许在 Lua 中对 RP2040 微控制器进行编程。它打包了最新的 Lua 解释器,其中包含 Pico SDK 的绑定和协作线程库。

特性

  • 原始的、未打补丁的 Lua 解释器:MicroLua 运行最新的、未修改的 Lua 5.4.x 解释器,作为 git 子模块导入。所有自定义都是通过 luaconf.h 完成的。
  • 每个核心的解释器实例:MicroLua 在每个核心中运行一个单独的 Lua 解释器。除非通过 C 库,否则它们不共享状态。
  • 通过 Lua 协程实现协作多线程:MicroLua 将协作线程实现为协程。这样就可以在不需要锁的情况下进行多任务处理。阻塞库调用(例如 pico.time.sleep_us())会让步给其他线程。
  • 与 C 库的精简绑定:MicroLua 公开了 Pico SDK 提供的功能的不断增长的子集。绑定设计为直接且一致地映射到其基础 C 实现。
  • Fennel 的支持:Fennel 源被转译为 Lua。
  • 全面的单元测试套件:它们不仅测试绑定层,而且在可能的情况下还测试 Pico SDK 的底层功能。

性能

对于不需要非常低延迟的应用程序来说,性能已经足够了,但它可能会更好。事件调度延迟目前为数百微秒,这是相当慢的。这主要是由于一个简单的线程实现,它还可以改进。

因此,在 Lua 中尝试位碰撞高速串行协议或 PWM 可能不现实,但这就是 PIO 和 PWM 外设的用途。任何需要精确计时的东西都应该用 C 语言实现。但是 Lua 对于非时序关键逻辑来说是一种很好的胶水语言,并且非常容易与 C 语言代码实现接口。

构建

下面是一个测试的例子,用解释如何在树莓派 Pico 上构建 Lua 代码。

# Configure the location of the Pico SDK. Adjust for your setup.
$ export PICO_SDK_PATH="${HOME}/pico-sdk"

# Clone the repository and initialize submodules.
$ git clone https://github.com/MicroLua/MicroLua.git
$ cd MicroLua
$ git submodule update --init

# Connect a Picoprobe to the target, on the UART and optionally on the debug
# port. Then view the Picoprobe's UART connection in a separate terminal.
# The "term" script uses socat.
$ tools/term /dev/ttyACM0

# Build the unit tests.
$ cmake -S . -B build -DPICO_BOARD=pico
$ make -j9 -C build/lib

# Start the target in BOOTSEL mode and flash it with picotool.
$ picotool load -v -x build/lib/mlua_tests.elf

# Alternatively, start the target in BOOTSEL mode and copy to its boot drive.
$ cp build/lib/mlua_tests.uf2 /mnt/RPI-RP2/

例子

MicroLua-examples 仓库包含演示如何使用 Lua 的 RP2040 功能的示例程序。

这是 MicroLua 中的 blink 示例,它是 pico-examples 仓库中 blink 示例的翻译。

_ENV = mlua.Module(...)

local gpio = require 'hardware.gpio'
local pico = require 'pico'
local time = require 'pico.time'

function main()
    local LED_PIN = pico.DEFAULT_LED_PIN
    gpio.init(LED_PIN)
    gpio.set_dir(LED_PIN, gpio.OUT)
    while true do
        gpio.put(LED_PIN, 1)
        time.sleep_ms(250)
        gpio.put(LED_PIN, 0)
        time.sleep_ms(250)
    end
end

文档

https://github.com/MicroLua/MicroLua/



坐沙发

发表评论

你的邮件地址不会公开


*