完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
stm32应用:lua在Keil上的移植和使用
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。本文主要说明一下关于lua移植到STM32上的过程以及简单的举两个例子来说明lua的应用。 Lua的简介 关于Lua的官方介绍,此处不在说明。有需要了解的看官可以在百度或者lua教程了解。关于其应用有: 游戏开发 独立应用脚本 Web 应用脚本 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统 但这些对此文章来时并不是重点,而重点在于将Lua移植到单片机上到底有什么用处。经过这些天的移植和测试,个人理解是这样:将通过某个方式将一段字符串输送给STM32。该段字符串就是一段lua脚本程序,而单片机就会根据这段脚本程序实现脚本的功能。你可以将这段脚本做成文件,用文件系统进行读取,或者通过串口输入,又后者用flash存储。那么它在单片机里具体有什么用呢,在我学习的过程中,在一些讨论群中很多网友都说这是个鸡肋,压根没什么用途。而本人则觉得如果对于一些懂得lua脚本编程的开发者来说未必会单片机开发能力,如果设备拥有脚本编程能力,对这类有设备需要的开发者来说还是挺好的。下面简单举个例子说明一下lua在单片机中如果灵活的使用。 假设当前有个主机设备,设备提供有串口3个(编号A,B,C),网口1个(net),继电器控制口8个(Q1-Q8)。485通信口2个(M1,M2) 现在有四个设备接在M1口上,分别为设备(A1-A4);这四个设备都可以通过命令进行查寻,而查询的结果可以让主机设备根据脚本进行不同的动作,比如,可以让查询A1设备的结果发送到网络,也可以查询A1的结果发送到串口,这样作为设备开发商对于这种不定性的要求是无法掌握的。如果主机能够支持脚本语言,虽然接口有限,但是却可以根据用户要求进行不同的转换或者处理。只要客户自行编写自己得脚本既可以。或者有厂家帮客户提供脚本服务。而不需要去编写底层代码,这类应有在一些PLC中控器是比较常见的。 这是目前个人对Lua的一点理解。如果说的不好也请见谅。这个并非本文的重点。接下来开始文章点重点,移植和使用。 Lua的移植 准备:开发板一块,lua程序包(当前版本为Lua-5.3.5版本) 说明:由于当前版本Lua的内存开销如下 l RAM 》= 7.5Kb,建议16KB以上 l ROM 》= 65kb,建议128kb以上 因此RAM和ROM少于最低要求的芯片是无法移植的 先创建一个简单的工程项目,保存项目可以正常运行。 Lua的程序文件都在包中的scr文件夹下面,因此将整个文件夹复制到项目文件夹中,并添加到工程项目里,然后在include paths中添加Lua的路径。注意添加时有两个文件不需要添加,lua.c 和 luac.c (分别为PC的解释器和编译器,这个跟java类型,如果有java基础的应该会有一定的理解)。既然是面对PC机的,所以我们不需要,如果加到项目里,因为其各自有个mian函数就会有错误。 由于lua底层还是有一些标准库函数,因此还需要为其添加一些标准库函数,具体有下面三个: 本机时间函数: time_t time(time_t * time){ return 0; } 进程退出函数,用于退出进程(单片机系统本是功能单一的应用,一般都不会用到,Lua程序要求因此添加一个空函数) void exit(int status){} 此处添加后会有警告,这是因为在stilib.h文件定义中,该函数是有返回值的,个人使用直接在头文件中修改了定义。 extern _ARMABI_NORETURN void exit(int /*status*/); 修改为 extern void exit(int status); 将命令名称或程序名称传给要被命令处理器执行环境,同样设置为空 int system(const char * string){ return 0; } 然后全编译后,成功如下图 个人还是喜欢无错误无警告的程序,(^ __ ^) 关于Lua的应用举例 主要用两个例子来说明Lua的应用 1、利用Lua脚本语言做个2的11次方运行,并通过串口打印出来。 2、添加自定义的接口函数实现LED灯的闪烁。其闪烁频率可以自己通过延时来设置。 第二个例子还是比较贴合实际应用,主要是了解如何将自定义点函数添加到Lua脚本解释器中,还有关于带有参数的接口程序如何实现。 串口打印运算结果:(此处不多少,直接上关键代码) /* * 库函数发送调用功能函数 * 形式参数: * 返 回 值: */ int fputc(int ch, FILE *f) { USART_SendData(USART1 , (uint8_t)ch); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_ClearITPendingBit(USART1,USART_FLAG_TC); return (ch); } /* * lua串口输出运算的脚本程序 */ const char lua_test[] = { “print(”Hello,I am lua!\n--this is newline printf“)n” “function foo()n” “ local i = 0n” “ local sum = 1n” “ while i 《= 10 don” “ sum = sum * 2n” “ i = i + 1n” “ endn” “return sumn” “endn” “print(”sum =“, foo())n” “print(”and sum = 2^11 =“, 2 ^ 11)n” }; /* * 编译器测试 */ static int do_file_script(void){ lua_State *L; L = luaL_newstate(); // 创建Lua编译器 luaopen_base(L); // 注册基本函数 luaL_dostring(L, lua_test); // 执行脚本语句 return 0; } /* * 主函数 */ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); usart1_initialization(); do_file_script(); while(1){ } } 其中lua代码中的print就是输出功能函数。 例子二,利用串口传入脚本,然后执行脚本语句,思路比较简单,就是通过串口接收一串数据然后直接送到脚本解释器解析就行。几个关键点函数如下: /* * 利用死循环在做得延时函数,为了方面 */ static int delay_ms(lua_State *L){ int num; int count = lua_tointeger(L,1); // 读取脚本中送入的参数,1表示第一个参数 for(int i = 0 ; i 《 count ; i++){ num = 20000; while(num--); } return 1; } /* * Led控制函数 */ static int Lua_LED(lua_State *L){ bool flag = lua_toboolean(L,1); // 读取传入函数的参数 if(flag)GPIO_ResetBits(GPIOF, GPIO_Pin_6); // LED灯亮 else GPIO_SetBits(GPIOF, GPIO_Pin_6); // LED灯灭 return 1; } /* * 自定义函数注册结构体数组 */ static const struct luaL_Reg mylib[] ={ {“delay_ms”,delay_ms}, {“Lua_LED”,Lua_LED}, {NULL,NULL} }; lua_State *L; // 解析器指针 static int do_file_script(void){ L = luaL_newstate(); // 创建解析器 luaopen_base(L); // 注册基础函数 luaL_setfuncs(L, mylib, 0); // 注册自定义函数 return 0; } /* * 主函数 */ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); usart1_initialization(); // 串口初始 led_initialization(); // LED的初始化 printf(“rnrn”); do_file_script(); while(1){ if(Usart1_Receive(150000)){ // 读取串口数据 luaL_dostring(L, (char*)usartBuf); // 读取到的数据直接送到解析器解析 memset(usartBuf,0,1024); // 清楚缓冲 } } } // 下面为串口输的数据 /* count = 10 while (count 》 0) do Lua_LED(false) delay_ms(50) Lua_LED(true) delay_ms(50) count = count - 1 end */ |
|
|
|
stm32应用:lua在Keil上的移植和使用
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。本文主要说明一下关于lua移植到STM32上的过程以及简单的举两个例子来说明lua的应用。 Lua的简介 关于Lua的官方介绍,此处不在说明。有需要了解的看官可以在百度或者lua教程了解。关于其应用有: 游戏开发 独立应用脚本 Web 应用脚本 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统 但这些对此文章来时并不是重点,而重点在于将Lua移植到单片机上到底有什么用处。经过这些天的移植和测试,个人理解是这样:将通过某个方式将一段字符串输送给STM32。该段字符串就是一段lua脚本程序,而单片机就会根据这段脚本程序实现脚本的功能。你可以将这段脚本做成文件,用文件系统进行读取,或者通过串口输入,又后者用flash存储。那么它在单片机里具体有什么用呢,在我学习的过程中,在一些讨论群中很多网友都说这是个鸡肋,压根没什么用途。而本人则觉得如果对于一些懂得lua脚本编程的开发者来说未必会单片机开发能力,如果设备拥有脚本编程能力,对这类有设备需要的开发者来说还是挺好的。下面简单举个例子说明一下lua在单片机中如果灵活的使用。 假设当前有个主机设备,设备提供有串口3个(编号A,B,C),网口1个(net),继电器控制口8个(Q1-Q8)。485通信口2个(M1,M2) 现在有四个设备接在M1口上,分别为设备(A1-A4);这四个设备都可以通过命令进行查寻,而查询的结果可以让主机设备根据脚本进行不同的动作,比如,可以让查询A1设备的结果发送到网络,也可以查询A1的结果发送到串口,这样作为设备开发商对于这种不定性的要求是无法掌握的。如果主机能够支持脚本语言,虽然接口有限,但是却可以根据用户要求进行不同的转换或者处理。只要客户自行编写自己得脚本既可以。或者有厂家帮客户提供脚本服务。而不需要去编写底层代码,这类应有在一些PLC中控器是比较常见的。 这是目前个人对Lua的一点理解。如果说的不好也请见谅。这个并非本文的重点。接下来开始文章点重点,移植和使用。 Lua的移植 准备:开发板一块,lua程序包(当前版本为Lua-5.3.5版本) 说明:由于当前版本Lua的内存开销如下 l RAM 》= 7.5Kb,建议16KB以上 l ROM 》= 65kb,建议128kb以上 因此RAM和ROM少于最低要求的芯片是无法移植的 先创建一个简单的工程项目,保存项目可以正常运行。 Lua的程序文件都在包中的scr文件夹下面,因此将整个文件夹复制到项目文件夹中,并添加到工程项目里,然后在include paths中添加Lua的路径。注意添加时有两个文件不需要添加,lua.c 和 luac.c (分别为PC的解释器和编译器,这个跟java类型,如果有java基础的应该会有一定的理解)。既然是面对PC机的,所以我们不需要,如果加到项目里,因为其各自有个mian函数就会有错误。 由于lua底层还是有一些标准库函数,因此还需要为其添加一些标准库函数,具体有下面三个: 本机时间函数: time_t time(time_t * time){ return 0; } 进程退出函数,用于退出进程(单片机系统本是功能单一的应用,一般都不会用到,Lua程序要求因此添加一个空函数) void exit(int status){} 此处添加后会有警告,这是因为在stilib.h文件定义中,该函数是有返回值的,个人使用直接在头文件中修改了定义。 extern _ARMABI_NORETURN void exit(int /*status*/); 修改为 extern void exit(int status); 将命令名称或程序名称传给要被命令处理器执行环境,同样设置为空 int system(const char * string){ return 0; } 然后全编译后,成功如下图 个人还是喜欢无错误无警告的程序,(^ __ ^) 关于Lua的应用举例 主要用两个例子来说明Lua的应用 1、利用Lua脚本语言做个2的11次方运行,并通过串口打印出来。 2、添加自定义的接口函数实现LED灯的闪烁。其闪烁频率可以自己通过延时来设置。 第二个例子还是比较贴合实际应用,主要是了解如何将自定义点函数添加到Lua脚本解释器中,还有关于带有参数的接口程序如何实现。 串口打印运算结果:(此处不多少,直接上关键代码) /* * 库函数发送调用功能函数 * 形式参数: * 返 回 值: */ int fputc(int ch, FILE *f) { USART_SendData(USART1 , (uint8_t)ch); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_ClearITPendingBit(USART1,USART_FLAG_TC); return (ch); } /* * lua串口输出运算的脚本程序 */ const char lua_test[] = { “print(”Hello,I am lua!\n--this is newline printf“)n” “function foo()n” “ local i = 0n” “ local sum = 1n” “ while i 《= 10 don” “ sum = sum * 2n” “ i = i + 1n” “ endn” “return sumn” “endn” “print(”sum =“, foo())n” “print(”and sum = 2^11 =“, 2 ^ 11)n” }; /* * 编译器测试 */ static int do_file_script(void){ lua_State *L; L = luaL_newstate(); // 创建Lua编译器 luaopen_base(L); // 注册基本函数 luaL_dostring(L, lua_test); // 执行脚本语句 return 0; } /* * 主函数 */ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); usart1_initialization(); do_file_script(); while(1){ } } 其中lua代码中的print就是输出功能函数。 例子二,利用串口传入脚本,然后执行脚本语句,思路比较简单,就是通过串口接收一串数据然后直接送到脚本解释器解析就行。几个关键点函数如下: /* * 利用死循环在做得延时函数,为了方面 */ static int delay_ms(lua_State *L){ int num; int count = lua_tointeger(L,1); // 读取脚本中送入的参数,1表示第一个参数 for(int i = 0 ; i 《 count ; i++){ num = 20000; while(num--); } return 1; } /* * Led控制函数 */ static int Lua_LED(lua_State *L){ bool flag = lua_toboolean(L,1); // 读取传入函数的参数 if(flag)GPIO_ResetBits(GPIOF, GPIO_Pin_6); // LED灯亮 else GPIO_SetBits(GPIOF, GPIO_Pin_6); // LED灯灭 return 1; } /* * 自定义函数注册结构体数组 */ static const struct luaL_Reg mylib[] ={ {“delay_ms”,delay_ms}, {“Lua_LED”,Lua_LED}, {NULL,NULL} }; lua_State *L; // 解析器指针 static int do_file_script(void){ L = luaL_newstate(); // 创建解析器 luaopen_base(L); // 注册基础函数 luaL_setfuncs(L, mylib, 0); // 注册自定义函数 return 0; } /* * 主函数 */ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); usart1_initialization(); // 串口初始 led_initialization(); // LED的初始化 printf(“rnrn”); do_file_script(); while(1){ if(Usart1_Receive(150000)){ // 读取串口数据 luaL_dostring(L, (char*)usartBuf); // 读取到的数据直接送到解析器解析 memset(usartBuf,0,1024); // 清楚缓冲 } } } // 下面为串口输的数据 /* count = 10 while (count 》 0) do Lua_LED(false) delay_ms(50) Lua_LED(true) delay_ms(50) count = count - 1 end */ |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1916 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1680 浏览 1 评论
1172 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
771 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1732 浏览 2 评论
1974浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
808浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
257浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
625浏览 3评论
634浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-25 04:28 , Processed in 0.592326 second(s), Total 44, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号