把Lua移植到stm32上,效果不错!

2020-01-04 18:48发布

因为我们产品的需要满足不同行业需求,所以一直在寻找一个脚本语言,以便灵活配置。

前段时间还自己花时间去实现一个C语言解释器,看了一堆编译原理的东西,以及虚拟机等,头都搞大了,把基本功能实现了,但总是不满意。


后来看到lua,网上一搜:


才知道 魔兽世界 的插件就是lua写的....
,愤怒的小鸟也是lua写的,lua在苹果和android都支持lua语言开发,lua已经成为移动平台开发的新贵...

lua是纯c写的最高效的脚本语言...

恍然大悟,原来lua就是我要找的东西啊!正所谓:梦里寻他千百度,蓦然回首,那人却在灯火阑珊处!于是立即产生了把lua移植到stm32的想法。




到网上查了半天stm32移植lua的资料,居然一篇都没有找到,失望啊。

难道我是第一个干这事的蠢人?没办法,只好硬着头皮上了!


lua果然名不虚传,代码极其简略,移植性极高,由标准ansi c写成。移植过程非常顺利,在IAR下编译后只有几十K字节。

编译了一个bin下载到stm32后,立马就顺利运行起来。



为了测试lua的内存的需求,我把ram设置到48k字节,结果运行很顺利。看来lua对内存的需求确实很小。

在STM32处于24M的频率下,测试了一下lua脚本的运行效率,大致为每秒2万次浮点计算。 (在我的电脑上测试lua是每秒1千万次运算)。

如果stm32设置到72M的话,大致应该是每秒6万次浮点运算。

花了几分钟时间,通过lua c api实现了几个api函数让lua调用,感觉lua和c的交互调用确实极其方便。

int main(){
    .....
     Sys_TimerInit();
     SerialPort_Init();
     IWDG_Configuration();
     WWDG_Configuration();
     __set_PRIMASK(0);
     
     Sys_TimerRequest(OTimerID7,50,1);


    // 这是main里面的调用lua
     
     L   = lua_open();      
     luaopen_base(L);   
     //注_册自己的c函数到lua中
     lua_register(L, "average", average);     
     lua_register(L, "Lsleep", Lsleep);
     lua_register(L, "Lmyputs0", Lmyputs0);     
     
     InitTasks();
     AddTask(facetask,1);
     AddTask(uart0task,1);     
     
     float a,c2;
     char buf[100];

    //这里是lua脚本, 脚本里面又调用了自己定义得c函数, Lmyputs0---串口输出函数   average --平均值函数,  Lsleep--延时函数

    strcpy(buf," Lmyputs0("start!",6); c2=2; a1 = {"one","two","three"}    a=average(10, 20, 30, 40, 50); count=0;  while 1>0 do     count=count+1;  Lmyputs0(a1[(count%3)+1],6);  Lsleep(300); end; Lmyputs0("end!",4)");
   
    //让lua运行脚本!
     luaL_dostring(L, buf);
      ...
}   





//下面是几定义的函数

static int average(lua_State *L)
{
/* 得到参数个数 */
int n = lua_gettop(L);
double sum = 0;
int i;
/* 循环求参数之和 */
for (i = 1; i <= n; i++)
{
/* 求和 */
sum += lua_tonumber(L, i);
}
/* 压入平均值 */
lua_pushnumber(L, sum / n);
/* 压入和 */
lua_pushnumber(L, sum);
/* 返回返回值的个数 */
return 2;
}

static int Lsleep(lua_State *L){
  int d;
  PT_Timer_t tmr0;
  
  d=lua_tonumber(L, 1);  
  PT_TimerSet(&tmr0,d);
  while(PT_TimerExpired(&tmr0)==false){
    WDT_FLAG = 0;
    RunTaskList();
  }
  lua_pushnumber(L, 1);
  return 1;
}
  
static int Lmyputs0(lua_State *L)
{
   char *buf;
   int len;

   buf=(char *)lua_tostring(L,1);
   len=lua_tonumber(L, 2);
   myputs0(buf,len);
   
   lua_pushnumber(L, 1);
   return 1;
}



//---------------附lua的说明------------------------
Lua 是一个小巧的脚本语言。作者是巴西人。该语言的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

Lua脚本可以很容易的被C/C++代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,Ini等文件格式,并且更容易理解和维护。

Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。

一个完整的Lua解释器不过200k,在目前所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。
-----------------------------------------------------------------------------

lua语言已经成为排名第十名的语言,(javascript在十一名)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
100条回答
smset
2020-01-07 21:54
在stm32上移植Lua不用做任何裁剪。

下载Lua源码,(我用的是5.1.4,很新的版本),把c文件添加到工程(lua.c,luac.c两个文件不用加),然后编译即可通过,无需修改一个字符。(选择lib为full),

接下来,就可以开始享受stm32上的Lua之旅!


Lua全编译也只有48k字节左右,所以不裁剪都是可以的。本身的Ram需求则在26K字节左右,Stm32应该是可以承受的。


在main 里面,或者其他函数里面:

     L   = lua_open();      
     luaopen_base(L);   

     //buf里面就是lua脚本了 ,自己写好;
     luaL_dostring(L, buf);

就可以了。就这么简单!


Lua可以和c无缝集成,c结合Lua后,则是如虎添翼。不要仅仅是把Lua当做是一门新的语言,这个世界优秀的语言已经很多了,不差Lua一个,虽然Lua语言也极其优秀。

Lua是一种新的开发方式,它带来的改变甚至是革_命性的!它可以让整个应用的逻辑以Lua脚本和原生语言的方式进行混合实现,而且比例任意切分。它可以让产品中相对不变的硬件代码和变化不定的用户业务逻辑充分结合起来。它可以让产品随时更新功能而无需重新编译!它甚至可以让用户和你一起来分工实现一个应用代码,同时又很好的保护了你的核心技术。

Java高调提倡的一次编写,到处运行的思想,在单片机里是行不通的,
而Lua则悄无声息的实现了,而且是那么易如反掌!而且是这么彻底,不受限于一次编写,还可以随时改写。

所以Lua才真正是做到了一次编写,到处运行,并可随意再次改写,所以她横跨了PC,服务器,苹果,安卓,PSP,以及单片机!  她横跨了windows,linux,ios,ucos,以及裸奔的单片机代码!

感谢Lua的开创者,感谢他们为这个世界创造了如此美妙的Lua !

一周热门 更多>