ML307C Lua 高性能脚本环境

发布于:2025-09-02 ⋅ 阅读:(18) ⋅ 点赞:(0)

ML307C Lua 高性能脚本环境

https://gitcode.com/qq_29101739/ML307C-Lua

本项目为 ML307C OpenCPU SDK 深度集成了一套强大、稳定且可用于生产的 Lua 5.3.6 脚本环境。它并非简单的解释器移植,而是一个完整的开发生态,包含了抢占式调度器、非阻塞 API 以及丰富的硬件与网络接口绑定,专门为构建复杂、可靠且支持远程更新的物联网应用而设计。

其核心设计理念是:让开发者使用上层 Lua 语言处理业务逻辑,而底层 RTOS、硬件和网络协议栈的复杂性则由高度优化的 C 模块来处理。


核心特性

  • 抢占式协程调度器: 此环境的核心。它能有效防止任何单个 Lua 脚本(即使包含死循环)独占 CPU 而导致系统看门狗复位,从而确保了系统的稳定性和多任务并发执行能力。
  • 动态脚本加载: 支持从文件系统 (sys.dofile) 或字符串 (sys.loadstring) 加载并执行 Lua 代码。这是实现远程逻辑更新(热更新)的关键,无需进行完整的固件升级。
  • 事件驱动的非阻塞 API: 所有可能引起阻塞的操作,尤其是 mcu.sleephttp 客户端,都被设计为非阻塞模式。它们通过调度器挂起当前 Lua 任务,稍后在操作完成时恢复,而不会阻塞底层的 C 线程。
  • 丰富的 C 接口绑定: 提供了一系列清晰、上层的 Lua 模块,用于访问 ML307C 的核心硬件与网络功能。

快速上手

  1. C 入口: C 语言部分的入口函数 lua_test_entry_start() 负责初始化 Lua 虚拟机和调度器。
  2. 主脚本: 系统启动后,会首先从文件系统加载并执行 /main.lua 脚本。该脚本是所有用户业务逻辑的起点。
  3. 并发任务: 所有的应用逻辑都应通过 sys.task(function() ... end) 来启动。这会将一个函数注册为调度器管理的新任务,确保其与其他任务安全地并发运行。

main.lua 示例

log.info('--- Lua 主脚本已启动 ---')

-- 任务1: 周期性上报信号质量
sys.task(function()
  while true do
    local _, rsrp = net.get_signal_quality()
    log.info('信号质量 RSRP: ', rsrp, ' dBm')
    mcu.sleep(30000) -- 非阻塞休眠 30 秒
  end
end)

-- 任务2: 监听 UART1 串口指令
sys.task(function()
  uart.setup(1, 115200)
  uart.on(1, function(uart_id)
    local data = uart.read(uart_id, 128)
    log.info('从 UART1 收到数据:', data)
    if data == 'reboot' then
      mcu.reboot()
    end
  end)
  log.info('UART1 命令监听已启动')
end)

-- 任务3: 一个用于测试调度器稳定性的死循环任务
-- 由于抢占式调度器的存在,此任务不会导致系统崩溃
sys.task(function()
  log.info('死循环任务已启动,系统应保持稳定')
  while true do
    -- 这个循环在常规脚本环境中会导致看门狗复位,
    -- 但我们的调度器会周期性地强制让出 CPU。
  end
end)

API 参考

sys - 系统与调度器

  • sys.dofile(filepath): 从文件系统加载并执行一个 Lua 脚本。成功返回 true,失败返回 false, error_message
  • sys.loadstring(script_string): 从字符串加载并执行 Lua 脚本。成功返回 true, ... (附带脚本返回值),失败返回 false, error_message
  • sys.task(function, ...args): 创建一个由调度器管理的新并发任务。第一个参数必须是函数,后续参数会传递给该函数作为启动参数。

log - 日志

  • log.info(...)
  • log.warn(...)
  • log.error(...)

mcu - MCU 控制

  • mcu.reboot(): 重启设备。
  • mcu.chip_id(): 返回芯片的唯一 ID 字符串。
  • mcu.sleep(milliseconds): 非阻塞休眠。挂起当前任务,但不会阻塞其他任务。

gpio - GPIO

  • gpio.setup(pin_id, mode): mode - 0为输出, 1为输入。
  • gpio.write(pin_id, value): value - 01
  • gpio.read(pin_id): 返回 01

timer - 定时器

  • timer.start(callback_func, interval_ms, is_periodic): 启动一个定时器。is_periodic 是布尔值,true代表周期执行。

fs - 文件系统

  • fs.open(filepath, mode): 打开文件。mode 可为 “rb”, “wb”, “ab”, “rb+”, “wb+”, “ab+”。返回文件句柄或 nil
  • file:read(bytes): 从文件读取数据。
  • file:write(content): 向文件写入数据。
  • file:close(): 关闭文件句柄。
  • fs.remove(filepath)
  • fs.exists(filepath)
  • fs.rename(old_path, new_path)

net - 网络信息

  • net.get_signal_quality(): 返回 rssi, rsrp, rsrq 三个数值。
  • net.get_reg_status(): 返回网络注册状态码。
  • net.on_reg_change(callback_func): 注册网络状态变更回调。

mqtt - MQTT 客户端

  • client = mqtt.create(): 创建一个新的 MQTT 客户端实例。
  • client:on(event, callback): event 可为 “connect”, “disconnect”, “message”。
  • client:connect(host, port, client_id, user, pass): userpass 为可选参数。
  • client:publish(topic, payload, qos)
  • client:subscribe(topic, qos)

uart - 串口通信

  • uart.setup(id, baudrate, databits, parity, stopbits)
  • uart.write(id, data)
  • uart.read(id, max_bytes)
  • uart.on(id, callback_func): 注册串口数据接收回调。

sim - SIM 卡信息

  • sim.get_imsi()
  • sim.get_iccid()

ntp - 网络时间同步

  • ntp.sync(server, port, callback_func): 启动 NTP 同步。完成后将调用 callback(is_ok, time_str)

http - 异步 HTTP 客户端

  • client = http.create(): 创建一个新的 HTTP 客户端实例。
  • client:set_timeout(connect_ms, response_ms): 设置连接和响应超时。
  • client:on(event, callback):
    • "done": 请求成功。内存响应模式为 callback(status_code, body_string);文件下载模式为 callback(status_code)
    • "error": 请求失败。callback(error_code)
    • "progress": 下载进度。callback(received_bytes, total_bytes)
  • client:request(method, url, headers, body): 发起请求。headers 是一个 table,body 是字符串。headersbody 均为可选。
  • client:download(method, url, filepath, headers, body): 用法同 request,但会将响应体保存到 filepath 指定的文件。

网站公告

今日签到

点亮在社区的每一天
去签到