数据打包解包(pack)
一、LuatOS string 库 pack 和 unpack 接口
LuatOS string 库的 pack 和 unpack 是一个用于在 Lua 程序中进行二进制数据打包和解包操作的接口,支持多种数据类型和字节序格式,方便处理二进制协议和文件。
由于 Lua 中字符串几乎可以用于存储所有形式的数据,所以下面先系统介绍下 Lua 字符串的特点,方便习惯使用 C 语言编程的初学者系统的了解两种语言在数据存储方面的一些差异。
1.1 字节序的概念
字节序是指在计算机存储或传输多字节数据时,字节的排列顺序,通常分为大端序(big-endian,最高有效字节在前)和小端序(little-endian,最低有效字节在前)。
大端也常被称作叫“网络序”因为 TCP、UDP 网络数据传输和存储都使用这种格式,而一些像 STM32 等 ARM 单片机,则使用小端存储格式;
1.2 Lua 中字符串存储
Lua 中字符串可以存储所有字节数据,包括“字符串中的可见和不可见字符”,这一点与 C 语言有很大区别;
1.3 Lua 中字符串的序号
注:Lua 中字符串首字节从序号 1 开始,而不像 C 语言是从序号 0 开始;并且 Lua 字符串有正数序号也有负数序号,这一点也与 C 语言不同;
二、演示功能概述
本文使用 Air780EP 核心板,运用 LuatOS string 库 pack 和 unpack 接口对二进制数据进行打包和解包操作。
三、硬件准备
参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。
四、软件环境
“凡事预则立,不预则废。”在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。
1. Luatools工具;
2. 内核固件文件(底层core固件文件):LuatOS-SoC_V2002_Air780EP;参考项目使用的内核固件;
3. luatos需要的脚本和资源文件
脚本和资源文件点击此处查看与下载
lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件;
准备好软件环境之后,接下来查看如何烧录项目文件到Air780EP核心板,将本篇文章中演示使用的项目文件烧录到Air780EP核心板中。
五、代码示例介绍
5.1 完整程序清单
注:完整复制后保存为 main.lua,可直接使用
-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "PACK"
VERSION = "2.0.0"
--[[
本demo演示 string字符串的基本操作
1\. lua的字符串是带长度, 这意味着, 它不依赖0x00作为结束字符串, 可以包含任意数据
2\. lua的字符串是不可变的, 就不能直接修改字符串的一个字符, 修改字符会返回一个新的字符串
]]
-- sys库是标配
_G.sys = require("sys")
sysplus = require("sysplus")
-- Air780EP的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
pm.power(pm.PWK_MODE, false)
end
local netLed = require("netLed")
--GPIO18配置为输出,默认输出低电平,可通过setGpio18Fnc(0或者1)设置输出电平
local LEDA= gpio.setup(27, 0, gpio.PULLUP)
sys.taskInit(function ()
sys.wait(1000) -- 免得看不到日志
local tmp
--实验1:以小端方式编码
local data = string.pack("<I", 0xAABBCCDD) --‘<’表示以小端方式编码,'I'表示,unsigned int , 4字节
log.info("pack:", string.format("%02X", data:byte(1)), --输出小端编码后的数据
string.format("%02X", data:byte(2)),
string.format("%02X", data:byte(3)),
string.format("%02X", data:byte(4)))
--实验2:以大端方式编码
local data = string.pack(">I", 0xAABBCCDD)
log.info("pack:", string.format("%02X", data:byte(1)), --输出大端编码后的数据
string.format("%02X", data:byte(2)),
string.format("%02X", data:byte(3)),
string.format("%02X", data:byte(4)))
--实验3:对上面已经完成的大端编码,再次进行解包为每个字节
local byte1,byte2,byte3,byte4 = string.unpack(">BBBB", data) --将32位数据拆成4个8位字节数据
--log.info("Unpack", byte1,byte2,byte3,byte4)
log.info("Unpack:", string.format("%02X", byte1), --以十六进制形式输出拆解后的4个字节数据,分别对应byte1~4
string.format("%02X", byte2),
string.format("%02X", byte3),
string.format("%02X", byte4))
end)
-- 这里演示4G模块上网后,会自动点亮网络灯,方便用户判断模块是否正常开机
sys.taskInit(function()
while true do
sys.wait(6000)
if mobile.status() == 1 then
gpio.set(27, 1)
else
gpio.set(27, 0)
mobile.reset()
end
end
end)
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
六、功能验证
注:详细日志输出内容,在程序中有增强注释说明,请详细查看。
七、总结
至此,我们已使用 Air780EP 开发板验证了 LuatOS string 库 pack 和 unpack 接口对二进制数据进行打包和解包的功能。
八、拓展说明
lua 5.3 之前,string 不支持这两个接口,当时我们移植了 pack 库,使用方法和 string 库的两个接口原理一样,函数入口参数顺序有少许差别,具体可以参考 api(https://docs.openluat.com/Air780EP/luatos/api/core/pack/),当前最新固件 string 已完全支持 pack 和 unpack 两个接口,所以开发者可直接使用 string 这两个方法即可。
给读者的话
本篇文章由
肇朔
开发;本篇文章描述的内容,如果有错误、细节缺失、细节不清晰或者其他任何问题,总之就是无法解决您遇到的问题;
请登录合宙技术交流论坛,点击文档找错赢奖金-Air780EP-LuatOS-软件指南-通用工具库-数据打包解包
用截图标注+文字描述的方式跟帖回复,记录清楚您发现的问题;
我们会迅速核实并且修改文档;
同时也会为您累计找错积分,您还可能赢取月度找错奖金!