sfud - flash驱动 软件包(仅支持驱动nor flash设备)
作者:马亚丹
一、概述
sfud 核心库是串行 Flash 通用驱动库( Serial Flash Universal Driver),主要作用是简化对各种品牌 / 型号的 Serial NOR Flash 的兼容操作,让开发者无需关注不同 Flash 的命令差异,直接通过统一 API 实现读写、擦除等功能。
- 硬件兼容性:当产品需要兼容多种 Flash(如应对供应链缺货,替换品牌 / 型号)时,sfud 核心库 可一键适配,无需修改业务逻辑。
- 快速开发:开发者只需初始化 SPI 通信,即可通过 sfud 核心库 直接操作 Flash,无需研究具体型号的手册。
- 工具开发:制作 Flash 烧写器、编程器时,sfud 核心库 可自动识别目标 Flash 并执行读写操作。
简言之,sfud 核心库 是连接 “上层应用” 与 “底层 Flash 硬件” 的桥梁,通过屏蔽硬件差异和提供标准化接口,大幅降低 Serial NOR Flash 的开发难度。
注意:
- sfud 库不支持挂载 nand flash.如需挂载 nand flash,可以使用 lf 核心库。
- sfud 只支持挂载 1 个设备,多设备挂载请使用 lf 核心库。
lf 核心库 lf-API 是合宙自己封装的用于驱动 nor flash 和 nand flash 的库,可以把 nor flash 和 nand flash 挂载成 littlefs 文件系统,目前功能上和 sfud 核心库的使用有重复,区别是 sfud 核心库不支持挂载 nand flash,但是 if 核心库可以,因为 lf 功能更强大,所以推荐使用 lf 核心库。
二、核心示例
1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/accessory_board/AirSPINORFLASH_1000
local function sfud_test()
-- flash操作起始地址(示例值,需根据需求调整)
local erase_addr = 4096
-- 擦除数据的大小(示例值,需匹配 Flash block 大小)
local erase_size = 4096
--需要操作的数据(示例值,需根据需求调整)
local data = "testdata"
--方式1 spi对象方式初始化sfud
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN,0,0,8,2000000,spi.MSB,spi.master,spi.full)
log.info("Flash初始化", "开始")
local result = sfud.init(spi_device)
--方式2 spi参数方式初始化sfud
--local result = sfud.init(spi.SPI_0,20,20 * 1000 * 1000)
if not result then
log.error("Flash初始化", "失败")
spi_device:close()
return
end
--log打印 I/user.Flash初始化结果: true
log.info("Flash初始化结果:", result)
local sfud_device = sfud.getDeviceTable()
--log打印 I/user.获取flash设备信息表: userdata: 0C0E0328
log.info("获取flash设备信息表:", sfud_device)
local sfud_int = sfud.getDeviceNum()
--log打印 I/user.获取flash设备信息表中的设备总数: 1
log.info("获取flash设备信息表中的设备总数:", sfud_int )
local sfud_device_ud= sfud.getDevice(0)
--log打印 I/user.获通过flash信息表中的索引获取flash设备: userdata: 0C0E0328
log.info("获通过flash信息表中的索引获取flash设备:", sfud_device_ud)
--log打印 I/user.擦除一个块的数据: 0
log.info("擦除一个块的数据:", sfud.erase(sfud_device, erase_addr, erase_size))
--log打印 I/user.写入数据: 0
log.info("写入数据:", sfud.write(sfud_device, erase_addr, data))
--log打印 I/user.读取数据: testdata
log.info("读取数据:", sfud.read(sfud_device, erase_addr, erase_size ))
--log打印 I/user.先擦除再写入数据:0
log.info("先擦除再写入数据:", sfud.eraseWrite(sfud_device, erase_addr, data))
local mount_point = "/sfud_flash"
--挂载flash为文件系统
local mount_ok = sfud.mount(sfud_device, mount_point)
--log打印 I/user.挂载 sfud lfs文件系统:true
log.info("挂载 sfud lfs文件系统:", mount_ok)
--log打印 I/user.获取flash 容量和page大小: 8388608 4096
log.info("获取 Flash 容量和page大小:", sfud.getInfo(sfud_device))
--log打印 I/user.擦除flash全部数据: 0
log.info("擦除flash全部数据:",sfud.chipErase(sfud_device))
end
sys.taskInit(sfud_test)
三、常量详解
核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
每个常量对应的常量取值仅做日志打印时查询使用,不要将这个常量取值用做具体的业务逻辑判断,因为LuatOS内核固件可能会变更每个常量对应的常量取值;
如果用做具体的业务逻辑判断,一旦常量取值发生改变,业务逻辑就会出错;
sfud 核心库,没有常量。
四、函数详解
4.1 sfud.init(spi_id, spi_cs, spi_bandrate)
功能
初始化 sfud 方式 1,以 spi 参数的方式初始化 sfud
注意事项
暂无
参数
spi_id
参数含义:SPI的总线ID号
数据类型:number
取值范围:0/1
是否必选:必须传入此参数;
注意事项:目前合宙模组的硬件SPI的总线ID只有0/1
参数示例:--如下所示,参数0就是初始化sfud时的spi_id
local result = sfud.init(0,8,20 * 1000 * 1000)
log.info("Flash初始化结果:", result)
spi_cs
参数含义:SPI总线的CS片选引脚编号
数据类型:number
取值范围:根据自己的电路设计选择对应的GPIO编号
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下所示,参数8就是初始化sfud时的spi_cs
local result = sfud.init(0,8,20 * 1000 * 1000)
log.info("Flash初始化结果:", result)
spi_bandrate
参数含义:SPI总线的波特率
数据类型:number
取值范围:Air780EXX系列和Air8000系列模组可取值:2000000,4042105,
4096000,4151351,4208219,4266666,4326760,4388571,4452173,4517647,
4585074,4654545,4726153,4800000,4876190,4954838,5036065,5120000,
5206779,5296551,5389473,5485714,5585454,5688888,5796226,5907692,
6023529,6144000,6269387,6400000,6536170,6678260,6826666,6981818,
7144186,7314285,7492682,7680000,7876923,8084210,8302702,8533333,
8777142,9035294,9309090,9600000,9909677,10240000,10593103,10971428,
11377777,11815384,12288000,12800000,13000000,13356521,13963636,
14628571,15360000,16168421,17066666,18070588,19200000,20480000,
21942857,23630769,25600000
Air8101/6101可取值:2000000,4083333,4454545,4900000,5444444,6125000,7000000,
8166666,9800000,12250000,16333333,24500000,49000000
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下所示,参数20*1000*1000就是初始化sfud是的spi_bandrate
local result = sfud.init(0,8,20 * 1000 * 1000)
log.info("Flash初始化结果:", result)
返回值
local result = sfud.init(spi_id, spi_cs, spi_bandrate)
有一个返回值 result
result
含义说明:初始化sfud是否成功;
成功返回true,否则返回false
数值类型:boolean
取值范围:true/false;
注意事项:初始化失败时,需做好对应逻辑处理,比如重新初始化,或者换下述4.2章节方式2初始化
返回示例:例如返回true表示初始化sfud成功
示例
local result = sfud.init(0,8,20 * 1000 * 1000)
--log打印 I/user.Flash初始化结果: true
log.info("Flash初始化结果:", result)
4.2 sfud.init(spi_device)
功能
初始化 sfud 方式 2,以 spi 对象的方式初始化 sfud
注意事项
参数 spi_device 是用对象方式初始化 SPI 获取,即 spi.deviceSetup()接口的返回值,详细参考 SPI-API-4.6 章节。
参数
spi_device
参数含义:以对象方式设置并启用硬件SPI返回的SPI对象
数据类型:userdata
取值范围:userdata类型的SPI对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--如下所示,初始化的spi对象spi_device 就是初始化sfud时的spi_device
local result = sfud.init(spi_device)
--log打印 I/user.Flash初始化结果: true
log.info("Flash初始化结果:", result)
返回值
local result = sfud.init(spi_device)
有一个返回值 result
result
含义说明:初始化sfud是否成功;
成功返回true,否则返回false
数值类型:boolean
取值范围:true/false;
注意事项:初始化失败时,需做好对应逻辑处理,比如关闭SPI;
返回示例:例如返回true表示初始化sfud成功
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--初始化 sfud
local result = sfud.init(spi_device)
--log打印 I/user.Flash初始化结果: true
log.info("Flash初始化结果:", result)
4.3 sfud.getDeviceTable()
功能
获取 flash 设备数组地址
注意事项
因为 sfud 只支持挂载 1 个设备,所以只会返回一个 userdata 类型的数据结构
参数
无
返回值
local sfud_device = sfud.getDeviceTable()
有一个返回值 sfud_device
sfud_device
含义说明:获取flash设备信息表;
成功时返回一个userdata类型的flash设备信息表实例对象,
实际上返回预留的luatos表地址
是固定静态数组直接编译进去,不会失败
实例对象名称并不是固定的sfud_device,可自定义
数值类型:userdata/nil
取值范围:无特别限制
注意事项:sfud挂载文件系统以及读写、擦除、获取flash大小等接口参数是用的这个返回值或者sfud.getDevice的返回值,获取失败时,注意其他接口的使用影响。
返回示例:例如返回 userdata: 0C0E0328 表示获取flash设备信息表成功
示例
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
local result = sfud.init(spi_device)
local sfud_device = sfud.getDeviceTable()
--log打印 I/user.获取flash设备信息表: userdata: 0C0E0328
log.info("获取flash设备信息表:", sfud_device)
4.4 sfud.getDeviceNum()
功能
获取 flash 设备信息表中的设备总数
注意事项
暂无
参数
无
返回值
local sfud_int = sfud.getDeviceNum()
有一个返回值 sfud_int
sfud_int
含义说明:获取flash设备信息表中的设备总数;
成功返回设备总数,失败返回nil
数值类型:number/nil
取值范围:固定值1
注意事项:因为sfud只支持挂载1个设备,成功只会返回1
返回示例:返回1表示当前总共有1个flash设备
示例
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
local result = sfud.init(spi_device)
local sfud_int = sfud.getDeviceNum()
--log打印 I/user.获取flash设备信息表中的设备总数: 1
log.info("获取flash设备信息表中的设备总数:", sfud_int )
4.5 sfud.getDevice(index)
功能
通过 flash 信息表中的索引获取 flash 设备
注意事项
暂无
参数
index
参数含义:flash信息表中的索引
数据类型:number
取值范围:0
是否必选:必须传入此参数;
注意事项:因为sfud只支持挂载1个设备,索引从0开始。
参数示例:--如下所示,参数0就是获取flash信息表的index值,获取第一个flash设备
local sfud_device_ud= sfud.getDevice(0)
--log打印 I/user.获通过flash信息表中的索引获取flash设备: userdata: 0C0E0328
log.info("获通过flash信息表中的索引获取flash设备:", sfud_device_ud)
返回值
local sfud_device_ud= sfud.getDevice(index)
有一个返回值 sfud_device_ud
sfud_device_ud
含义说明:获取flash设备信息;
成功时返回一个userdata类型的flash设备信息表实例对象,
实际上返回预留的luatos表地址
是固定静态数组直接编译进去,不会失败
数值类型:userdata/nil
取值范围:无特别限制
注意事项:sfud挂载文件系统以及读写、擦除、获取flash大小等接口参数是用的这个接口或者sfud.getDeviceTable接口的返回值,获取失败时,注意其他接口的使用影响。
返回示例:例如返回userdata: 0C0E0328表示获取flash设备成功
示例
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
local result = sfud.init(spi_device)
local sfud_device_ud= sfud.getDevice(0)
--log打印 I/user.获通过flash信息表中的索引获取flash设备: userdata: 0C0E0328
log.info("获通过flash信息表中的索引获取flash设备:", sfud_device_ud)
4.6 sfud.mount(flash, mount_point, offset, maxsize)
功能
挂载 sfud lfs 文件系统
注意事项
如果已经用 sfud.mount 把整个 flash 挂载为文件系统,不支持再次挂载这个 flash 的一部分内存为文件系统。
参数
flash
参数含义:flash设备对象,即sfud.getDeviceTable()或者sfud.getDevice(index)返回的数据结构
数据类型:userdata
取值范围:userdata类型的flash设备对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:local sfud_device = sfud.getDeviceTable()
local mount_point = "/sfud_flash"
--如下所示,参数sfud_device就是挂载文件系统时的flash 参数
local mount_ok = sfud.mount(sfud_device, mount_point)
--log打印 I/user.挂载 sfud lfs文件系统:true
log.info("挂载 sfud lfs文件系统:", mount_ok)
mount_point
参数含义:flash挂载为文件系统的目录名
数据类型:string
取值范围:string类型的名称
是否必选:必须传入此参数;
注意事项:暂无
参数示例:local sfud_device = sfud.getDeviceTable()
local mount_point = "/sfud_flash"
--如下所示,参数mount_point就是挂载文件系统时的目录名
local mount_ok = sfud.mount(sfud_device, mount_point)
--log打印 I/user.挂载 sfud lfs文件系统:true
log.info("挂载 sfud lfs文件系统:", mount_ok)
offset
参数含义:起始偏移量,在flash的存储空间里,文件系统开始使用的位置,相对于flash起始地址的偏移值(单位为字节)
数据类型:number
取值范围:nil,0~(flash总大小-1),单位为字节
是否必选:非必须传入此参数;
注意事项:nil默认是0,注意_offset+_maxsize的结果不要超过总flash内存
如果已经把整个flash挂载为文件系统,不支持再次挂载这个flash的一部分内存为文件系统。
参数示例:local sfud_device = sfud.getDeviceTable()
local mount_point = "/sfud_flash"
--如下所示,挂载flash为文件系统,起始偏移量从4K开始
local mount_ok = sfud.mount(sfud_device, mount_point,4096,4096)
--log打印 I/user.挂载 sfud lfs文件系统:true
log.info("挂载 sfud lfs文件系统:", mount_ok)
maxsize
参数含义:指定给文件系统使用的flash存储空间的容量大小,单位为字节
数据类型:int
取值范围:nil,1~(总flash大小-_offset),单位为字节_
是否必选:非必须传入此参数;
注意事项:nil是整个flash,注意_offset+_maxsize的结果不要超过总flash内存
如果已经把整个flash挂载为文件系统,不支持再次挂载这个flash的一部分内存为文件系统。
参数示例:local sfud_device = sfud.getDeviceTable()
local mount_point = "/sfud_flash"
--如下所示,挂载flash为文件系统,指定给文件系统使用的flash存储空间的容量大小是4K
local mount_ok = sfud.mount(sfud_device, mount_point,4096,4096)
--log打印 I/user.挂载 sfud lfs文件系统:true
log.info("挂载 sfud lfs文件系统:", mount_ok)
返回值
local mount_ok = sfud.mount(flash, mount_point, offset, maxsize)
有一个返回值 mount_ok
mount_ok
含义说明:挂载为文件系统;
成功时返回true,否则返回false
数值类型:boolean
取值范围:true/false
注意事项:挂载失败时,需做好对应逻辑处理,比如关闭SPI;
返回示例:例如返回true表示挂载文件系统成功
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
local result = sfud.init(spi_device)
local mount_point = "/sfud_flash"
local sfud_device = sfud.getDeviceTable()
--挂载整个flash为文件系统
local mount_ok = sfud.mount(sfud_device, mount_point)
--log打印 I/user.挂载 sfud lfs文件系统:true
log.info("挂载 sfud lfs文件系统:", mount_ok)
--查询根文件系统信息 依次返回 操作是否成功 总块数 已用块数,块大小 类型 I/user.fsstat true 128 4 4096 lfs
log.info("fsstat", io.fsstat("/"))
--查询挂载的文件系统信息 依次返回 操作是否成功 总块数 已用块数,块大小 类型 I/user.fsstat true 2048 10 4096 lfs
log.info("fsstat", io.fsstat(mount_point))
4.7 sfud.erase(flash,addr,size)
功能
擦除 flash 指定地址指定大小,按照 flash block 大小进行擦除
注意事项
addr + size
的结果不能超过 flash 的总容量。flash 擦除是 “整块擦除”,哪怕你只想擦除一小部分,也会实际擦除整个块,因此要提前规划擦除区域,避免误删其他数据。
参数
flash
参数含义:flash设备对象,即sfud.getDeviceTable()或者sfud.getDevice(index)返回的数据结构
数据类型:userdata
取值范围:userdata类型的flash设备对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:local sfud_device = sfud.getDeviceTable()
--如下所示 sfud_device就是擦除操作时sfud.erase的flash参数
local erase_ok=sfud.erase(sfud_device , erase_addr, erase_size)
--log打印 I/user.擦除一个块的数据: 0
log.info("擦除一个块的数据:",erase_ok)
addr
参数含义:操作擦除的起始地址
数据类型:number
取值范围:0~flash总大小,按照flash block的倍数取值
是否必选:必须传入此参数;
注意事项:addr + size 的结果不能超过 flash 的总容量.
注意块对齐,按照flash block的倍数取值,不同flash块大小不一样,比如常见的有4KB、32KB、64KB 等,
例如:块大小为 4KB 时,add 取值为 0、4096、8192… 这类能被 4096 整除的地址。
可以使用io.fsstat获取flash的block size,具体参考[io-api-4.6章节](https://docs.openluat.com/osapi/core/io/#46-iofsstatpath)
参数示例:-- 擦除起始地址(示例值,需根据需求调整)
local erase_addr = 4096
-- 擦除大小(示例值,需匹配 Flash block 大小)
local erase_size = 4096
local sfud_device = sfud.getDeviceTable()
--如下所示 erase_addr就是擦除操作时sfud.erase的_addr_参数
local erase_ok=sfud.erase(sfud_device , erase_addr, erase_size)
--log打印 I/user.擦除一个块的数据: 0
log.info("擦除一个块的数据:",erase_ok)
size
参数含义:需要擦除的flash容量大小
数据类型:number
取值范围:0~flash总大小,按照flash block的倍数取值
是否必选:必须传入此参数;
注意事项:add + size 的结果不能超过 flash 的总容量.
size 建议也是 “块大小” 的整数倍(例如:块大小为 4KB 时,size 可以是 4096、8192…)。
因为addr取块大小的整数倍,flash 擦除是 “整块擦除”,
哪怕你只想擦除一小部分,也会实际擦除整个块,
因此要规划擦除区域大小,避免误删其他数据
参数示例:-- 擦除起始地址(示例值,需根据需求调整)
local erase_addr = 4096
-- 擦除大小(示例值,需匹配 Flash block 大小)
local erase_size = 4096
local sfud_device = sfud.getDeviceTable()
--如下所示 erase_size就是擦除操作时sfud.erase的_size_参数
local erase_ok=sfud.erase(sfud_device , erase_addr, erase_size)
--log打印 I/user.擦除一个块的数据: 0
log.info("擦除一个块的数据:",erase_ok)
返回值
local erase_ok=sfud.erase(flash,add,size)
有一个返回值 erase_ok
erase_ok
含义说明:flash块擦除;
成功时返回0,失败时返回错误码
0 success
1 not found or not supported
2 write error
3 read error
4 timeout error
5 address is out of flash bound
数值类型:number
取值范围:无特别限制
注意事项:flash特性要求是先擦除再写入,如果擦除失败,会影响后续写入。
返回示例:例如返回0表示擦除成功
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--初始化sfud
local result = sfud.init(spi_device)
-- 擦除起始地址(示例值,需根据需求调整)
local erase_addr = 4096
-- 擦除大小(示例值,需匹配 Flash block 大小)
local erase_size = 4096
local sfud_device = sfud.getDeviceTable()
local erase_ok=sfud.erase(sfud_device , erase_addr, erase_size)
--log打印 I/user.擦除一个块的数据: 0
log.info("擦除一个块的数据:",erase_ok)
4.8 sfud.chipErase(flash)
功能
擦除 Flash 全部数据
注意事项
暂无
参数
flash
参数含义:flash设备对象,即sfud.getDeviceTable()或者sfud.getDevice(index)返回的数据结构
数据类型:userdata
取值范围:userdata类型的flash设备对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:local sfud_device = sfud.getDeviceTable()
--如下所示 sfud_device就是擦除操作时sfud.chipErase的flash参数
local erase_ok=sfud.chipErase(sfud_device)
--log打印 I/user.擦除flash全部数据: 0
log.info("擦除flash全部数据:",erase_ok)
返回值
local erase_ok=sfud.chipErase(flash)
有一个返回值 erase_ok
erase_ok
含义说明:擦除 Flash 全部数据;
成功时返回0 失败时返回错误码
0 success
1 not found or not supported
2 write error
3 read error
4 timeout error
5 address is out of flash bound
数值类型:number
取值范围:无特别限制
注意事项:flash特性要求是先擦除再写入,如果擦除失败,会影响后续写入。
返回示例:例如返回0时表示擦除成功
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--初始化 sfud
local sfud_flash_device = sfud.init(spi_device)
--获取flash对象
local sfud_device = sfud.getDeviceTable()
local erase_ok=sfud.chipErase(sfud_device)
--log打印 I/user.擦除flash全部数据: 0
log.info("擦除flash全部数据:",erase_ok)
4.9 sfud.read(flash, addr, size)
功能
读取 flash 指定位置开始的指定长度的数据
注意事项
addr + size
的结果不能超过 flash 的总容量。
参数
flash
参数含义:flash设备对象,即sfud.getDeviceTable()或者sfud.getDevice(index)返回的数据结构
数据类型:userdata
取值范围:userdata类型的flash设备对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下方所示,sfud_device就是读取数据的flash参数
local sfud_device = sfud.getDeviceTable()
log.info("sfud.read",sfud.read(sfud_device,1024,4))
addr
参数含义:读取数据的起始地址,单位字节
数据类型:number
取值范围:0~flash总大小
是否必选:必须传入此参数;
注意事项:addr + size 的结果不能超过 flash 的总容量
参数示例:-- 读取数据起始地址(示例值,需根据需求调整)
local addr = 4096
-- 读取数据的长度(示例值,需根据需求调整)
local size = 4096
local sfud_device = sfud.getDeviceTable()
--如下方所示,从4096字节位置开始读取数据
log.info("sfud.read",sfud.read(sfud_device,addr,size))
size
参数含义:从起始地址开始需要读取的数据的长度大小
数据类型:number
取值范围:0~flash总大小
是否必选:必须传入此参数;
注意事项:addr + size 的结果不能超过 flash 的总容量
参数示例:-- 读取数据起始地址(示例值,需根据需求调整)
local erase_addr = 4096
-- 读取数据的长度(示例值,需根据需求调整)
local size = 4096
--如下方所示,从4096字节位置开始读取4096字节的数据
log.info("sfud.read",sfud.read(sfud_device,addr,size))
返回值
local read_str=sfud.read(flash, addr, size)
有一个返回值 read_str
read_str
含义说明:从指定位置开始读取指定长度的数据;
成功时返回读到的数据;失败时返回错误码
0 success
1 not found or not supported
2 write error
3 read error
4 timeout error
5 address is out of flash bound
数值类型:string
取值范围:无要求
注意事项:暂无
返回示例:例如返回"testdata"表示读取数据成功
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--初始化 sfud
local sfud_flash_device = sfud.init(spi_device)
--获取flash对象
local sfud_device = sfud.getDeviceTable()
-- 读取数据起始地址(示例值,需根据需求调整)
local addr = 4096
-- 读取数据的长度(示例值,需根据需求调整)
local size = 4096
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
log.info("写入数据:", sfud.write(sfud_device , addr, data))
local read_str=sfud.read(sfud_device , addr, size)
--log打印 I/user.读取到的数据:testdata
log.info("读取到的数据:",read_str)
4.10 sfud.write(flash, addr,data)
功能
向 flash 写数据
注意事项
data 长度 +addr 的结果不能超过 flash 的总容量。
参数
flash
参数含义:flash设备对象,即sfud.getDeviceTable()或者sfud.getDevice(index)返回的数据结构
数据类型:userdata
取值范围:userdata类型的flash设备对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:-- 写入数据起始地址(示例值,需根据需求调整)
local addr = 4096
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
--如下方所示,sfud_device就是读取数据的flash参数
log.info("写入数据:", sfud.write(sfud_device , addr, data))
addr
参数含义:写数据的起始地址
数据类型:number
取值范围:0~flash总大小
是否必选:必须传入此参数;
注意事项:data长度+addr 的结果不能超过 flash 的总容量
参数示例:-- 写入数据起始地址(示例值,需根据需求调整)
local addr = 4096
local data = "testdata"
--如下方所示,从4096字节位置开始写入数据
log.info("写入数据:", sfud.write(sfud_device , addr, data))
data
参数含义:从起始地址开始需要写入的数据
数据类型:string
取值范围:string数据长度可取值0~flash总大小
是否必选:必须传入此参数;
注意事项:data长度+addr 的结果不能超过 flash 的总容量
参数示例:-- 写入数据起始地址(示例值,需根据需求调整)
local addr = 4096
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
--如下方所示,从4096字节位置开始写入数据
log.info("写入数据:", sfud.write(sfud_device , addr, data))
返回值
local write_ok=sfud.write(flash, addr, data)
有一个返回值 write_ok
write_ok
含义说明:从指定位置开始写入指定数据是否成功;
成功时返回0,失败时返回错误码
0 success
1 not found or not supported
2 write error
3 read error
4 timeout error
5 address is out of flash bound
数值类型:umber
取值范围:无特别要求
注意事项:暂无
返回示例:例如0表示写入成功
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--初始化 sfud
local sfud_flash_device = sfud.init(spi_device)
--获取flash对象
local sfud_device = sfud.getDeviceTable()
--写数据起始地址(示例值,需根据需求调整)
local addr = 4096
--待写入的数据(示例值,需根据需求调整)
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
--log打印 I/user.写入数据: 0
log.info("写入数据:", sfud.write(sfud_device , addr, data))
4.11 sfud.eraseWrite(flash, addr,data)
功能
先按照 flash block 大小进行擦除再往 flash 写数据,
注意事项
data长度+addr 的结果不能超过 flash 的总容量。flash 擦除是 “整块擦除”,哪怕你只想擦除一小部分,也会实际擦除整个块,因此要提前规划擦除区域,避免误删其他数据。
参数
flash
参数含义:flash设备对象,即sfud.getDeviceTable()或者sfud.getDevice(index)返回的数据结构
数据类型:userdata
取值范围:userdata类型的flash设备对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:-- 操作数据起始地址(示例值,需根据需求调整)
local erase_addr = 4096
--待写入的数据(示例值,需根据需求调整)
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
--如下方所示,sfud_device就是读取数据的flash参数
log.info("先擦除再写入数据:", sfud.eraseWrite(sfud_device , erase_addr, data))
addr
参数含义:操作数据的起始地址
数据类型:number
取值范围:0~flash总大小
是否必选:必须传入此参数;
注意事项:data长度+addr 的结果不能超过 flash 的总容量。
注意块对齐,按照flash block的倍数取值,不同flash块大小不一样,比如常见的有4KB、32KB、64KB 等,
例如:块大小为 4KB 时,add 取值为 0、4096、8192… 这类能被 4096 整除的地址。
可以使用io.fsstat获取flash的block size,具体参考[io-api-4.6章节](https://docs.openluat.com/osapi/core/io/#46-iofsstatpath)
参数示例:-- 操作数据起始地址(示例值,需根据需求调整)
local erase_addr = 4096
--待写入的数据(示例值,需根据需求调整)
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
--如下方所示,从4096字节位置开始擦除并写入数据
log.info("先擦除再写入数据:", sfud.eraseWrite(sfud_device , erase_addr, data))
data
参数含义:待写入的数据
数据类型:string
取值范围:无特别要求
是否必选:必须传入此参数;
注意事项:data长度+addr 的结果不能超过 flash 的总容量。
参数示例:-- 操作数据起始地址(示例值,需根据需求调整)
local erase_addr = 4096
--待写入的数据(示例值,需根据需求调整)
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
--如下方所示,从4096字节位置开始擦除并写入数据
log.info("先擦除再写入数据:", sfud.eraseWrite(sfud_device , erase_addr, data))
返回值
local erwrite_ok=sfud.eraseWrite(flash, addr, data)
有一个返回值 erwrite_ok
erwrite_ok
含义说明:从指定位置开始擦除并写入指定数据是否成功;
成功时返回0 ,失败时返回错误码
0 success
1 not found or not supported
2 write error
3 read error
4 timeout error
5 address is out of flash bound
数值类型:number
取值范围:无特别限制
注意事项:暂无。
返回示例:例如返回0表示擦除并写入成功
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--初始化 sfud
local sfud_flash_device = sfud.init(spi_device)
--获取flash对象
local sfud_device = sfud.getDeviceTable()
--操作数据起始地址(示例值,需根据需求调整)
local erase_addr = 4096
--待写入的数据(示例值,需根据需求调整)
local data = "testdata"
local sfud_device = sfud.getDeviceTable()
--log打印 I/user.先擦除再写入数据:0
log.info("先擦除再写入数据:", sfud.eraseWrite(sfud_device , erase_addr, data))
4.12 sfud.getInfo(flash)
功能
获取 flash 容量和 page 大小
注意事项
“page” 指的是 Flash(闪存)的 “页”。
多个 page(页) 组成一个 block(块)
一个 block 包含的 page 数量 由芯片设计决定(比如 1 个 block 可能包含 16、32 甚至上百个 page)
- page 是 Flash “读写操作” 的最小单位(读 / 写数据时,必须以 “整页” 为单位);
- block 是 Flash “擦除操作” 的最小单位(擦除数据时,必须以 “整块” 为单位)
参数
flash
参数含义:flash设备对象,即sfud.getDeviceTable()或者sfud.getDevice(index)返回的数据结构
数据类型:userdata
取值范围:userdata类型的flash设备对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:local sfud_device = sfud.getDeviceTable()
--如下方所示,sfud_device就是读取数据的flash参数
log.info("获取 Flash 容量和page大小:", sfud.getInfo(sfud_device ))
返回值
local get_flash,get_page =sfud.getInfo(flash)
有两个返回值 get_flash 和 get_page
get_flash
含义说明:获取flash容量,单位是字节
成功时返回flash容量的值 ,失败时返回错误码
0 success
1 not found or not supported
2 write error
3 read error
4 timeout error
5 address is out of flash bound
数值类型:number,非负整数
取值范围:flash容量大小,非负整数
注意事项:暂无
返回示例:例如返回8388608表示flash的容量是8388608字节。
get_page
含义说明:获取flash的page页大小,单位字节
成功时返回页大小的值 ,失败时返回错误码
0 success
1 not found or not supported
2 write error
3 read error
4 timeout error
5 address is out of flash bound
数值类型:number,非负整数
取值范围:flash的page页大小,非负整数
注意事项:暂无
返回示例:例如返回4096表示flash的页大小是4096字节
示例
--以对象方式设置并启用硬件SPI
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--初始化 sfud
local sfud_flash_device = sfud.init(spi_device)
--获取flash对象
local sfud_device = sfud.getDeviceTable()
--log打印 I/user.获取flash 容量和page大小: 8388608 4096
log.info("获取 Flash 容量和page大小:", sfud.getInfo(sfud_device ))
五、产品支持说明
Air780EPM 不支持 sfud 核心库,Air700ECH/Air780EHN/EHU/EHM/EHV/EGH/Air8000 全系/Air8101/6101, 支持 sfud 核心库。