跳转至

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 的开发难度。

注意:

  1. sfud 库不支持挂载 nand flash.如需挂载 nand flash,可以使用 lf 核心库。
  2. 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系列模组可取值20000004042105
40960004151351420821942666664326760438857144521734517647
45850744654545472615348000004876190495483850360655120000
52067795296551538947354857145585454568888857962265907692
60235296144000626938764000006536170667826068266666981818
71441867314285749268276800007876923808421083027028533333
87771429035294930909096000009909677102400001059310310971428
11377777118153841228800012800000130000001335652113963636
14628571153600001616842117066666180705881920000020480000
219428572363076925600000
Air8101/6101可取值:2000000408333344545454900000544444461250007000000
8166666980000012250000163333332450000049000000
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下所示,参数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表示当前总共有1flash设备

示例

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块大小不一样,比如常见的有4KB32KB64KB 等,
         例如:块大小为 4KB 时,add 取值为 040968192 这类能被 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 可以是 40968192…)。
         因为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块大小不一样,比如常见的有4KB32KB64KB 等,
         例如:块大小为 4KB 时,add 取值为 040968192 这类能被 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 核心库。