单片机移植Lua(STM32H743移植Lua-5.4.6)

文章目录

  • 目的
  • 移植演示
  • 示例链接
  • 更多说明
    • 合理设置内存大小
    • 按需加载标准库
    • 实现系统和IO接口
    • 设置引用路径
  • 总结

目的

通常单片机都是使用C/C++来开发的,任何修改都需要重新编译固件然后下载运行。在一些需要灵活性更强的场合中可以内嵌Lua解释器实现动态更新应用程序的功能。这篇文章将对相关内容做个简单说明。

移植演示

Lua本身就是纯C实现的,不管是移植到上位机程序还是单片机程序中本质上没有多大区别,单就移植以及Lua脚本和C代码交互等参考我之前的文章即可:
《Lua和C语言交互入门》https://blog.csdn.net/Naisu_kun/article/details/134000058

这里进行简单演示,使用NUCLEO-H743ZI2开发板,启用默认使能的串口,用来打印输出信息:
在这里插入图片描述

修改最小堆栈大小,生成初始化项目代码。

然后参考上面文章,直接引入Lua源码(排除 lua.cluac.c),接着改写 main.c 代码如下:

#include "main.h"

#include <stdio.h> // 引入该库为了可以使用 printf 函数

#include "src/lua.h"     // Lua数据类型与函数接口
#include "src/lauxlib.h" // Lua与C交互辅助函数接口
#include "src/lualib.h"  // Lua标准库打开接口

UART_HandleTypeDef huart3;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);

/* 以下代码用来实现putchar操作,以此可实现printf功能 */
/* With GCC, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) // 实现__io_putchar函数
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

PUTCHAR_PROTOTYPE
{
	// 实际发送操作,这里可以改成自己真实需要操作的端口
    HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}
/* 以上代码用来实现putchar操作,以此可实现printf功能 */

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART3_UART_Init();

  lua_State* L = luaL_newstate(); // 创建Lua线程
  luaL_openlibs(L); // 打开标准库

  while (1)
  {
	 HAL_Delay(1000);
	luaL_dostring(L, "print('Naisu, Lua!')"); // 解析并执行Lua脚本字符串
  }

  lua_close(L); // 关闭Lua线程(虽然代码并不会运行到这里)
}

void SystemClock_Config(void)
{
  // some code ...
}

static void MX_USART3_UART_Init(void)
{
  // some code ...
}

static void MX_GPIO_Init(void)
{
  // some code ...
}

void Error_Handler(void)
{
  // some code ...
}

上面代码主要就两方面内容:

  • 实现了 putchar 操作,这样在 Lua 中就可以使用 print 函数了;
  • 创建Lua虚拟机初始化标准库,然后循环执行Lua脚本;

将上述代码编译后下载到开发板可以看到相关输出:
在这里插入图片描述

示例链接

仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples

本文中的示例位于仓库中 Lua_H743

更多说明

从上面演示可以看到,移植本身很简单,不过相比在上位机上移植,在单片机中移植还有些需要注意的地方。

合理设置内存大小

单片机相比上位机一个比较大的问题是内存比较小,所以需要合理设计内存使用。

单片机本身设置合适的堆栈空间:
在这里插入图片描述

Lua源码 luaconf.h 文件中 #define LUAI_MAXSTACK 宏定义用于设置Lua使用的最大栈大小:

/*
@@ LUAI_MAXSTACK limits the size of the Lua stack.
** CHANGE it if you need a different limit. This limit is arbitrary;
** its only purpose is to stop Lua from consuming unlimited stack
** space (and to reserve some numbers for pseudo-indices).
** (It must fit into max(size_t)/32 and max(int)/2.)
*/
#if LUAI_IS32INT
#define LUAI_MAXSTACK		1000000
#else
#define LUAI_MAXSTACK		15000
#endif

按需加载标准库

上面演示中使用 luaL_openlibs(L); 方式加载了所有的Lua标准库,实际使用中完全可以按需加载。

在Lua源码 linit.c 中注释掉不需要的库即可:

/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
  {LUA_GNAME, luaopen_base},
  {LUA_LOADLIBNAME, luaopen_package},
  {LUA_COLIBNAME, luaopen_coroutine},
  {LUA_TABLIBNAME, luaopen_table},
  {LUA_IOLIBNAME, luaopen_io},
  {LUA_OSLIBNAME, luaopen_os},
  {LUA_STRLIBNAME, luaopen_string},
  {LUA_MATHLIBNAME, luaopen_math},
  {LUA_UTF8LIBNAME, luaopen_utf8},
  {LUA_DBLIBNAME, luaopen_debug},
  {NULL, NULL}
};

实现系统和IO接口

Lua中很多操作都是调用了操作系统相关的接口,这些接口单片机是不带的,如果需要用到相关功能的话要不就去实现相关接口(比如演示中的print函数就需要实现相关接口才可以使用),要不就直接改写Lua标准库相关函数。

设置引用路径

如果单片机上跑了文件系统,将Lua脚本以文件的形式放到文件系统中,那么在执行这些文件的时候可能需要合理设置Lua相关路径。比如在Lua源码 luaconf.h 文件中 LUA_PATH_DEFAULT 宏定义就可以设置默认的路径。

总结

总体来说在单片机上移植Lua并不复杂,更多的是对内存的限制以及没有操作系统自带的各种接口问题上话时间去调试处理。

这些年单片机性能越来越强,约来越多的脚本语言和高级语言可以运行在单片机上,玩法真的是越来越多了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux:docker搭建redis集群(3主3从扩容缩容 哈希槽分配)

操作系统&#xff1a;centos7 docker-ce版本&#xff1a;24.0.7 1.准备redis镜像 我这里使用redis 6.0.8 镜像进行操作&#xff0c;如果你也需要镜像&#xff0c;在网络正常情况下直接使用 docker pull redis:6.0.8 即可进行下载&#xff0c;如果你没配置国内加速器&#x…

Doris ——SQL原理解析

目录 前言 一、Doris简介 二、SQL解析简介 2.1 词法分析 2.2 语法分析 2.3 逻辑计划 2.4 物理计划 三、Doris SQL解析的总体架构 四、Parse阶段 五、Analyze阶段 六、SinglePlan阶段&#xff08;生成单机逻辑Plan阶段&#xff09; 七、DistributedPlan计划&#xf…

蓝桥杯备赛_python_BFS搜索算法_刷题学习笔记

1 bfs广度优先搜索 1.1 是什么 1.2怎么实现 2案例学习 2.1.走迷宫 2.2.P1443 马的遍历 2.3. 九宫重排&#xff08;看答案学的&#xff0c;实在写不来&#xff09; 2.4.青蛙跳杯子&#xff08;学完九宫重排再做bingo&#xff09; 2.5. 长草 3.总结 1 bfs广度优先搜索 【P…

数据记笔记:USGS 查看上世纪卫星图

1 先到USGS EarthExplorer 界面&#xff0c;在address 处选择需要的城市/也可以在底下polygon处手动标出需要研究的区域 2&#xff0c;点击show&#xff0c;就会出找到的对应的区域&#xff0c;点击这个区域&#xff0c;polygon处就会有响应了。然后选择date range 3 点击下方的…

P1439 背包九讲(1):简单的0-1背包

P1439 背包九讲1&#xff1a;简单的0-1背包 一、原题呈现1、题目描述2、输入描述3、输出描述4、样例输入5、样例输出 二、思路分析这是一个最基础的01背包问题。 三、整体代码 一、原题呈现 1、题目描述 有一个箱子容量为 V&#xff08;正整数&#xff0c;0&#xff1c;&…

Java SE:集合

1. 单列集合顶层接口Collection 集合&#xff1a;将一个个数据结构写好封装成类&#xff0c;方便开发者调用 单列集合底下有两大接口&#xff1a;List和Set List底下有3个集合类&#xff1a;ArrayList&#xff08;数组&#xff09;、LinkedList&#xff08;链表&#xff09;…

【NI-DAQm入门】构建应用程序案例1

1.系统框图 2.应用框图 3. 代码结构 3.1 技巧1 使用模拟采样时钟作为编码器的时钟源•(而不是使用隐式) 同步模拟输入和编码 3.2 技巧2 为模拟输入和计数器输入采集样本 写入相同采样点至文件 对齐数据文件 3.3 技巧3 数字读写技巧

FLUENT Meshing Watertight Geometry工作流入门 - 7 共享拓扑

本视频中学到的内容&#xff1a; “共享拓扑”任务的工作细节如何使用“更新边界”和“更新区域”任务来更新边界和区域的属性 视频链接&#xff1a; FLUENT Meshing入门教程-7应用共享拓扑_哔哩哔哩_bilibili 【Import Geometry】 启动Ansys Fluent进入网格模式。在工作流类…

Swing程序设计(10)列表框,文本框,文本域,密码框

文章目录 前言一、列表框二、文本框&#xff08;域&#xff09; 1.文本框2.文本域三、密码框总结 前言 该篇文章简单介绍了Java中Swing组件里的列表框、文本框、密码框。 一、列表框 列表框&#xff08;JList&#xff09;相比下拉框&#xff0c;自身只是在窗体上占据固定的大小…

第三百四十九回

文章目录 1. 概念介绍2. 原理与方法2.1 知识对比2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"加密包crypto"相关的内容&#xff0c;本章回中将介绍characters包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 在项目中会遇到获取字…

Paper - CombFold: predicting structures of large protein assemblies 论文简读

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/136143199 CombFold: predicting structures of large protein assemblies using a combinatorial assembly algorithm and AlphaFold2 CombFold…

从物联网到数字孪生:智慧社区的演变

随着科技的飞速发展和数字化转型的深入推进&#xff0c;智慧社区已成为提升城市治理水平和居民生活质量的重要方向。在这一演变过程中&#xff0c;物联网和数字孪生技术起到了至关重要的作用。本文将深入探讨从物联网到数字孪生的演变过程&#xff0c;分析这一转变对智慧社区建…

EasyRecovery软件免费版与付费版有哪些功能区别?

免费版的EasyRecovery软件在功能和恢复能力上确实存在一些限制。 首先&#xff0c;在数据恢复方面&#xff0c;免费版通常只能恢复最多1GB的数据。这意味着&#xff0c;如果你需要恢复的数据量超过1GB&#xff0c;你将需要升级到付费版才能完全恢复。 其次&#xff0c;免费版…

LeetCode---384周赛

题目列表 3033. 修改矩阵 3034. 匹配模式数组的子数组数目 I 3035. 回文字符串的最大数量 3036. 匹配模式数组的子数组数目 II 一、修改矩阵 简单模拟即可&#xff0c;代码如下 class Solution { public:vector<vector<int>> modifiedMatrix(vector<vecto…

专业140+总分400+华中科技大学824信号与系统考研经验华科华中大电子信息与通信工程,真题,大纲,参考书。

今年考研落下帷幕&#xff0c;看到有人落寞&#xff0c;有人金榜题名&#xff0c;心里体会五谷杂陈&#xff0c;自己很幸运通过努力上岸华科&#xff0c;初试专业课824信号与系统140&#xff0c;数一130&#xff0c;总分400&#xff0c;对于这个成绩稍微有点超出自己预期&#…

ViT: transformer在图像领域的应用

文章目录 1. 概要2. 方法3. 实验3.1 Compare with SOTA3.2 PRE-TRAINING DATA REQUIREMENTS3.3 SCALING STUDY3.4 自监督学习 4. 总结参考 论文&#xff1a; An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 代码&#xff1a;https://github.com…

删除windows自带输入法

ctrl shift F 搜狗简繁体切换

【大厂AI课学习笔记】【2.1 人工智能项目开发规划与目标】(4)数据准备的流程

今天学习的是数据准备的流程。 我们已经知道&#xff0c;数据准备占了AI项目超过一半甚至79%的时间。 那么数据准备&#xff0c;都做些什么&#xff0c;有哪些流程。 1.数据采集 观测数据人工收集调查问卷线上数据库 2.数据清洗 有缺失的数据有重复的数据有内容错误的数据…

CSS的注释:以“ /* ”开头,以“ */ ”结尾

CSS的注释:以“ /* ”开头&#xff0c;以“*/”结尾 CSS的注释: 以“ /* ”开头&#xff0c;以“ */ ”结尾 在CSS中&#xff0c;注释是一种非常重要的工具&#xff0c;它们可以帮助开发者记录代码的功能、用法或其他重要信息。这些信息对于理解代码、维护代码以及与他人合作都…

SpringBoot实现OneDrive文件上传

SpringBoot实现OneDrive文件上传 源码 OneDriveUpload: SpringBoot实现OneDrive文件上传 获取accessToken步骤 参考文档&#xff1a;针对 OneDrive API 的 Microsoft 帐户授权 - OneDrive dev center | Microsoft Learn 1.访问Azure创建应用Microsoft Azure&#xff0c;使…