最近在一個在做一個PLC項(xiàng)目,對于PLC需要根據(jù)不同場景實(shí)現(xiàn)不同的功能钥飞,因此為了保持系統(tǒng)的穩(wěn)定性決定做一個腳本配置的方案百框。開始的時候自己寫了一個腳本解析程序琳要,系統(tǒng)運(yùn)行不錯料扰,就是腳本有點(diǎn)長,易讀性比較差焙蹭,今天突然想到Lua,決定把Lua移植到STM32上去晒杈,網(wǎng)上查了一下相關(guān)資料,說實(shí)話孔厉,關(guān)于STM32Lua的工程應(yīng)用還是比較少的拯钻,決定自己移植一下
前期準(zhǔn)備
Lua源碼包:
目前最新版本是5.3.4 帖努,下載鏈接:http://www.lua.org/ftp/lua-5.3.4.tar.gz
Stm32f103工程模板:
我已經(jīng)做好的工程模板,主要有一個LED驅(qū)動粪般,串口驅(qū)動
下載鏈接?密碼:o2x5
開始移植
我用的KEIL 5.17拼余,板子用的STM32f103板子
1.Lua源碼解壓會得到一個src文件夾,把src下的源碼添加到STM32的工程里亩歹,設(shè)置好包含路徑匙监,注意lua.c 和 luac.c 這兩個文件是不包含的(它們包含PC上Lua解釋器和編譯器的main函數(shù)),將這兩個文件刪除。
2.Lua硬件要求
l RAM >= 7.5Kb小作,建議16KB以上
l ROM >= 65kb亭姥,建議128kb以上
改動堆棧大小:堆最小為5.5kb顾稀,棧最小是1.5kb达罗。在啟動文件里把堆(Heap_Size)設(shè)置的足夠大,我設(shè)置的0x00008000(32KB)是沒問題的静秆,其實(shí)要不了這么多粮揉。建議把棧設(shè)置的大一點(diǎn)(1KB足夠)
把MicroLib的勾打上了,如下圖:
然后我寫了一個簡單的函數(shù)來實(shí)現(xiàn)解釋器:
/* 測試的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"
};
/* 運(yùn)行Lua */
static int do_file_script(void)
{
? ? lua_State *L;
? ? L = luaL_newstate(); /* 建立Lua運(yùn)行環(huán)境 */
? ? luaL_openlibs(L);
? ? luaopen_base(L);
? ? luaL_dostring(L, lua_test); /* 運(yùn)行Lua腳本 */
? ? lua_close(L);
? ? return 0;
}
#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"
/**********************************************************
* 函數(shù)名 : 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()這三個標(biāo)準(zhǔn)庫函數(shù)沒有定義抚笔,我們需要自己定義
/* 定義MicroLib沒有的函數(shù) */
time_t time(time_t * time)
{
? ? return 0;
}
void exit(int status)
{? ?
}
int system(const char * string)
{
? ? return 0;
}
好扶认,現(xiàn)在終于可以運(yùn)行了,
運(yùn)行結(jié)果: