本帖最后由 夜声 于 2023-1-2 10:05 编辑
Lua移植
一、前言
本篇文章将Lua在MDK环境移植到AT32F437ZMT7开发板,记录移植过程并通过Lua点亮开发板上的LED灯作为演示。
二、Lua简介
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组于 1993 年开发的,该小组成员有:Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo。
特点:
轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
三、AT32F437ZMT7简介
雅特力科技AT32F437系列超高效能微控制器,搭载32位ARM® Cortex®-M4内核,配合先进工艺与整合技术缔造业界Cortex®-M4最高主频效能288MHz的运算速度。内建的单精度浮点运算单元(FPU)、数字信号处理器(DSP)及存储器保护单元(MPU),搭配丰富的外设及灵活的时钟控制机制,能满足多种领域应用。最高可支持超大容量4032KB的闪存(Flash)和高达512KB的SRAM,超越业界同级芯片水平。
3.1芯片资源
定时器:
3个16位带死区控制PWM高级控制定时器
2个32位, 8个16位通用定时器
2个16位基本定时器
2个看门狗定时器(独立和窗口型)
1个系统时间定时器: 24位自减型
3.1通信接口
3 x I²C (支持SMBus/PMBus)
4 x SPI / I²S (SPI可达36MHz)(其中I²S2/I²S3支持全双工)
4 x USART + 4 x UART (支持ISO7816,LIN,IrDA接口和调制解调控制)
2 x SDIO
2 x OTG全速控制器, 设备模式时支持无晶振(Crystal-less)
2 x CAN 2.0B
红外发射器
10/100M以太网MAC:具有专用DMA和4 K字节SRAM,支持IEEE 1588硬件,MII/RMII接口
3.3开发板外观
四、移植准备
4.1 Lua源码下载
官网地址:http://www.lua.org/ftp/
4.2 KEIL工程准备
官网下载AT32F437的BSP,以其中的tamplates为例。
打开工程,是通过按键控制LED快闪和慢闪两种模式,进行简单调整,只需留着GPIO的即可。
调整过后如下所示,查看整个工程编译的大小,方便查看Lua移植后所需的内存大小。
五、移植过程
在KEIL工程中添加Lua源码
排除“lua.c”、“luac.c”这2个文件,两个是一个Lua Shell,和平台相关,单片机用不上。
添加头文件路径:
添加头文件
添加底层函数处理接口:
typedef int FILEHANDLE;
#pragma import(__use_no_semihosting_swi)
#pragma import(_main_redirection)
const char __stdin_name[150];
const char __stdout_name[150];
const char __stderr_name[150];
FILEHANDLE _sys_open(const char *name, int openmode)
{
return 0;
}
int _sys_close(FILEHANDLE fh)
{
return 0;
}
int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
{
return 0;
}
int _sys_read(FILEHANDLE fh, unsigned char*buf, unsigned len, int mode)
{
return 0;
}
//检查句柄是否为终端
int _sys_istty(FILEHANDLE fh)
{
return 0;
}
int _sys_seek(FILEHANDLE fh, long pos)
{
return 0;
}
//刷新句柄关联的缓冲区
int _sys_ensure(FILEHANDLE fh)
{
return 0;
}
//返回文件当前长度
long _sys_flen(FILEHANDLE fh)
{
return 0;
}
void _sys_exit(int status)
{
}
int _sys_tmpnam(char *name, int fileno, unsigned maxlength)
{
return 0;
}
//将一个字符写入控制台
void _ttywrch(int ch)
{
}
int remove(const char *filename)
{
return 0;
}
char *_sys_command_string(char *cmd, int len)
{
return NULL;
}
time_t time(time_t * time)
{
return 0;
}
添加led控制处理:
static int lua_led_on(lua_State *L)
{
gpio_bits_write(GPIOD,GPIO_PINS_14,TRUE);
return 1;
}
static int lua_led_off(lua_State *L)
{
gpio_bits_write(GPIOD,GPIO_PINS_14,FALSE);
return 1;
}
static int lua_delay(lua_State *L)
{
uint16_t ms;
ms = (uint16_t)lua_tointeger(L,1);
delay_ms(ms);
return 1;
}
static const struct luaL_Reg lib[]=
{
{"delay",lua_delay},
{"led_on",lua_led_on},
{"led_off",lua_led_off},
{NULL,NULL}
};
const char LUA_GLOBAL[]="\
off = 500 \
on = 500 \
while 1 do \
led_on() \
delay(off)\
led_off() \
delay(on) \
end";
static lua_State *luaL;
void lua_run(void)
{
luaL = luaL_newstate();
luaopen_base(luaL);
luaL_setfuncs(luaL,lib,0);
luaL_dostring(luaL,LUA_GLOBAL);
while(1);
}
主函数:
int main(void)
{
system_clock_config();
at32_board_init();
uart_print_init(115200);
lua_run();
}
修改启动文件:
编译了一下,报了110个错误和36个警告,慢慢的一个一个解决吧!!!
选择C99Mode模式,编译错误解决
再次编译,还有错误,同时需要将工程串口打印例程,或者自己添加串口打印。
原因分析:
在luaconfig.h 中有 luai_writestring 和 luai_writeline 两个宏,这两个宏关系到了 lua 中 print 的输出,需要针对平台重定向,一般定向到调试串口就行。所以需要将GPIO工程替换串口打印工程。
我工程中使用了MicroLIB
同时在at32f435_437_board.c中已经定义,同时在进行添加底层接口时也进行了定义。
解决方法:
不使用MicroLIB,同时将at32f435_437_board.c所定义的部分屏蔽掉。
六、结果
Lua已经在板子上正常跑起来了
|
感谢分享,MARK一下,学习了
楼主能分享一下代码工程吗?让更多人贴友学习学习。