单片机中移植lua解释器

news2024/11/25 8:22:07

一、基本开发环境

开发环境基于野火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);
  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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/652001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AIGC数据库工具-阿里开源Chat2DB

前言 今天无意间发现了一个AIGC数据库工具,chat2DB,重点!!!阿里开源,其设计产品的思想给了我很多灵感,故记录一下,并分享给大家。 概述: Chat2DB 是一款有开源免费的多…

驱动开发:内核RIP劫持实现DLL注入

本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用CreateRemoteThread直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过劫持EIP的方式实现,其实现原理可总结为&am…

【C++】入门基础知识详解(二)

目录 一、内联函数 1、概念 2、特性 3、内联函数与宏的优缺点 二、auto关键字(C11) 1、auto 简介 2、auto的使用细则 2.1 auto与指针和引用结合起来使用 2.2 在同一行定义多个变量 3、auto不能推导的场景 3.1 auto 不能作为函数的参数 3.2 auto 不能直接用来声明数组 三、…

英语中如何描述五颜六色

前言 如何用英语描述五颜六色,看完这篇文章,你就学会了 🏠个人主页:我是沐风晓月 🧑个人简介:大家好,我是沐风晓月,阿里云社区博客专家 😉😉 💕 …

Axure RP 9 基础教程 元件基础2

第一章:Axure RP 9的元件(2) 6、改变元件的位置 要改变元件的位置,只需要拖动对应的元件即可。另外也可以在顶部快捷样式菜单中设置坐标值,然后按回车键,让元件移动到指定位置。 X轴是横轴,改变可以调整左右的位置。 Y…

技术科普与解读:ChatGPT 大模型硬核解读!(一)家族历史从GPT-1到ChatGPT

多模态,指的是融合文本、图像、视频或音频等多种模态作为输入或输出。 GPT-4是严格意义上的多模态模型,可以支持图像和文字两类信息的同时输入,输出为文本。从学术界的分析来看,无论是知识/能力获取还是与现实物理世界的交互&…

【应用安全架构】什么是联合身份管理?

介绍 联合身份管理是一种可以在两个或多个信任域之间进行的安排,以允许这些域的用户使用相同的数字身份访问应用程序和服务。这称为联合身份,使用这种解决方案模式称为身份联合。 联合身份管理建立在两个或多个域之间的信任基础之上。例如,信…

如此有艺术感的AI生成式二维码,你肯定没有见过

这是一张很常见的图片,要说有特殊的话可能是由 AI 来生成的,其它并无特别之处。但给它加上三个定位点后,这张图就变成一个可以扫描识别的二维码: 真的假的?不信你长按图片识别一下!我一次看到时&#xff0c…

基于Hexo和Butterfly创建个人技术博客,(8) 博客网站butterfly主题UI框架美化

Butterfly官方网站,请 点击进入 说明: 此文中的设置并不影响网站的整体,只是一些视觉上的调整,可以按需调整。 本章目标: 掌握butterfly主题的配置,优化UI样式 一、特效 1、过场动画 在每个页面打开前会有…

干货!具有三维感知的换脸算法

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 作者介绍 李逸轩 上海交通大学2022级硕士研究生,研究兴趣主要是三维人脸生成 报告题目 具有三维感知的换脸算法 内容简介 AI换脸旨在将一张给定目标图片中的人脸五官替换成源图片中的另一个人&#…

操作系统中的进程调度与优先级算法:理论与实践探索

前言 在计算机科学领域中,进程调度是操作系统中一个重要的组成部分,它负责决定哪个进程能够获得 CPU 的执行权,以及如何合理地分配 CPU 时间。通过合理的进程调度算法,可以提高系统的性能和响应能力。在本篇博客中,我…

ubuntu开发环境

boost介绍 Boost是一个广受欢迎的、开源的C程序库集合,提供了许多高质量和可重用的组件,涵盖了广泛的领域,如容器、算法、函数对象、日期与时间、正则表达式、文件系统、线程等。Boost旨在通过提供开发人员友好的C工具和组件来增强C的功能。…

阿里云主机详解:ECS/轻量/虚拟主机/GPU/裸金属/云电脑详解

阿里云云主机分为云虚拟主机、云服务器ECS、轻量应用服务器、GPU云服务器、弹性裸金属服务器、专有宿主机、FPGA云服务器、高性能计算E-HPC、无影云电脑等,阿里云百科来详细说下阿里云云主机详解: 目录 阿里云云主机 云服务器ECS 轻量应用服务器 云…

博泰应宜伦:把Vision Pro放大二十倍,就是未来汽车的终极形态

作者 | Amy 编辑 | 德新 新能源是上半场,智能化是下半场。 而随着智能汽车发展,智能座舱也不断革新,过去智能座舱的各项功能全面开花,竞争愈演愈烈,未来的座舱将如何被定义? 6月15日,博泰车联…

微信小程序手机号授权登录

文章目录 小程序端服务端注意事项 微信小程序,手机号授权登录需求。 大体流程是这样的: 小程序端使用 getPhoneNumber 向微信平台获取授权通过微信授权后,小程序端接收微信授权后的回调小程序携带微信的回调请求自己的服务端服务端请求微信获…

QML 模型和视图

模型/视图架构简介 使用 QML 时,有些情况下需要使用模型视图结构显示一些列表等控件,比较好的方式是用 Python 接管数据模型部分,方便处理数据;QML 和 JavaScript 负责前端部分,实现前端和后端的分离。 MVD 简介 Mo…

C# 特性(一)——什么是特性

目录 什么是特性 Serializable DllImport Obsolete Conditional Attribute类 自定义特性 AttributeUsage的使用例子 特性非常常见,官方解释为: 特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法…

【批处理DOS-CMD命令-汇总和小结】上网和通信相关命令-查看路由表,查看网卡GUID UUID(route、getmac)

一、查看、编辑路由表(route) 首先我们看看route命令的帮助信息,可以发现这个命令其实就是用来查看路由表、以及添加(或编辑、删除)路由项目的。 路由项目是指操作系统对数据包的导向规则,往往包括目标IP…

《统计学习方法》——条件随机场#习题解答#

引言 这是统计学习方法第十一章条件随机场的阅读笔记,包含所有公式的详细推导。 条件随机场(conditional random field,CRF)是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫随机场。 建议先阅…

【计算机网络】为什么是TCP四次挥手,可以变成三次吗?

【计算机网络】为什么是TCP四次挥手,可以变成三次吗? 文章目录 【计算机网络】为什么是TCP四次挥手,可以变成三次吗?引言TCP 四次挥手为什么 TCP 挥手需要四次呢?粗暴关闭 vs 优雅关闭 什么情况会出现三次挥手&#xf…