单片机中移植lua解释器

news/2024/11/30 8:00:33/

一、基本开发环境

开发环境基于野火STM32开发板。

前测试的 Lua 解释器版本为 5.4.2。

官网下载lua资源包,下载地址如下:

https://www.lua.org/

https://github.com/rjpcomputing/luaforwindows/releases

lua: Lua 国内镜像 (gitee.com)‍

1f415694b1643573c448af9b9678487b.png

二、移植Lua解释器

1.下载的Lua解压,删除源文件中的的 lua.c 和 luac.c (如果有的话)文件。

2.新建stm32工程

3.工程添加Lua源码

将Lua源文件拷贝到工程

807418b271bfaa51cd05b3e55848e1f4.png

添加头文件

451aa165037e7d3753914b9ca707e803.png

更改 loslib.c 文件下部分内容 

  1. 将 os_exit(lua_State * L)函数中 if(L) exit(status)注释,并添加 status=status 语句。

    4c3f1d8a72ce433e091c02d0082137f6.png

2.添加 time(time_t *time)和 system(const char * string)

e96f41cbc9d3d57cd16a5a1f8dbafe34.png

更改以上内容是因为使用了 Use MicroLIB 模式。

static int os_exit (lua_State *L) {int status;if (lua_isboolean(L, 1))status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);elsestatus = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);if (lua_toboolean(L, 2))lua_close(L);//if (L) exit(status);  /* 'if' to avoid warnings for unreachable 'return' */status=status;return 0;
}time_t time(time_t *time)
{return 0;
}int system(const char * string)
{return 0;
}

三、Lua使用测试

  1. 编写测试代码

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"static int lua_led_on(lua_State *L)
{LED1( ON );       return 1;
}
static const struct luaL_Reg mylib[]=
{{"led_on",lua_led_on},{NULL,NULL}
};const char LUA_SCRIPT_GLOBAL_ON[] =" \while 1 do\led_on() \end";int main(void)
{SystemClock_Config();LED_GPIO_Config();LED1( ON );       // 亮HAL_Delay(1000);LED1( OFF );      // 灭HAL_Delay(1000);lua_State *L;L = luaL_newstate(); //建立Lua运行环境luaopen_base(L);//注册基础函数(此函数要屏蔽luaL_setfuncs(L, base_funcs, 0);)luaL_setfuncs(L, mylib, 0);//注册自定义函数luaL_dostring(L, LUA_SCRIPT_GLOBAL_ON);while(1){    }    
}
/********************************************************************************* @file    main.c* @author  fire* @version V1.0* @date    2017-xx-xx* @brief   GPIOÊä³ö--ʹÓù̼þ¿âµãÁÁLEDµÆ******************************************************************************* @attention** ʵÑéƽ̨:Ò°»ð  STM32 F407 ¿ª·¢°å * ÂÛ̳    :http://www.firebbs.cn* ÌÔ±¦    :http://firestm32.taobao.com********************************************************************************//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx.h"
#include "./led/bsp_led.h"#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"static void SystemClock_Config(void);#if 1static int lua_led_delay_ms(lua_State *L)
{
//    int i=0xFFFFF;
//	while(i--)
//    {
//        ;;
//    }
//    //HAL_Delay(1000);HAL_Delay(1000);return 1;
}
static int lua_led_on(lua_State *L)
{LED1( ON );			 // ÁÁ lua_led_delay_ms(L);LED1( OFF );lua_led_delay_ms(L);//HAL_GPIO_TogglePin(GPIOG,GPIO_PIN_7);return 1;
}
static int lua_led_off(lua_State *L)
{LED1( OFF );		  // Ãðreturn 1;
}static const struct luaL_Reg mylib[]=
{{"led_on",lua_led_on},{NULL,NULL}
};const char LUA_SCRIPT_GLOBAL_ON[] =" \while 1 do\led_on() \end";
const char LUA_SCRIPT_GLOBAL_OFF[] =" \led_off() \end";const char LUA_SCRIPT_GLOBAL_TEST[] =" \while 1 do\led_on() \led_delay()\led_off() \led_delay()\end";void BEEP_GPIO_Config(void)
{		/*¶¨ÒåÒ»¸öGPIO_InitTypeDefÀàÐ͵ĽṹÌå*/GPIO_InitTypeDef  GPIO_InitStruct;/*¿ªÆôBEEPÏà¹ØµÄGPIOÍâÉèʱÖÓ*/__GPIOG_CLK_ENABLE();/*Ñ¡ÔñÒª¿ØÖƵÄGPIOÒý½Å*/															   GPIO_InitStruct.Pin = GPIO_PIN_7;	/*ÉèÖÃÒý½ÅµÄÊä³öÀàÐÍΪÍÆÍìÊä³ö*/GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;  /*ÉèÖÃÒý½ÅΪÉÏÀ­Ä£Ê½*/GPIO_InitStruct.Pull  = GPIO_PULLUP;/*ÉèÖÃÒý½ÅËÙÂÊΪ¸ßËÙ */   GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; /*µ÷Óÿ⺯Êý£¬Ê¹ÓÃÉÏÃæÅäÖõÄGPIO_InitStructure³õʼ»¯GPIO*/HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);	HAL_GPIO_WritePin(GPIOG,GPIO_PIN_7,0);
}/*** @brief  Ö÷º¯Êý* @param  ÎÞ* @retval ÎÞ*/
int main(void)
{/* ϵͳʱÖÓ³õʼ»¯³É168MHz */SystemClock_Config();/* LED ¶Ë¿Ú³õʼ»¯ */LED_GPIO_Config();//BEEP_GPIO_Config();LED1( ON );			 // ÁÁ HAL_Delay(1000);LED1( OFF );		  // ÃðHAL_Delay(1000); #if 0lua_State *L;L = luaL_newstate(); //luaopen_base(L);lua_register(L, "led_on", lua_led_on);     lua_register(L, "led_off", lua_led_off);lua_register(L, "led_delay", lua_led_delay_ms);    while(1){luaL_dostring(L, LUA_SCRIPT_GLOBAL_TEST);}  #else    /* ¿ØÖÆLEDµÆ */while(1){lua_State *L;L = luaL_newstate(); //luaopen_base(L);luaL_setfuncs(L, mylib, 0);luaL_dostring(L, LUA_SCRIPT_GLOBAL_ON);while(1);}   
#endif    
}#else 
static int lua_led_on(lua_State *L)
{LED1( ON );return 1;
}
static int lua_led_off(lua_State *L)
{LED1( OFF );return 1;
}static int lua_delay(lua_State *L)
{int num;
//	num= lua_tointeger(L, 1);HAL_Delay(500);return 1;
}static const struct luaL_Reg mylib[]=
{{"led_on",lua_led_on},{"led_off",lua_led_off},{"delay",lua_delay},{NULL,NULL}
};const char LUA_SCRIPT_GLOBAL[] ="  \off = 500     \on = 500       \while 1 do \led_on() \delay(on)    \led_off()        \delay(off)      \end";/*** @brief  Ö÷º¯Êý* @param  ÎÞ* @retval ÎÞ*/
int main(void)
{/* ϵͳʱÖÓ³õʼ»¯³É168MHz */SystemClock_Config();/* LED ¶Ë¿Ú³õʼ»¯ */LED_GPIO_Config();LED1( ON );			 // ÁÁ HAL_Delay(1000);LED1( OFF );		  // ÃðHAL_Delay(1000); /* ¿ØÖÆLEDµÆ */while(1){lua_State *L;L = luaL_newstate(); //luaopen_base(L);luaL_setfuncs(L, mylib, 0);luaL_dostring(L, LUA_SCRIPT_GLOBAL);while(1);}    
}
#endif
/*** @brief  System Clock Configuration*         The system Clock is configured as follow : *            System Clock source            = PLL (HSE)*            SYSCLK(Hz)                     = 168000000*            HCLK(Hz)                       = 168000000*            AHB Prescaler                  = 1*            APB1 Prescaler                 = 4*            APB2 Prescaler                 = 2*            HSE Frequency(Hz)              = 8000000*            PLL_M                          = 25*            PLL_N                          = 336*            PLL_P                          = 2*            PLL_Q                          = 7*            VDD(V)                         = 3.3*            Main regulator output voltage  = Scale1 mode*            Flash Latency(WS)              = 5* @param  None* @retval None*/
static void SystemClock_Config(void)
{RCC_ClkInitTypeDef RCC_ClkInitStruct;RCC_OscInitTypeDef RCC_OscInitStruct;/* Enable Power Control clock */__HAL_RCC_PWR_CLK_ENABLE();/* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet.  */__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/* Enable HSE Oscillator and activate PLL with HSE as source */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 25;RCC_OscInitStruct.PLL.PLLN = 336;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 7;if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){while(1) {};}/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){while(1) {};}/* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported  */if (HAL_GetREVID() == 0x1001){/* Enable the Flash prefetch */__HAL_FLASH_PREFETCH_BUFFER_ENABLE();}
}/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2.下载,查看测试效果

实验现象,指示灯先亮后灭再常亮,符合预期。

欢迎关注个人公众号:嵌入式学习与实践

参考:

https://www.gd32mcu.com/data/documents/userManual/AN019_CN_Rev1.0.pdf

https://blog.csdn.net/weixin_38728721/article/details/104068015

https://blog.csdn.net/weixin_41558887/article/details/101385077

https://www.armbbs.cn/forum.php?mod=viewthread&tid=94757


http://www.ppmy.cn/news/414600.html

相关文章

对象存储服务MinIO简介

黑马程序员学习资料 MinIO简介 MinIO基于Apache License v2.0开源协议的对象存储服务,可以做为云存储的解决方案用来保存海量的图片,视频,文档。由于采用Golang实现,服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置简单&…

Python 中的结构模式匹配

文章目录 结构模式匹配简介及其重要性在 Python 中使用结构模式匹配match ... case 语句的基本使用使用 match ... case 来检测和解构数据结构使用 match ... case 与捕获模式和序列模式使用 match ... case 和通配符模式在类模式中使用 match ... case使用 match ... case 和 …

AIGC 加持 Cocos,游戏开发需要几步?

近日,游戏行业知名的 B2B 大会 WN 2023 大会于土耳其首都伊斯坦布尔顺利举办。本次大会邀请了来自全球的游戏开发商、媒体、发行商、分发平台等行业决策者,共同探讨游戏行业未来发展态势,进一步拓展业务,并在世界范围内寻找新的合…

智驾传感器新风向!拐点将至

“大家都比较关注激光雷达,尤其是在今年整个行业聚焦降本的大背景下,这个赛道还行不行?”6月8日,2023年度(第十四届)高工智能汽车开发者大会上,高工智能汽车研究院首发《2023-2025年中国汽车市场…

华为认证 | HCIA-SDN 考试大纲

01 考试概述 02 考试范围 HCIA-SDN V1.0考试覆盖数据通信基础知识,SDN架构,SDN二、三层网络原理,SDN接口协议原理比如OpenFlow协议、Netconf协议、RestFul协议原理,以及在华为交换机与路由器中的实现。 SDN二三层技术&#xff1…

Ubuntu显示设置

作者 QQ群:852283276 微信:arm80x86 微信公众号:青儿创客基地 B站:主页 https://space.bilibili.com/208826118 参考 linux系统配置x11,配置Xorg X11窗口系统 恢复ubuntu20.04默认桌面管理器 Ubuntu18.04多显卡配置显示输出&…

安装Ubuntu 18.04卡死问题记录

新机安装 ubuntu 出现卡死问题,本篇做下记录 由于本机没有核显,独显又是 nvidia GT710,起初猜测跟显卡有关,网上也有许多相关问题的解决实例,具体步骤如下: BIOS关闭安全启动模式进入grub,按键…

计算机屏幕出现GT,传奇亮机卡GT710又诈尸?这次居然可同时带16个显示器

[PConline 杂谈]近日,华硕在其官网上架了型号为GT710-4H-SL-2GD5的新显卡,售价预计在400人民币以内,要知道GT710自首发伊始定位就是一张“亮机卡”,公版的性能甚至不如主流核显,在该GPU首发4年后厂商居然还为其推出新品…