0%

STM32FXX之Lua解释器移植

将Lua解释器移植到STM32

最近在一个在做一个PLC项目,对于PLC需要根据不同场景实现不同的功能,因此为了保持系统的稳定性决定做一个脚本配置的方案。开始的时候自己写了一个脚本解析程序,系统运行不错,就是脚本有点长,易读性比较差,今天突然想到Lua,决定把Lua移植到STM32上去,网上查了一下相关资料,说实话,关于STM32Lua的工程应用还是比较少的,决定自己移植一下

前期准备
Lua源码包:
目前最新版本是5.3.4 ,下载链接:http://www.lua.org/ftp/lua-5.3.4.tar.gz
Stm32f103工程模板:
我已经做好的工程模板,主要有一个LED驱动,串口驱动
下载连接:

开始移植
我用的KEIL 5.17,板子用的STM32f103板子

1.Lua源码解压会得到一个src文件夹,把src下的源码添加到STM32的工程里,设置好包含路径,注意lua.c 和 luac.c 这两个文件是不包含的(它们包含PC上Lua解释器和编译器的main函数),将这两个文件删除。

fig3.png

fig4.png

2.Lua硬件要求
l RAM >= 7.5Kb,建议16KB以上
l ROM >= 65kb,建议128kb以上
改动堆栈大小:堆最小为5.5kb,栈最小是1.5kb。在启动文件里把堆(Heap_Size)设置的足够大,我设置的0x00008000(32KB)是没问题的,其实要不了这么多。建议把栈设置的大一点(1KB足够)

fig1.png

把MicroLib的勾打上了,如下图:

fig2.png

然后我写了一个简单的函数来实现解释器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 测试的Lua代码字符串 */
const char lua_test[] = {
"print(\"Hello,I am lua!\\n--this is newline printf\")\n"
"function foo()\n"
" local i = 0\n"
" local sum = 1\n"
" while i <= 10 do\n"
" sum = sum * 2\n"
" i = i + 1\n"
" end\n"
"return sum\n"
"end\n"
"print(\"sum =\", foo())\n"
"print(\"and sum = 2^11 =\", 2 ^ 11)\n"
"print(\"exp(200) =\", math.exp(200))\n"
};
1
2
3
4
5
6
7
8
9
10
11
12
/* 运行Lua */
static int do_file_script(void)
{
lua_State *L;

L = luaL_newstate(); /* 建立Lua运行环境 */
luaL_openlibs(L);
luaopen_base(L);
luaL_dostring(L, lua_test); /* 运行Lua脚本 */
lua_close(L);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "stm32_config.h"
#include "stdio.h"
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "stdlib.h"
#include "bsp_led.h"
#include "time.h"
#include "usart.h"
/**********************************************************
* 函数名 : main
* 输入 :none
* 输出 :none
* 功能 :
**********************************************************/
int main(void)
{
delay_init(72);
LED_Init();
USARTx_Init(115200);

do_file_script();

while(1)
{
// GPIO_SetBits(GPIOE,GPIO_Pin_5);
// delay_ms(200);
// GPIO_ResetBits(GPIOE,GPIO_Pin_5);
// delay_ms(200);
}
}

编译之后报错说time(), exit(), system()这三个标准库函数没有定义,我们需要自己定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 定义MicroLib没有的函数 */
time_t time(time_t * time)
{
return 0;
}

void exit(int status)
{
}

int system(const char * string)
{
return 0;
}

好,现在终于可以运行了,