跳转至

otp - OTP操作库

作者:马亚丹

一、概述

otp 核心库是合宙 LuatOS 系统中用于操作" 一次性可编程存储(One-Time Programmable Memory)"的模块,主要作用是:

  • 读取芯片内置 OTP 区域的数据(如设备唯一 ID、加密密钥、生产信息等);
  • 向 OTP 区域写入数据(注意:OTP 写入后不可擦除,需谨慎操作)。

关键注意事项

  1. OTP 的 “一次性” 特性:OTP 存储区域写入后永久不可修改,因此写入前必须确认数据正确,且地址未被使用过。
  2. 地址与长度限制: 写入 / 读取的长度需与 OTP 块大小对齐,按 4 字节对齐。

典型应用场景

  • 设备身份标识:读取 OTP 中内置的唯一 ID,作为设备 “身份证”;
  • 加密密钥存储:将 AES/RSA 密钥写入 OTP,防止被逆向窃取;
  • 生产信息固化:工厂量产时写入固件版本、生产日期等信息,永久保存。

二、核心示例

1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/otp

-- 步骤1:读取 OTP 中指定地址的数据(示例:读取地址 0 开始的 4 字节)
local otp_data = otp.read(0, 0, 4)
if otp_data then
    -- 以十六进制打印读取的数据
    log.info("OTP 读取结果", otp_data:toHex())  
else
    log.error("OTP 读取失败")
end

-- 步骤2:写入测试数据到 OTP
-- 要写入的字符串(需确保长度与 OTP 块大小匹配)    
local write_data = "1234" 
-- 写入数据
local write_ok = otp.write(0, write_data, 0) 
if write_ok then
    log.info("OTP 写入成功")
    -- 验证写入结果
    local verify_data = otp.read(0, 0, #write_data)
    log.info("写入验证", verify_data:toHex(), 
        verify_data == write_data and "匹配" or "不匹配")
else
    log.error("OTP 写入失败(OTP 不可重复写入)"
end

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

otp 核心库,没有常量。

四、函数详解

4.1 otp.read(zone, offset, len)

功能

读取指定 OTP 区域的数据

注意事项

暂无

参数

zone

参数含义:otp区域
数据类型:number
取值范围:Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB取值是1/2/3
Air722取值只有2
Air8101/6101取值是0/1/2/3/4/5/6/7.
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下所示,第一个参数0即是读取指定OTP区域的数据时的otp区域
         local otpdata = otp.read(0, 0, 64)

offset

参数含义:偏移量,表示从 OTP 区域的哪个位置开始读
数据类型:number
取值范围:            Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB/Air722取值是0~4095;        
        Air8101/6101取值是0~255.
是否必选:必须传入此参数;
注意事项:必须是4的倍数,offset+len的结果不能超出该区域的总容量
参数示例:--如下所示,第二个参数0即是读取指定OTP区域的数据时的偏移量
         local otpdata = otp.read(0, 0, 64)

len

参数含义:读取数据的长度, 单位字节
数据类型:number
取值范围:Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB/Air722取值是1~4096;        
         Air8101/6101取值是1~256.
是否必选:必须传入此参数;
注意事项:必须是4的倍数, offset+len的结果不能超出该区域的总容量
参数示例:--如下所示,第三个参数64即是读取指定OTP区域的数据时的数据长度,64字节
         local otpdata = otp.read(0, 0, 64)

返回值

local otpdata = otp.read(zone, offset, len)

有一个返回值 otpdata

otpdata

含义说明:在指定OTP区域读取到的数据
         成功时返回string,否则返回nil     
数值类型:string
取值范围:无特别限制
注意事项:暂无
返回示例:例如返回 "test data"时表示读取数据成功

示例

local otpdata = otp.read(0, 0, 64)
if otpdata then
    log.info("otp", otpdata:toHex())
end

4.2 otp.write(zone, data, offset)

功能

往指定 OTP 区域写入数据

注意事项

写数据操作需在飞行模式下调用,否则有死机风险!

OTP 写入后不可擦除,需谨慎操作

参数

zone

参数含义:otp区域
数据类型:number
取值范围:    Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB取值是1/2/3
         Air722取值只有2
         Air8101/6101取值是0/1/2/3/4/5/6/7.
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下所示,第一个参数0即是读取指定OTP区域的数据时的otp区域
         local write_data = "1234" 
         local write_ok = otp.write(0, write_data , 0)

data

参数含义:待写入的数据
数据类型:string
取值范围:数据长度Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB/Air722是1~4096字节;        
         Air8101/61011~256字节.
是否必选:必须传入此参数;
注意事项:数据长度必须是4的倍数, data长度+offset的结果不能超出该区域的总容量
参数示例:--如下所示,第二个参数write_data即是写入到指定OTP区域的数据
         local write_data = "1234" 
         local write_ok = otp.write(0, write_data , 0)

offset

参数含义:偏移量,表示从 OTP 区域的哪个位置开始写入
数据类型:number
取值范围:Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB/Air722取值是0~4095;        
         Air8101/6101取值是0~255.
是否必选:必须传入此参数;
注意事项:必须是4的倍数,offset+len的结果不能超出该区域的总容量
参数示例:--如下所示,第三个参数0即是写入数据到指定OTP区域时的偏移量
         local write_data = "1234" 
         local write_ok = otp.write(0, write_data , 0)

返回值

local write_ok = otp.write(zone, data, offset)

有一个返回值 write_ok

write_ok

含义说明:写入数据到指定OTP区域的结果
         成功时返回true,否则返回false   
数值类型:boolean
取值范围:true/false
注意事项:写数据操作需在飞行模式下调用,否则有死机风险!
OTP 写入后不可擦除,写之前需要擦除
返回示例:例如返回true时表示写入数据成功

示例

-- 进入飞行模式
mobile.flymode(0, true)
-- 要写入的字符串(需确保长度与 OTP 块大小匹配)    
local write_data = "1234" 
-- 写入数据
local write_ok = otp.write(0, write_data,0) 
if write_ok then
    log.info("OTP 写入成功")    
end

4.3 otp.erase(zone)

功能

擦除指定的 OTP 区域的数据

注意事项

擦除数据操作需在飞行模式下调用,否则有死机风险!

OTP 写入后不可擦除,写入前需要擦除

参数

zone

参数含义:otp区域
数据类型:number
取值范围:Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB取值是1/2/3
         Air722取值只有2
         Air8101/6101取值是0/1/2/3/4/5/6/7.
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下所示,参数0即是擦除指定OTP区域的数据时的otp区域
         local erase_ok = otp.erase(0)

返回值

local erase_ok = otp.erase(zone)

有一个返回值 erase_ok

erase_ok

含义说明:擦除指定OTP区域的结果
         成功时返回true,否则返回false   
数值类型:boolean
取值范围:true/false
注意事项:擦除数据操作需在飞行模式下调用,否则有死机风险!
         OTP写入后不可擦除,写之前需要擦除
返回示例:例如返回true时表示擦除数据成功

示例

-- 进入飞行模式
mobile.flymode(0, true)
local erase_ok = otp.erase(0)
if erase_ok then
    log.info("OTP 擦除成功")    
end

4.4 otp.lock(zone)

功能

锁定 OTP 区域.

注意事项

特别注意!!一旦加锁即无法解锁,OTP 会变成只读!!!

锁定操作需在飞行模式下调用,否则有死机风险!

参数

zone

参数含义:otp区域
数据类型:number
取值范围:Air780EPM/EHM/EHV/EGH/Air8000/A/W/G/T/U/N/GU/GN/XB/DB取值是1/2/3
         Air722取值只有2
         Air8101/6101取值是0/1/2/3/4/5/6/7.
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下所示,参数0即是锁定指定OTP区域的数据时的otp区域
         local lock_ok = otp.lock(0)

返回值

local lock_ok = otp.lock(zone)

有一个返回值 lock_ok

lock_ok

含义说明:锁定指定OTP区域的结果
         成功时返回true,否则返回false   
数值类型:boolean
取值范围:true/false
注意事项:特别注意!!一旦加锁即无法解锁,OTP会变成只读!!!
锁定操作需在飞行模式下调用,否则有死机风险!
返回示例:例如返回true时表示擦除数据成功

示例

-- 进入飞行模式
mobile.flymode(0, true)
local lock_ok = otp.lock(0)
if lock_ok then
    log.info("OTP 锁定成功")    
end

五、产品支持说明

支持 LuatOS 开发的所有产品都支持 otp 核心库。

Air780EPM 的 1 号、2 号、103 号固件除外。

具体参考 合宙资料中心 具体产品下固件和 demo 中的固件版本说明;

以 Air780EPM 为例,可以访问:https://docs.openluat.com/air780epm/luatos/firmware/version/

可以得知,Air780EPM ,仅 104 号固件支持 otp 核心库。

其余型号所有固件都支持 otp 核心库。