单片机中移植lua解释器

这篇具有很好参考价值的文章主要介绍了单片机中移植lua解释器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、基本开发环境

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

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

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

https://www.lua.org/

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

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

lua开发单片机,lua,单片机,开发语言,嵌入式硬件

二、移植Lua解释器

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

2.新建stm32工程

3.工程添加Lua源码

将Lua源文件拷贝到工程

lua开发单片机,lua,单片机,开发语言,嵌入式硬件

添加头文件

lua开发单片机,lua,单片机,开发语言,嵌入式硬件

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

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

    lua开发单片机,lua,单片机,开发语言,嵌入式硬件

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

lua开发单片机,lua,单片机,开发语言,嵌入式硬件

更改以上内容是因为使用了 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);
  else
    status = (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 1

static 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 0
    lua_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文章来源地址https://www.toymoban.com/news/detail-697076.html

到了这里,关于单片机中移植lua解释器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 单片机开发---ESP32S3移植NES模拟器(一)

    《单片机开发—ESP32-S3模块上手》 《单片机开发—ESP32S3移植lvgl+触摸屏》 依旧是参考韦东山老师的作品来移植的 《ESP32|爷青回!ESP32(单片机) NES模拟器_NES游戏机掌机教程(开源+详细讲解实现代码!)》 韦老师已经将代码开源,喜欢的朋友当然是可以去支持一波。 另外还有gi

    2023年04月16日
    浏览(45)
  • 『pycharm 』解决无法添加解释器,无法新建项目问题(是无法添加解释器,不是没有添加解释器)

    这个问题和大家常见的: 没有Python解释器 这种简单问题不同。请看问题描述。👇👇 如图,解释器列表空空如也,即使点击“ 添加本地解释器 ”也没有反应(那个展开小三角也是空的)。 所有项目都这样了,那里变成空的了。而且这些都是我自己的项目,之前都好好的。 删

    2024年02月11日
    浏览(75)
  • Pycharm 重命名SSH的conda解释器后,提示该解释器不可用

    目前已知是BUG,截至投稿日未修复 已经提交给youtrack.jetbrains.com,如下图:

    2024年01月17日
    浏览(77)
  • 解锁Spring Boot中的设计模式—02.解释器模式:探索【解释器模式】的奥秘与应用实践!

    解释器模式(Interpreter Pattern)是一种行为设计模式,它用于定义语言的文法,并且解释语言中的表达式。在Java中,解释器模式可以用于构建解释器以解析特定的语言或表达式,如数学表达式、查询语言等。 优点: 灵活性: 解释器模式可以 灵活地添加新的表达式和规则 ,因

    2024年02月19日
    浏览(72)
  • 解释器模式(Interpreter)

    解释器模式是一种行为设计模式,可以解释语言的语法或表达式。给定一个语言,定义它的文法的一种表示,然后定义一个解释器,使用该文法来解释语言中的句子。解释器模式提供了评估语言的语法或表达式的方式。 解释器模式包含如下角色: Context,上下文,包含解释器

    2024年02月14日
    浏览(45)
  • 解释器设计模式

    解释器设计模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法,并建立一个解释器来解释该语言中的句子。这种模式通常用于需要解释或执行一种特定类型的语言的场景,例如编程语言的编译器或解释器、规则引擎系统等。 关键组成部分 抽象表达式(

    2024年02月21日
    浏览(58)
  • 解释器模式简介

    解释器模式( Interpreter Pattern )是一种行为型设计模式,它用于定义语言的文法,并解析和执行给定语言中的表达式。该模式将每个表达式表示为一个类,并提供了一种方式来组合这些表达式以实现复杂的语句。 定义了一种简单、可扩展的语法规则,使得可以灵活地处理不同

    2024年02月07日
    浏览(46)
  • 什么是解释器模式

    程序员必知!解释器模式的实战应用与案例分析 - 知乎 上边这篇文章写的比较好,有定义,有例子,还划了重点,引用一下重点: 解释器模式在日常Java开发过程中使用的非常多,它最大的优点在于灵活性:能动态地解释和执行代码,这在处理复杂逻辑或多变需求时特别有用

    2024年01月19日
    浏览(55)
  • 设计模式——解释器模式

    更多内容,前往IT-BLOG 在软件开发中,会遇到有些问题多次重复出现,而且有一定的相似性和规律性。如果将它们归纳成一种简单的表达式(例如:正则表达式等),那么这些问题实例将是该表达式的一些句子,这样就可以用 “编译原理” 中的解释器模式来实现。 【1】解释

    2024年02月03日
    浏览(72)
  • 行为型模式-解释器模式

    提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。 意图: 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的

    2024年02月07日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包