Lua移植到标准ANSI C环境
本文目录
- 1、引言
- 2、环境准备
- 2.1 源码下载
- 2.2 项目构建环境准备
- 3、项目编译
- 3.1 添加main.c
- 3.2 Kconfig选择模块
- 3.3 项目构建
- 3.4 项目编译
- 4、运行
文章对应视频教程:
在下方喔 ~~~ 欢迎关注
点击图片或链接访问我的B站主页~~~
lau解释器移植与功能验证
1、引言
本文将介绍如何将Lua解释器移植到标准的ANSI C环境。
实现ANSI C的移植,就可以实现在嵌入式各类板卡的移植。
当然,你的板卡得具备ANSI C环境,一般情况keil、GCC都会有C库实现。
关于Lua解释器的重要性,或者有何特殊指出,可以看看我得上篇文章:
《可用于嵌入式的解释器调研对比,及lua解释器介绍》
2、环境准备
2.1 源码下载
您可以在Lua官方网站上下载Lua解释器的源代码。以下是Lua官方网站的链接:
Lua解释器下载
在该网页上,点击的Lua解释器源代码的下载链接(图中红色框部分),进行源代码下载,可能有点慢。
下载完成后,进行接下,得到下图的文件,提取其中的src
文件夹,将src
中的makefile
、lua.c
、luac.c
文件删除,待用。
2.2 项目构建环境准备
参考往期博客《Cmake+Kconfig项目构建》,搭建一个空的项目框架,用来测试Lua是否移植成功。
复制项目构建模板,修改名字,修改CMakeLists.txt和kconfig文件,方便后续模块化移植到自己的项目中,目录结构如下。
这里也可以直接复制到keil工程中,只要你的环境具有ANSI C接口即可。
将前面准备好的源码复制到source/lua
文件夹下,注意是将src
中的makefile
、lua.c
、luac.c
文件删除后,剩下的代码。
3、项目编译
3.1 添加main.c
我们需要在main.c中实现对lua代码的解释功能。
由于我在window环境下,我可以很轻松的打开文件,所以直接采用的文件读取的方式执行。
大家也可以直接将代码写在内存中,类似与下面这种方式:
char buff[] = "printf(123)";
我这边的代码比较复杂,还是用读取文件实现。
main.c内容如下:
#include "stdio.h"
#include <stdlib.h>#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "string.h"#define BUFFER_SIZE 1024*1024*1static lua_State *L = NULL ;int lua_deal_line(const char *str)
{int ret = luaL_dostring(L,str);if(ret != LUA_OK){printf("%s\r\n",lua_tostring(L ,-1));return -1;} return 0;
}int main(void)
{L = luaL_newstate();luaL_openlibs(L);FILE *file;char buffer[BUFFER_SIZE] = {0};size_t read_size;// 打开文件file = fopen("test.lua", "rb"); // 使用"rb"模式以二进制方式读取文件if (file == NULL) {perror("无法打开文件");return 1;}// 读取文件内容到缓冲区read_size = fread(buffer, 1, BUFFER_SIZE - 1, file); // 保留一个字节给'\0'if (read_size == 0 && ferror(file)) {perror("read file error\r\n");fclose(file);return 1;}// 添加字符串末尾的空字符buffer[read_size] = '\0';// 关闭文件fclose(file);lua_deal_line(buffer);lua_close(L);return 1;
}
创建test.lua文件放在当前路径下。
-- Lua 基本语法
print("Running basic syntax test...")
assert(true) -- 如果代码运行到这里,没有错误发生,那么基本语法测试通过-- Lua 数据类型
print("Running data type test...")
local num = 10 -- number
local str = "Hello" -- string
local bool = true -- boolean
local tbl = {1, 2, 3} -- table
local func = function() return "I am a function" end -- function
assert(type(num) == "number")
assert(type(str) == "string")
assert(type(bool) == "boolean")
assert(type(tbl) == "table")
assert(type(func) == "function")-- Lua 变量
print("Running variable test...")
local localVar = "I am local"
_G.globalVar = "I am global"
assert(localVar == "I am local")
assert(_G.globalVar == "I am global")-- Lua 循环
print("Running loop test...")
local sum = 0
for i = 1, 5 dosum = sum + i
end
assert(sum == 15)sum = 0
local i = 1
while i <= 5 dosum = sum + ii = i + 1
end
assert(sum == 15)-- Lua 流程控制
print("Running control flow test...")
local x = 10
local result
if x > 5 thenresult = "greater"
elseif x == 5 thenresult = "equal"
elseresult = "less"
end
assert(result == "greater")-- Lua 函数
print("Running function test...")
function add(a, b)return a + b
end
assert(add(5, 3) == 8)-- Lua 运算符
print("Running operator test...")
local a, b = 10, 20
assert(a + b == 30)
assert(a - b == -10)
assert(a * b == 200)
assert(a / b == 0.5)
assert(a % b == 10)
assert(a ^ 2 == 100)-- Lua 字符串
print("Running string test...")
local s = "Lua"
assert(#s == 3)
assert(s .. " programming" == "Lua programming")-- Lua 数组
print("Running array test...")
local arr = {10, 20, 30, 40, 50}
assert(arr[1] == 10)
assert(#arr == 5)-- Lua 迭代器
print("Running iterator test...")
local function squareIterator(max, current)current = current + 1if current <= max thenreturn current, current * currentend
end
local results = {}
for i, n in squareIterator, 5, 0 dotable.insert(results, n)
end
assert(#results == 5)
assert(results[1] == 1)
assert(results[5] == 25)-- Lua table(表)
print("Running table test...")
local person = {name = "John", age = 30}
assert(person.name == "John")
assert(person.age == 30)-- Lua 模块与包
print("Running module test...")
-- 假设有一个 module_name.lua 文件,内容如下:
-- local M = {}
-- function M.hello() return "Hello, module!" end
-- return M
-- local module = require("module_name")
-- assert(module.hello() == "Hello, module!")-- Lua 元表(Metatable)
print("Running metatable test...")
local mt = {__add = function(table1, table2)local sum = {}for k, v in pairs(table1) dosum[k] = v + table2[k]endreturn sumend
}
local t1 = {1, 2, 3}
local t2 = {4, 5, 6}
setmetatable(t1, mt)
local t3 = t1 + t2
assert(t3[1] == 5)
assert(t3[2] == 7)
assert(t3[3] == 9)-- Lua 协同程序(coroutine)
-- print("Running coroutine test...")
-- local co = coroutine.create(function()
-- for i = 1, 5 do
-- coroutine.yield(i)
-- end
-- end)
-- local _, first = coroutine.resume(co)
-- assert(first == 1)
-- local _, second = coroutine.resume(co)
-- assert(second == 2)-- Lua 文件 I/O
-- print("Running file I/O test...")
-- local file = io.open("test.txt", "w")
-- file:write("Hello, file!")
-- file:close()
-- file = io.open("test.txt", "r")
-- local content = file:read("*all")
-- file:close()
-- assert(content == "Hello, file!")-- Lua 错误处理
print("Running error handling test...")
local status, err = pcall(function()error("An error occurred")
end)
assert(not status)
assert(string.find(err, "An error occurred"))-- Lua 调试(Debug)
-- print("Running debug test...")
-- local debug = require("debug")
-- local traceback
-- local function myfunc()
-- traceback = debug.traceback("Stack trace")
-- end
-- myfunc()
-- assert(string.find(traceback, "Stack trace"))-- Lua 垃圾回收
print("Running garbage collection test...")
local tbl = {1, 2, 3}
setmetatable(tbl, {__gc = function() print("Garbage collected") end})
tbl = nil
collectgarbage() -- 在控制台中应能看到 "Garbage collected"-- Lua 面向对象
print("Running object-oriented test...")
local Animal = {name = "", age = 0}
function Animal:new(o, name, age)o = o or {}setmetatable(o, self)self.__index = selfself.name = name or ""self.age = age or 0return o
end
function Animal:speak()return "I am " .. self.name .. ", " .. self.age .. " years old."
endlocal dog = Animal:new(nil, "Dog", 5)
assert(dog:speak() == "I am Dog, 5 years old.")print("All tests passed!")
3.2 Kconfig选择模块
在project\pro1
目录下,打开powershell,输入python .\ck_script.py cn
进入到图形配置界面。
确保回车选中该模块,再按Q Y按键退出。
3.3 项目构建
在powershell,输入python .\ck_script.py b
进行项目构建,构建完成后,对文件的编译规则就已经生成。
3.4 项目编译
在powershell,输入python .\ck_script.py m
进行项目编译,结果如下。
4、运行
在powershell,输入.\lua.exe
运行程序,结果如下。
这个Lua脚本验证了我们需要的基本语法、数据类型、变量、循环、流程控制、函数、运算符、字符串、数组、迭代器、table(表)、元表(Metatable)、错误处理、垃圾回收、面向对象等功能。
时间流逝、年龄增长,是自己的磨炼、对知识技术的应用,还有那不变的一颗对嵌入式热爱的心!
点赞o( ̄▽ ̄)d、关注(o)/~、评论(▽)!
相关文章:

Lua移植到标准ANSI C环境
本文目录 1、引言2、环境准备2.1 源码下载2.2 项目构建环境准备 3、项目编译3.1 添加main.c3.2 Kconfig选择模块3.3 项目构建3.4 项目编译 4、运行 文章对应视频教程: 在下方喔 ~~~ 欢迎关注 点击图片或链接访问我的B站主页~~~ lau解释器移植与功能验证 1、引言 本…...

crossover软件安装程序怎么安装 Crossover for Mac切换Windows系统 crossover软件怎么样
CrossOver Mac版是专为苹果电脑用户打造的一款实用工具,这款工具主要方便用户在Mac上运行windows系列的应用程序,用户不需要安装虚拟机就可以实现各种应用程序的直接应用,并且可以实现无缝集成,实现跨平台的复制粘贴和文件互通等&…...
【2024高考作文】新课标I卷-人工智能主题,用chatGPT作答
目录 🐸🐸作文真题 ⭐⭐1.chatGPT作答 ⭐⭐2.通义千问作答 ⭐⭐3.KiMi作答 整理不易,欢迎一键三连!!! 送你们一条美丽的--分割线-- 🐸🐸作文真题 随着互联网的普及、人工智能的…...
【计算机网络】P2 计算机网络体系结构基本概念,涉及分层的基本术语、SDU、PCI 与 PDU 的概念以及层次结构的含义
目录 概述分层的基本元组基本术语SDU、PCI 以及 PDU层次结构含义 概述 在两个系统中实体间的通信是一个很复杂的过程。而为了降低协议设计以及调试过程的复杂性,同时便于对网络进行研究、实现和维护,促进标准化工作,通常对计算机网络的体系结…...
主流物联网协议客户端开源库介绍(mqtt,coap,websocket,httphttps,tcp及udp)
一.概述 本文主要介绍主流物联网协议(mqtt,coap,websocket,http/https,tcp/udp)客户端c/c开源库,并对其特点进行对比分析。 二.各个库具体介绍 1.MQTT (1)常见的c/c客户…...

【Python】成功解决SyntaxError: invalid syntax
【Python】成功解决SyntaxError: invalid syntax 下滑即可查看博客内容 🌈 欢迎莅临我的个人主页 👈这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地!🎇 🎓 博主简介:985高校的普通本硕&am…...
源代码防泄密
深信达SDC沙盒数据防泄密系统,是专门针对敏感 数据防泄密的保护系统,尤其是对研发型企业数据 防泄密保护。实现对数据的代码级保护,且不影响 工作效率,不影响正常使用。所有敏感数据都自动 加密并配合多种管控机制,从而…...

Unity DOTS技术(十三) ComponentSystem及JobComponentSystem
文章目录 一.ComponentSystem介绍二.JobComponentSystem 一.ComponentSystem介绍 1.继承ComponentSystem需要实现抽象OnUpdate() 2.与SystemBase不同,ComponentSystem不包含LambdaSingleJobDescription, 3.CompoentSystem的带代码都是在主线程上运行,不支持多线程. 4.并不能在…...

Apifox的使用
1、了解Apifox的工具特点和使用方法 2、使用Apifox辅助生成接口文档,尝试使用Apifox进行其他前后端调试。 Apifox IDEA 插件快速上手 | Apifox 帮助文档 Apifox IDEA 插件来啦!是真的超好用!_哔哩哔哩_bilibili 21分钟学会Apifox_哔哩哔哩…...

【SpringBoot】SpringBoot整合RabbitMQ消息中间件,实现延迟队列和死信队列
📝个人主页:哈__ 期待您的关注 目录 一、🔥死信队列 RabbitMQ的工作模式 死信队列的工作模式 二、🍉RabbitMQ相关的安装 三、🍎SpringBoot引入RabbitMQ 1.引入依赖 2.创建队列和交换器 2.1 变量声明 2.2 创建…...
kafka消息积压处理方案
背景: 某值班的一天,生产出现消息积压问题,对此类的问题做出快速应对方案来避免同类型问题,防止影响范围进一步的扩大。 出现消费积压后如何处理: 首先优先处理消息积压,如果代码逻辑问题,立…...

【vscode-快捷键 一键JSON格式化】
网上有很多JSON格式化工具,也有很多好用的在线json格式化工具。但是其实Vscode里面的可以直接格式化JSON,这里分享一个我常用的小插件 Prettify JSON 未格式化的JSON数据 召唤出命令行,输入prettify JSON 即可! ✿✿ヽ(▽)ノ✿...
什么是 Spring Boot 的起步依赖和自动配置?它们的作用是什么?
Spring Boot 的起步依赖和自动配置是 Spring Boot 框架的两个核心特性,它们的作用主要是简化了 Spring Boot 项目的搭建和配置过程。 起步依赖(Starter Dependencies):起步依赖是一种预先定义好的依赖关系集合,它包含…...

rk3568 norflash+pcei nvme 配置
文章目录 rk3568 norflashpcei nvme 配置1,添加parameter_nor.txt文件2 修改编译规则3 修改uboot4 修改BoardConfig.mk5 修改kernel pcei配置6 编译7 烧录 rk3568 norflashpcei nvme 配置 1,添加parameter_nor.txt文件 device/rockchip/rk356x/rk3568_…...
【Vue】面经基础版-首页请求渲染
步骤分析 1.安装axios 2.看接口文档,确认请求方式,请求地址,请求参数 3.created中发送请求,获取数据,存储到data中 4.页面动态渲染 代码实现 1.安装axios yarn add axios npm i axios 2.接口文档 请求地址: …...

OBS+nginx+nginx-http-flv-module实现阿里云的推流和拉流
背景:需要将球机视频推送到阿里云nginx,使用网页和移动端进行播放,以前视频格式为RTMP,但是在网页上面播放RTMP格式需要安装flash插件,chrome浏览器不给安装,调研后发现可以使用nginx的模块nginx-http-flv-…...
ch1计算机网络和因特网
*1.1 什么是因特网 因特网是一个世界范围的计算机网络,即一个互联了遍及全世界的数十亿计算设备的网络。 具体构成: 主机hosts或端系统end-systems:数以亿计的计算设备互连,例如 主机-PCs(计算机), workstations(工作站), servers(服务器)端系统-PDAs,phones(…...
Web前端安全测试:深入剖析与实战策略
Web前端安全测试:深入剖析与实战策略 在数字化时代,Web前端作为用户与互联网服务交互的直接窗口,其安全性至关重要。然而,随着技术的不断进步,前端安全面临的威胁也日益复杂和多样化。因此,进行Web前端安全…...

Java学习-JDBC(一)
JDBC 概念 JDBC(Java Database Connectivity)Java数据库连接JDBC提供了一组独立于任何数据库管理系统的APIJava提供接口规范,由各个数据库厂商提供接口的实现,厂商提供的实现类封装成jar文件,也就是我们俗称的数据库驱动jar包JDBC充分体现了…...

异步复位和同步释放
文章目录 前言一、为什么需要复位呢?二、同步复位1. 同步复位定义2. 同步复位的实现3. 同步复位的优点和缺点同步复位优点同步复位缺点 三、异步复位1. 异步复位定义2. 异步复位的实现3. 异步复位的优点和缺点异步复位优点异步复位缺点 四、异步复位同步释放1. reco…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...

6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...

高效的后台管理系统——可进行二次开发
随着互联网技术的迅猛发展,企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心,成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统,它不仅支持跨平台应用,还能提供丰富…...