
最近在一個在做一個PLC項目,對于PLC需要根據(jù)不同場景實現(xiàn)不同的功能,因此為了保持系統(tǒng)的穩(wěn)定性決定做一個腳本配置的方案。開始的時候自己寫了一個腳本解析程序,系統(tǒng)運行不錯,就是腳本有點長,易讀性比較差,今天突然想到Lua,決定把Lua移植到STM32上去,網(wǎng)上查了一下相關資料,說實話,關于STM32Lua的工程應用還是比較少的,決定自己移植一下
前期準備
Lua源碼包:
目前最新版本是5.3.4 ,下載鏈接:http://www.lua.org/ftp/lua-5.3.4.tar.gz
Stm32f103工程模板:
我已經(jīng)做好的工程模板,主要有一個LED驅動,串口驅動
下載鏈接?密碼:o2x5
開始移植
我用的KEIL 5.17,板子用的STM32f103板子
1.Lua源碼解壓會得到一個src文件夾,把src下的源碼添加到STM32的工程里,設置好包含路徑,注意lua.c 和 luac.c 這兩個文件是不包含的(它們包含PC上Lua解釋器和編譯器的main函數(shù)),將這兩個文件刪除。


2.Lua硬件要求
l RAM >= 7.5Kb,建議16KB以上
l ROM >= 65kb,建議128kb以上
改動堆棧大?。憾炎钚?.5kb,棧最小是1.5kb。在啟動文件里把堆(Heap_Size)設置的足夠大,我設置的0x00008000(32KB)是沒問題的,其實要不了這么多。建議把棧設置的大一點(1KB足夠)

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

然后我寫了一個簡單的函數(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"
};
/* 運行Lua */
static int do_file_script(void)
{
? ? lua_State *L;
? ? L = luaL_newstate(); /* 建立Lua運行環(huán)境 */
? ? luaL_openlibs(L);
? ? luaopen_base(L);
? ? luaL_dostring(L, lua_test); /* 運行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()這三個標準庫函數(shù)沒有定義,我們需要自己定義
/* 定義MicroLib沒有的函數(shù) */
time_t time(time_t * time)
{
? ? return 0;
}
void exit(int status)
{? ?
}
int system(const char * string)
{
? ? return 0;
}
好,現(xiàn)在終于可以運行了,
運行結果: