LuatOS入门指南:深入理解基于Lua的嵌入式开发架构!

本文旨在为初学者全面解析LuatOS这一基于Lua语言的嵌入式开发框架,从系统架构到运行机制,帮助新手快速掌握其核心原理与开发逻辑。

一、LuatOS 编程起步

1.1 底层固件怎么启动 LuatOS 脚本

1.1.1 脚本入口执行文件

简单来说,底层固件首先就是要找到 main.lua 这个文件,然后启动它。

所有的其他功能,都需要在 main.lua 发起。

1.1.2 LuatOS 启动脚本的详细流程

进一步详细的说,LuatOS 的底层固件启动脚本的流程如下:

1,系统上电或者复位后,底层固件(core)首先启动,进行硬件初始化、内存分配、文件系统挂载等系统底层的基础操作。

2,加载 Lua 虚拟机:底层固件加载 Lua 虚拟机,为执行 Lua 脚本提供运行环境;

3,自动查找并加载存储在设备上的主脚本 main.lua;

4,按顺序执行 main.lua 脚本中的代码,通常包括任务创建(如 sys.taskInit)、功能初始化等,从这一步,已经正式开始运行用户逻辑。

5,进入任务调度:脚本最后通常调用 sys.run(),进入事件循环和多任务调度。

1.1.3 怎么把固件和脚本烧录到硬件:

1,使用LuatTools ,将底层固件和用户 Lua 脚本烧录到模组或者引擎硬件;

2,上电后,底层固件自动完成上述启动和脚本加载流程,无需手动干预。

1.2 main.lua 需要包含哪些部分?

1.2.1 项目信息声明

在 main.lua 的文件开头,需要声明项目名和版本号,便于管理和调试。后续的远程升级,也需要用到项目名和版本号。

例如:


1.2.2 核心库,扩展库以及如何加载

在 main.lua 需要加载 LuatOS 的基础库和扩展库(如 zbuff,onewire,gnss 等)用来实现具体的业务逻辑。

核心库和扩展库的内容,在后续的章节里面介绍。

核心库在底层固件加载Lua虚拟机的时候,在底层固件已经自动加载,不需要在用户脚本中再去加载,例如sys,rtos等;

扩展库是Lua脚本文件写的库,需要在用户脚本中,使用require语句加载,例如libnet,httpplus等,加载方式如下:


1.2.3 至少启动一个任务

在 main.lua 里面,至少需要启动一个任务,否则这个 main 就无所事事,是一个没什么实际用处的主脚本了。

启动一个任务的方法,分为 2 个步骤:

1,创建一个函数,把要做的事情,放在这个函数里面使用。这个函数必须是无限循环的,防止很快结束生命,不妨把这个函数命名为 task1(),

2,调用 sys.taskInit(task1),启动这个函数,于是这个任务,就放在待运行的任务列表里面了。

1.2.4 初步理解 sys.run()

sys.run() 是一个无限循环的函数。

main.lua 的最后一行, 只能是 sys.run(),代表 sys.run() 接管了 LuatOS 的所有的执行调度工作。

sys.run() 是 LuatOS 的运行中枢。

在本文的 3.3 节和 7.3 节,还会继续介绍 sys.run()这个函数。

1.3 LuatOS 脚本编程的核心要点

1.3.1 LuatOS 实现的典型功能

LuatOS 脚本是利用了 Lua 的语法,以及基于 LuatOS 的核心库和扩展库提供的 API,进行简便的编程,实现如下功能:

1,实现和云端服务器通信;

2,采集外设的数据,控制外设设备;

3,实现人机交互,包括图形交互和语音交互;

1.3.2 LuatOS 的学习要点

要想写好 LuatOS 的软件,实现上述三个功能,除了逐渐掌握 Lua 的基本语法之外,还需要熟悉 LuatOS 的核心库和扩展库,这样才能开发出优质的基于 LuatOS 的物联网设备软件。

学习的方法有如下几个:

1, 运行各个功能模块的 demo 代码;

2, 阅读 docs.openluat.com 的教程文档;

3, 遇到不懂问 AI;

1.3.3 一个典型的 LuatOS 实现

一个典型的 LuatOS 实现,包含 main.lua 入口文件和若干个功能模块文件。

这里用 Air780EPM 模组的蜂鸣器的代码为例, 有两个脚本文件以及一个管脚描述 json 文件:

1, main.lua 文件, 作用是启动一个任务,让蜂鸣器响一秒钟,再停顿一秒钟,如此往复;

2, airbuzzer.lua 封装了驱动蜂鸣器的功能实现;

3, pins_Air780EPM.json 描述了本例使用到的管脚的功能,780EPM 的 26 管脚,用作 PWM4。

main.lua 内容如下:

airbuzzer.lua 内容如下:

pins_air780EPM.json 内容如下:

把上述几个文件,连同 airr780EPM 最新的固件版本,用 Luatools 建立一个工程,烧录到 780EPM 开发板,就可以听到蜂鸣器的播放声音了。

二、几个要熟悉的常识

2.1 匿名函数

在 Lua 代码里面,经常看到没有名字的函数。

这种函数定义之后, 要么马上运行,要么作为另一个函数的返回值赋给其他变量,所以并不需要一个函数名字。

这种函数,称为匿名函数。

匿名函数可以某些时候简化代码,初学者写代码可以先不考虑匿名函数。

但是由于匿名函数在你能阅读到的 Lua 代码里面出现的频次实在是太高了,所以你也不得不重视和习惯匿名函数。

2.2 闭包

闭包的实现通常是通过在外部函数内部定义一个函数,并将这个内部函数作为外部函数的返回值。

这样一来,内部函数就可以访问外部函数作用域中的变量,即使外部函数已经执行完毕,这些变量依然可以被内部函数访问,从而形成闭包。

常见的闭包实现模式如下:

这样的好处是,可以定义一个函数,能够在一定范围内,访问外部的变量,实现可控的持续行为。

很多初学者会被这段代码迷惑,会被绕晕。

这里做一下解释:

(1)z 不是函数里面声明的变量,z 是函数的参数;

所以 在代码里面, 因为 f=outer(10), 所以, f(5)就意味着是调用了 两次函数,传入了两个函数的参数: outer(10)(5)。

第一次调用,out(10) ,意味着 在 outer 函数里面, y = x 这句, x 换成 10, 就是 y = 10;

outer(10)(5)意味着 5 是内部匿名函数的参数,就是替代 z 的;

匿名函数返回 y+z, 这里 y 是 10,z 是 5, 返回的就是 10+5=15.

这里比较绕的,就是给了两次参数,一个是 10 对应 x, 一个是 5 对应 z。

匿名参数和闭包,对初学者有点绕,很多读者不明白为什么 z 为什么是 outer 的第二个参数,

这里需要特别搞清楚的是, outer 这个函数的返回值是个函数, 而且这个函数是有参数的。

那么,这个带参数的函数赋值给 f 之后, f 就是个函数了, 于是给 f 一个参数 5, 这个 5 自然就是返回的函数的参数了,也就是 z 了。

虽然并不是所有的闭包都是上面这种代码的实现形式,但是初学者可以先记住这样的闭包形式。

如果不习惯闭包,初学者可以先避免在代码里面体现闭包的代码形式。

2.3 回调函数

2.3.1 回调函数是什么

回调函数是在 LuatOS 编程过程中经常用到的一个技术。

理解 LuatOS 的回调函数,可以从“事件驱动”和“函数作为参数”两个角度来把握:

回调函数(Callback)是在特定事件发生时,由系统或框架自动调用你事先定义好的函数。你只需要把自己的函数注册给系统,等事件触发时,系统就会帮你调用它。

本质上,回调函数就是一个普通函数,但它被作为参数传递或注册到其他地方,由系统或其他代码在合适的时机自动执行。


回调函数的作用是实现事件响应,异步处理。

消息到来,定时器到点,网络收发等功能都经常会用到回调函数的处理。

总之,LuatOS 的回调函数,就是你注册给系统的,在特定事件发生时自动被调用的函数。

回调函数让事件响应、异步处理、任务解耦变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值