首先很感谢能找到这么一门优秀的脚本语言。
我很早就知道做这个项目需要一门编程语言作为系统的灵魂,汇编语言速度快,但是不容易开发大型的程序;python流行但是恕我直言不适合单片机的编程,找来找去找到了Lua语言,这个语言的好处在于他使用标准的C语言编写的,移植起来很简单,特别容易嵌入到STM32的工程中,甚至可以在高端F1系列中也可以使用,我第一次是在STM32F103ZET6上移植的,现在刚刚移植到F4上,由于技术上年久失修导致很多地方都忘了,终于还是弄完了,在这了写一写移植的过程。
首先下载最新版本的Lua源代码http://www.lua.org/ftp/
修改启动文件的堆栈大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Stack_Size EQU 0x1000; AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp ; <h> Heap Configuration ; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> ; </h> Heap_Size EQU 0x2C00; AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base Heap_Mem SPACE Heap_Size |
然后,解压出来文件,把str文件中的所有文件复制到工程中并在keil中设置好文件夹的路径,然后吧lua.c和luac.c删除掉。
接下来改一改两个文件的内容,首先是lstate.h
1 2 3 4 |
#if !defined(luai_makeseed) #include <time.h> #define luai_makeseed() cast(unsigned int, 1) #endif |
然后是itablib.c
1 2 3 4 5 6 7 8 9 10 11 |
static unsigned int l_randomizePivot (void) { clock_t c = clock(); time_t t = 1;//time(NULL); //jama unsigned int buff[sof(c) + sof(t)]; unsigned int i, rnd = 0; memcpy(buff, &c, sof(c) * sizeof(unsigned int)); memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); for (i = 0; i < sof(buff); i++) rnd += buff[i]; return rnd; } |
然后写系统函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
#include "luasys.h" #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include "delay.h" #include "led.h" 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) { //while(1); } 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; } static int lua_led_on(lua_State *L) { //PCout(13) = 1; led_on(); return 1; } static int lua_led_off(lua_State *L) { //PCout(13) = 0; led_off(); return 1; } static int lua_delay(lua_State *L) { int num; num = lua_tointeger(L, 1); Delay(num); return 1; } static const struct luaL_Reg mylib[]= { {"led_on",lua_led_on}, {"led_off",lua_led_off}, {"delay",lua_delay}, {NULL,NULL} }; char cmd1[] =" \ off = 10000 \ on = 10000 \ while 1 do \ led_on() \ delay(off) \ led_off() \ delay(on) \ end"; char kk[]="\ led_off()"; void lua_process() { while(1) { lua_State *L; L = luaL_newstate(); /* ½¨Á¢LuaÔËÐл·¾³ */ luaopen_base(L); luaL_setfuncs(L, mylib, 0); luaL_dostring(L, cmd1); while (1); } } |
接下来直接写main函数
1 2 3 4 5 6 |
int main(void) { LED_Init(); lua_process(); } |
如果没有改上述的两处文件内容,程序会卡死到硬件故障中断里,千万别忘了这个。