Lua在单片机上的移植与使用

32单片机移植LUA

前言:仅介绍Lua的使用,而不介绍内部运行原理,旨在快速上手移植并使用Lua。

移植

以Lua5.3.5为例,移植到Keil-MDK工程:
使用芯片:GD32F4(STM32同理)
操作系统:FreeRtos

Lua源码下载地址:https://download.csdn.net/download/SXD_SJJ/88273800
解压后文件夹下有文件:
在这里插入图片描述
我们打开src文件夹,这是我们需要的文件
在这里插入图片描述
将lua-5.3.5整个文件夹复制到我们的工程里,然后打开我们的keil工程,将lua-5.3.5/src文件夹下的c文件全部添加到我们的工程里:
在这里插入图片描述

使用

配置

我们明确几个关键的Lua的配置:
在luaconf.h:
在这里插入图片描述
此处配置Lua的最大堆栈大小,用来限制Lua可使用的堆栈大小
lua.h:
在这里插入图片描述
当然这些数值的单位并不是字节Byte,而是Lua堆栈的槽位数量,怎么理解槽位呢。我们可以认为是一个队列或者C++里的list,每一个槽位可以存放一个值,这个值可以是一个整形数字,可以是一个字符串甚至是一个列表。具体的内部的原理我们可以再深究,这里不再细说,通常情况下我们无需去配置这些参数,保持默认即可。

而我们需要的配置就是我们分配的堆空间,即在*.s的启动文件内分配的堆的大小,但是堆要分配多大的内存呢?

这个我们可以通过查看map文件来获取堆的起始地址,然后顺着堆的增长方向debug调试来确认堆到底使用了多少,当然,这些都是你已经运行了你的Lua的脚本文件的前提下,否则是看不到堆被使用的,而且因为脚本文件内的脚本是会被改动的,即堆的使用情况也是会变化的,所以我们需要预留足够的堆来保证Lua脚本的正确运行。

如果有小伙伴不明白MDK怎么查看堆的使用情况,可以参考博文:待补充

代码编写

那么前文提到Lua脚本,那这个脚本是什么呢?
我们可以在Windows下编写一个写了shutdown的test.bat脚本,那么运行这个test.bat,电脑就会关机,那么Windows是怎么认为这个shutdown就是关机呢,那肯定是Windows提供给了我们一个指令表或者函数表,告诉我们,这个shutdown对于Windows来说就是关机。

这个概念很重要,因为我们要在代码里去注册一个这种表,来提供给用户,让用户在编写脚本时去使用我们提供的表来写脚本,当然,对于Lua来说,我们提供的全是函数表。

那么现在开始,我们来编写底层的Lua注册代码

static int do_file_script(void)
{
    L = luaL_newstate();
    luaL_openlibs(L);
    lua_register(L, "led_green", lua_green);
    lua_register(L, "led_green_toggle", lua_led_green_toggle);
    lua_sethook(L, &function_hook, LUA_MASKCALL, 0);
    uint8_t* lp  = lua_get_file();
    int      res = luaL_dostring(L, ( const char* )lp);
    if (res) {
        int type = lua_type(L, -1);
        if (LUA_TSTRING == type) {
            const char* str = lua_tostring(L, -1);
            printf("%s", str);
        }
    }
    lua_close(L);
    return 0;
}

同样的我们用一个点灯实例来演示,luaL_newstate函数来为我们新建虚拟机(我们的脚本需要在这个虚拟机内运行),当然,他和文件系统的打开和关闭同理,新建一个虚拟机,在不用时或使用完毕后需要关闭这个虚拟机防止一致占用内存,我们可以使用lua_close函数关闭。
luaL_openlibs:我们需要为这个虚拟机去提供一些Lua的库。
lua_register:这个函数就很有意思了,这个就是我们注册的表,从上述代码来看,我们在这个表内注册了两个函数,一个是lua_green,一个是lua_led_green_toggle,这两个函数是我们底层实现的函数,而led_green和led_green_toggle就是我们提供给Lua脚本的函数表的项,脚本内调用led_green,底层就会执行lua_green函数。
lua_sethook:这个我们可以不必太多关心,这个大多是是调试调用,有兴趣的可以查查他的使用和原理
lua_get_file:这个是我自己定义的,他返回的是Lua脚本的存储地址,Lua脚本是在PC上编写的,但是下载到单片机内我们需要在单片机内找个地方(一段flash)把他存起来,那也就有了脚本地址。
luaL_dostring:这里就开始运行Lua脚本了

那么我们再来看看脚本怎么写,有意思的事Lua本身提供了一些关键词给我们使用,比如:
function:声明并定义函数
local:声明并定义变量
当然还有if else while 等等的关键词,有兴趣也可以问问度娘。

我们写一个简单的脚本,让灯闪起来:

local time=500
function led_green_flash()  led_green_toggle(time) end
function main()
    led_green_flash()
    while true do
    end
end
main()

我们在脚本内定义了一个变量time和函数led_green_flash,并在led_green_flash函数内调用了led_green_toggle,
那么我们把脚本下载进去脚本运行起来后,就会调用我们底层的lua_led_green_toggle函数。

那么会有刚接触的同学会问我该怎么下载Lua脚本文件到单片机内呢?
有很多通用的文件下载协议,例如YMODEM协议,也可以自己制定一些文件下载的协议,根本上来说文件本身也可以读取分解成一个大数组,而我们就是将这个大数组发送到单片机,这样理解后自己制定下载协议就很简单了。
当然我们也是自己定义的协议,编写了一个QT的上位机来下载Lua脚本,如果不想这样做的话网上有很多YMODEM的文件下载软件也可以的

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值