当前位置: 首页 > news >正文

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中的makefilelua.cluac.c文件删除,待用。
在这里插入图片描述

2.2 项目构建环境准备

参考往期博客《Cmake+Kconfig项目构建》,搭建一个空的项目框架,用来测试Lua是否移植成功。

复制项目构建模板,修改名字,修改CMakeLists.txt和kconfig文件,方便后续模块化移植到自己的项目中,目录结构如下。

在这里插入图片描述
这里也可以直接复制到keil工程中,只要你的环境具有ANSI C接口即可。

将前面准备好的源码复制到source/lua文件夹下,注意是将src中的makefilelua.cluac.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)、错误处理、垃圾回收、面向对象等功能。


时间流逝、年龄增长,是自己的磨炼、对知识技术的应用,还有那不变的一颗对嵌入式热爱的心!

到这里就结束了!希望大家给我的文章和B站视频
点赞o( ̄▽ ̄)d、关注(o)/~、评论(▽)!

相关文章:

Lua移植到标准ANSI C环境

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

crossover软件安装程序怎么安装 Crossover for Mac切换Windows系统 crossover软件怎么样

CrossOver Mac版是专为苹果电脑用户打造的一款实用工具&#xff0c;这款工具主要方便用户在Mac上运行windows系列的应用程序&#xff0c;用户不需要安装虚拟机就可以实现各种应用程序的直接应用&#xff0c;并且可以实现无缝集成&#xff0c;实现跨平台的复制粘贴和文件互通等&…...

【2024高考作文】新课标I卷-人工智能主题,用chatGPT作答

目录 &#x1f438;&#x1f438;作文真题 ⭐⭐1.chatGPT作答 ⭐⭐2.通义千问作答 ⭐⭐3.KiMi作答 整理不易&#xff0c;欢迎一键三连&#xff01;&#xff01;&#xff01; 送你们一条美丽的--分割线-- &#x1f438;&#x1f438;作文真题 随着互联网的普及、人工智能的…...

【计算机网络】P2 计算机网络体系结构基本概念,涉及分层的基本术语、SDU、PCI 与 PDU 的概念以及层次结构的含义

目录 概述分层的基本元组基本术语SDU、PCI 以及 PDU层次结构含义 概述 在两个系统中实体间的通信是一个很复杂的过程。而为了降低协议设计以及调试过程的复杂性&#xff0c;同时便于对网络进行研究、实现和维护&#xff0c;促进标准化工作&#xff0c;通常对计算机网络的体系结…...

主流物联网协议客户端开源库介绍(mqtt,coap,websocket,httphttps,tcp及udp)

一.概述 本文主要介绍主流物联网协议&#xff08;mqtt&#xff0c;coap&#xff0c;websocket&#xff0c;http/https&#xff0c;tcp/udp&#xff09;客户端c/c开源库&#xff0c;并对其特点进行对比分析。 二.各个库具体介绍 1.MQTT &#xff08;1&#xff09;常见的c/c客户…...

【Python】成功解决SyntaxError: invalid syntax

【Python】成功解决SyntaxError: invalid syntax 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通本硕&am…...

源代码防泄密

深信达SDC沙盒数据防泄密系统&#xff0c;是专门针对敏感 数据防泄密的保护系统&#xff0c;尤其是对研发型企业数据 防泄密保护。实现对数据的代码级保护&#xff0c;且不影响 工作效率&#xff0c;不影响正常使用。所有敏感数据都自动 加密并配合多种管控机制&#xff0c;从而…...

Unity DOTS技术(十三) ComponentSystem及JobComponentSystem

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

Apifox的使用

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

【SpringBoot】SpringBoot整合RabbitMQ消息中间件,实现延迟队列和死信队列

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;死信队列 RabbitMQ的工作模式 死信队列的工作模式 二、&#x1f349;RabbitMQ相关的安装 三、&#x1f34e;SpringBoot引入RabbitMQ 1.引入依赖 2.创建队列和交换器 2.1 变量声明 2.2 创建…...

kafka消息积压处理方案

背景&#xff1a; 某值班的一天&#xff0c;生产出现消息积压问题&#xff0c;对此类的问题做出快速应对方案来避免同类型问题&#xff0c;防止影响范围进一步的扩大。 出现消费积压后如何处理&#xff1a; 首先优先处理消息积压&#xff0c;如果代码逻辑问题&#xff0c;立…...

【vscode-快捷键 一键JSON格式化】

网上有很多JSON格式化工具&#xff0c;也有很多好用的在线json格式化工具。但是其实Vscode里面的可以直接格式化JSON&#xff0c;这里分享一个我常用的小插件 Prettify JSON 未格式化的JSON数据 召唤出命令行&#xff0c;输入prettify JSON 即可! ✿✿ヽ(▽)ノ✿...

什么是 Spring Boot 的起步依赖和自动配置?它们的作用是什么?

Spring Boot 的起步依赖和自动配置是 Spring Boot 框架的两个核心特性&#xff0c;它们的作用主要是简化了 Spring Boot 项目的搭建和配置过程。 起步依赖&#xff08;Starter Dependencies&#xff09;&#xff1a;起步依赖是一种预先定义好的依赖关系集合&#xff0c;它包含…...

rk3568 norflash+pcei nvme 配置

文章目录 rk3568 norflashpcei nvme 配置1&#xff0c;添加parameter_nor.txt文件2 修改编译规则3 修改uboot4 修改BoardConfig.mk5 修改kernel pcei配置6 编译7 烧录 rk3568 norflashpcei nvme 配置 1&#xff0c;添加parameter_nor.txt文件 device/rockchip/rk356x/rk3568_…...

【Vue】面经基础版-首页请求渲染

步骤分析 1.安装axios 2.看接口文档&#xff0c;确认请求方式&#xff0c;请求地址&#xff0c;请求参数 3.created中发送请求&#xff0c;获取数据&#xff0c;存储到data中 4.页面动态渲染 代码实现 1.安装axios yarn add axios npm i axios 2.接口文档 请求地址: …...

OBS+nginx+nginx-http-flv-module实现阿里云的推流和拉流

背景&#xff1a;需要将球机视频推送到阿里云nginx&#xff0c;使用网页和移动端进行播放&#xff0c;以前视频格式为RTMP&#xff0c;但是在网页上面播放RTMP格式需要安装flash插件&#xff0c;chrome浏览器不给安装&#xff0c;调研后发现可以使用nginx的模块nginx-http-flv-…...

ch1计算机网络和因特网

*1.1 什么是因特网 因特网是一个世界范围的计算机网络,即一个互联了遍及全世界的数十亿计算设备的网络。 具体构成: 主机hosts或端系统end-systems:数以亿计的计算设备互连,例如 主机-PCs(计算机), workstations(工作站), servers(服务器)端系统-PDAs,phones(…...

Web前端安全测试:深入剖析与实战策略

Web前端安全测试&#xff1a;深入剖析与实战策略 在数字化时代&#xff0c;Web前端作为用户与互联网服务交互的直接窗口&#xff0c;其安全性至关重要。然而&#xff0c;随着技术的不断进步&#xff0c;前端安全面临的威胁也日益复杂和多样化。因此&#xff0c;进行Web前端安全…...

Java学习-JDBC(一)

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

异步复位和同步释放

文章目录 前言一、为什么需要复位呢&#xff1f;二、同步复位1. 同步复位定义2. 同步复位的实现3. 同步复位的优点和缺点同步复位优点同步复位缺点 三、异步复位1. 异步复位定义2. 异步复位的实现3. 异步复位的优点和缺点异步复位优点异步复位缺点 四、异步复位同步释放1. reco…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)

这是系统中断服务程序的默认处理汇编函数&#xff0c;如果我们没有定义实现某个中断函数&#xff0c;那么当stm32产生了该中断时&#xff0c;就会默认跑这里来了&#xff0c;所以我们打开了什么中断&#xff0c;一定要记得实现对应的系统中断函数&#xff0c;否则会进来一直循环…...