lua在stm32上的移植

来源:互联网 发布:宣传片制作 知乎 编辑:程序博客网 时间:2024/06/08 05:26

1.下载lua源码从官网,本文使用的是lua5.3.2,将加载到自己的工程中(不用添加lua.c和luac.c),修改luaconf.h,在其中增加宏定义#define LUA_32BITS;

2.增加文件stm32_lua_config.c,其内容如下,主要是重定义lua中文件操作的底层函数(即fopen、fread、fclose等函数要调用的函数):

#include "includes.h"#include "LCD_Get_Res.h"#include "ff.h"#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];typedef int FILEHANDLE;void _sys_exit(int status){while(1);}FILEHANDLE _sys_open(const char *name, int openmode){uint32_t mode = 0;int ret;if(openmode == 0){mode |= FA_READ;}if(openmode & 0x01){mode |= FA_WRITE;}if(openmode & 0x10){mode |= FA_READ | FA_WRITE;}if(openmode & 0x0100){mode |= FA_CREATE_NEW;}ret = f_open(&sd_file, name,  mode);if(ret != FR_OK){return 0;}return 1;}int _sys_close(FILEHANDLE fh){f_close(&sd_file);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){int res,i = 0;//int cou_sd;//int size;//int read_len = len;//while(1)//{//(read_len > 512)? (size = 512) : (size = read_len);//res = f_read(&sd_file, &buf[i], size, &cou_sd);//if(res != FR_OK)//{//return EOF;//}//read_len -=cou_sd;//i += cou_sd;//if(read_len <= 0 || cou_sd == 0)//{//break;//}//}return i;}//若此处重定义了fgetc则fread不会调用_sys_readint fgetc(FILE *stream){char ch = 0;int res;int cou_sd;res = f_read(&sd_file, &ch, 1, &cou_sd);if(res != FR_OK || cou_sd == 0){return EOF;}return ch;}int _sys_seek(FILEHANDLE fh, long pos){int res;res = f_lseek(&sd_file, pos);if(res != FR_OK){return res;}return 0;}int _sys_istty(FILEHANDLE fh){return 0;}int _sys_ensure(FILEHANDLE fh){return 0;}long _sys_flen(FILEHANDLE fh){return 0;}int _sys_tmpnam(char *name, int fileno, unsigned maxlength){return 0;}void _ttywrch(int ch){}time_t time(time_t *t){return 0;}int remove(const char *filename){return 0;}char *_sys_command_string(char *cmd, int len){return 0;}clock_t clock(void){return 0;}int system(const char* a){return 0;}int rename(const char *a, const char *b){return 0;}


3.在2中已经重新定义了lua中的文件操作的底层函数,但是lua中有一些函数如luaL_dofile需要从文件目录中加载.lua程序,这时我们只需实现上面的_sys_open、_sys_close、fgetc等函数再修改luaconf.h即可,在2中我已经实现文件操作一些函数的接口,修改luaconf.h:

在luaconf.h 190行左右有如下代码:

#define LUA_ROOT "/usr/local/"#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"#define LUA_PATH_DEFAULT  \LUA_LDIR"?.lua;"  LUA_LDIR"?/init.lua;" \LUA_CDIR"?.lua;"  LUA_CDIR"?/init.lua;" \"./?.lua;" "./?/init.lua"#define LUA_CPATH_DEFAULT \LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"


上面及时lua寻找文件的一个默认路径,因我们不存在这些路径,把它修改为我们自己的sd卡路径或其他存储设备路径即可,这里我用的是sd卡,把上面注释,修改如下:

#define LUA_PATH_DEFAULT  "1:/LUALib/?.lua;"#define LUA_CPATH_DEFAULT "1:/LUALib/?.so;"


4.上面的工作做完就可以执行在sd卡中的lua程序了,举例如下:

c程序:

static int Delay_ms(lua_State *L){    delay_ms(luaL_checkinteger(L, -1));    return 0;}static int print(lua_State *L){    int n=lua_gettop(L);    int i;    for (i=1; i<=n; i++)    {        if (lua_isstring(L,i))            printf("%s",lua_tostring(L,i));        else if (lua_isnil(L,i))            printf("%s","nil");        else if (lua_isboolean(L,i))            printf("%s",lua_toboolean(L,i) ? "true" : "false");        else            printf("%s:%p",luaL_typename(L,i),lua_topointer(L,i));     }     return 0;}static luaL_Reg LuaLib1_0[] = {     //c接口函数都可以放在这里在lua中声明    {"Delay_ms", Delay_ms},    {"print", print},    {NULL, NULL} };void Lua_task(void){     lua_State* L;    L = luaL_newstate();    luaL_openlibs(L);    luaL_newlibtable(L, LuaLib1_0);    luaL_setfuncs(L, LuaLib1_0, 0);    //这里定义全局变量把栈顶的table赋值给LuaLib1_0,这个方式使用模块是因为无法将c模块生成动态链接库.so或.dll给LUA_CPATH_DEFAULT加载    lua_setglobal(L, "LuaLib1_0");    if (luaL_dofile(L, "1:/Lua.lua")!=0)//加载sd卡中的Lua.lua并运行          printf(lua_tostring(L,-1));}


Lua.lua中程序:

local LuaLib1_0 = require("LuaLib1_0")Windows = {    WINDOW1 = 0,    WINDOW2 = 1,}local i = 0function window2()    i = i + 1;    if i == 256 then        i = 0    end endfunction window1()    i = i + 1;    if i == 256 then        i = 0    endendfunction window_handle()    Window_Cur = WINDOW1     if Window_Cur == Windows.WINDOW1 then        window1()    elseif Window_Cur == Windows.WINDOW2 then        window2()    end endfunction Lua_main()    while true do        window_handle()        LuaLib1_0.Delay_ms(200)    endendLua_main()


这样就可以把c和lua分开,在lua中写自己的应用程序了,lua中想要什么数据由c提供。

以上内容均为自己理解,如有错误,欢迎指正

0 0
原创粉丝点击