前言

概述

本文档主要针对WS63V100中NV存储模块的使用进行介绍。用于指导工程人员能够快速使用NV模块进行二次开发。

产品版本

与本文档相对应的产品版本如下。

产品名称

产品版本

WS63

V100

读者对象

本文档主要适用于以下工程师:

  • 技术支持工程师

  • 软件工程师

符号约定

在本文中可能出现下列标志,它们所代表的含义如下。

符号

说明

表示如不避免则将会导致死亡或严重伤害的具有高等级风险的危害。

表示如不避免则可能导致死亡或严重伤害的具有中等级风险的危害。

表示如不避免则可能导致轻微或中度伤害的具有低等级风险的危害。

用于传递设备或环境安全警示信息。如不避免则可能会导致设备损坏、数据丢失、设备性能降低或其它不可预知的结果。

“须知”不涉及人身伤害。

对正文中重点信息的补充说明。

“说明”不是安全警示信息,不涉及人身、设备及环境伤害信息。

修改记录

文档版本

发布日期

修改说明

05

2025-02-28

更新“NV项汇总”章节。

04

2024-10-14

更新“编译生成NV镜像”小节内容。

03

2024-05-30

  • 更新“功能描述”小节内容。
  • 更新“接口说明”小节内容。

02

2024-05-07

更新“接口说明”小节内容。

01

2024-04-10

第一次正式版本发布。

  • 更新“功能描述”小节内容。
  • 更新“接口说明”小节内容。
  • 更新“开发指引”小节内容。

00B02

2024-03-29

新增“NV项汇总”章节。

00B01

2024-01-10

第一次临时版本发布。

NV简介

NV模块用于本地存储器中存储非易失性数据。NV中的每项数据以类似key-value的方式进行定义,数据项中包含唯一的索引key和自定义数据类型的value。

NV项可通过两种方式进行存储:编译预置和API写入。

  • 编译预置是指开发者可在代码编译阶段,通过修改NV头文件和NV配置文件的方式生成客制化的NV镜像,在镜像烧录的过程中统一烧录到存储介质中。预置的NV在代码运行阶段可通过API接口进行读取和更新。

  • API写入是指用户可直接在代码中调用API接口写入新的NV项,具体使用方法请参见“NV API指南”。

NV编译预置

编译预置的方式不支持加密NV项的生成。如需写入加密NV项,必须使用API接口。

新增NV项

新增NV项流程

  1. 在头文件中新增kvalue的数据类型定义(非必须,如果是通用类型数据可忽略此步骤)。

  2. 在json文件中新增NV描述项。

新增kvalue数据类型

  • 通用数据类型:

    unit8_t、unit16_t、unit32_t、bool。

  • 自定义数据类型:

    支持自定义枚举(enum)类型和结构体(struct)类型。

  • 自定义数据类型存放路径:

    middleware/chips/ws63/nv/nv_config/include/nv_common_cfg.h

  • 当用户使用通用或已定义的数据类型时,不涉及上述文件的修改;当用户要新增枚举或结构体类型时,需在上述文件中定义。

新增NV描述项

  • NV描述项文件路径:

    middleware/chips/ws63/nv/nv_config/cfg/acore/app.json

  • 定义说明:

    表 1 NV配置选项说明

    NV配置选项

    说明

    key_id

    NV项的ID。

    key_status

    NV项的状态。

    structure_type

    NV项的数据结构类型。

    attributions

    NV项的属性值。

    value

    NV项的数据。

    图 1 NV配置文件示例

    在NV的配置中,每个字段的详细描述如下:

    • key_id:

      以十六进制形式给出的NV项ID。key_id必须唯一,不能重复,因此建议用户在“key_id.h”中预留的用户区间内取值,避免不同模块使用NV互相影响。

    • key_status:

      用于标记是否将该项的NV值编到生成的bin文件中。该字段为“alive”,表示NV项生效,当前固件版本正在使用此key;若为其他的字段或空,则不生效。

    • structure_type:

      NV项的数据类型。已在“新增kvalue数据类型”中详细描述。

    • attributions:NV项属性值。1 、2、4为互斥关系,三选一。

      1:Normal nv(普通NV,可修改)。

      2:Permanent nv(不可修改)。

      4:Un-upgrade nv(不随版本升级而修改)。

    • value:

      如果value不是上述通用数据类型,任何结构都必须以列表的形式书写,有如下两种情况:

      • 列表所有成员全部赋值。

      • 只对列表前面若干个成员赋值。这表明对末尾未赋值的成员缺省赋值为0。

新增NV项示例

  • 在“middleware/chips/ws63/nv/nv_config/include/nv_common_cfg.h”文件中新增自定义结构体。新增自定义数据类型示例如下:

    • 新增结构体类型且结构体内都为基础类型:

      typedef struct {
          int8_t param1;
          int8_t param2;
          int8_t param3;
          int8_t param4;
          int8_t param5;
          uint32_t param6;
          uint32_t param7;
          int32_t param8;
          uint32_t param9;
          uint32_t param10;
          uint32_t param11;
          uint32_t param12;
          uint32_t param13;
          uint32_t param14;
          uint32_t param15;
          uint32_t param16;
          uint32_t param17;
      } sample_type_t;
      
    • 新增结构体类型且结构体内有数组类型:

      typedef struct {
          uint16_t param1; 
          uint16_t param2; 
          uint16_t param3;
          uint16_t param4[2];
      } sample_two;
      
    • 新增枚举类型:

      typedef enum {
          PARAM1,
          PARAM2,
          PARAM3,
          PARAM4
      } sample_three;
      
  • 在“middleware/chips/ws63/nv/nv_config/cfg/acore/app.json”文件中添加新的NV项。

    • 当kvalue预置值类型是基础类型时,添加kvalue预置值如图1所示,可在“app.json”配置文件直接添加,无需在头文件中新增。

      图 1 添加基础类型kvalue预置值

    • 当kvalue预置值类型是结构体类型时,添加kvalue预置值如图2所示,该kvalue值要对应头文件中已有的结构体,如果没有需手动添加自定义结构体。

      图 2 添加结构体类型kvalue预置值

编译生成NV镜像

须知: 使用build.py编译非boot目标,如ws63-liteos-app、ws63-liteos-xts等时,会默认编译生成NV镜像并打包,打包时默认仅包含ws63_all_nv.bin,不包含ws63_all_nv_factory.bin,若需打包ws63_all_nv_factory.bin,可在编译命令中加入额外参数进行打包,例如:“python3 build.py -c ws63-liteos-app -def=PACKET_NV_FACTORY;”。

在全量编译时自动生成NV镜像,如图 build_nvbin.py脚本执行成功所示即为成功,即可在输出路径下生成“ws63_all_nv.bin”文件,可直接烧录使用。

输出路径:output\ws63\acore\nv_bin\ws63_all_nv.bin

图 1 build_nvbin.py脚本执行成功

NV API指南

功能描述

NV 当前支持存储最多16K(存在管理结构体占用空间,实际略小于16K)数据,备份分区大小与NV主区一致,总计占用32K flash 空间,API主要提供以下几种功能:

  • NV项写入:

    保存需要存储的格式化数据。除普通属性的NV外,还可以设置NV项是否永久存储、是否加密存储和是否不可升级。

  • NV项读取:

    从本地存储器读取NV数据。

  • NV信息查询:

    • 查询NV是否已存储于本地存储器中。

    • 查询NV空间的使用状态。

  • NV数据备份

    • 对NV数据进行备份,仅在退出产测模式时会自动进行备份,不接受手动备份。

  • NV数据恢复

    • 对NV数据进行恢复,可实现全量和部分恢复。

NV项的写入接口可设置NV项的属性,对于通过API动态添加的NV项,可在其写入的接口中传入其所拥有的特殊属性。

须知: NV数据写入flash不可避免的会增加flash的擦写次数,消耗flash寿命,甚至缩短产品使用年限。因此,一定要避免频繁写入NV数据。电池类产品设备,运行数据不会丢失,建议只在关机前写入要保存的NV数据,减少数据写入次数

接口说明

使用NV接口需要引用NV接口头文件,路径:include/middleware/utils/nv.h

NV模块主要提供以下API:

errcode_t uapi_nv_write(uint16_t key, const uint8_t *kvalue, uint16_t kvalue_length)

uapi_nv_write

写入NV数据项,默认属性Normal,无回调函数,写入成功时返回ERRCODE_SUCC,其他返回错误码。

key

要写入的NV项的key ID,用于索引。

*kvalue

指向要写入的NV项的值的指针。

kvalue_length

写入数据的长度,单位:Byte。对于非加密NV项,支持最大值为4060;加密NV项为4048。

errcode_t uapi_nv_write_with_attr(uint16_t key, const uint8_t *kvalue, uint16_t kvalue_length,nv_key_attr_t *attr, nv_storage_completed_callback func)

uapi_nv_write_with_attr

写入NV数据项,并根据业务需求配置属性及回调函数,写入成功时返回ERRCODE_SUCC,其他返回错误码。

key

要写入的NV项的key ID,用于索引。

*kvalue

指向要写入的NV项的值的指针。

kvalue_length

写入数据的长度,单位:Byte。对于非加密NV项,支持最大值为4060;加密NV项为4048。

*attr

要配置的NV项的属性。

func

kvalue写入Flash后调用的回调函数。当前不支持。

errcode_t uapi_nv_read(uint16_t key, uint16_t kvalue_max_length, uint16_t *kvalue_length, uint8_t *kvalue)

uapi_nv_read

读取指定NV数据项的值,默认不获取key的属性值,读取成功时返回ERRCODE_SUCC,其他返回错误码。

key

要读取的NV项的key ID,用于索引。

kvalue_max_length

*kvalue指向空间所能存储数据的最大值,单位:Byte。

*kvalue_length

实际读取到的数据长度。

*kvalue

指向保存读取数据的buffer的指针。

errcode_t uapi_nv_read_with_attr(uint16_t key, uint16_t kvalue_max_length, uint16_t *kvalue_length,uint8_t *kvalue, nv_key_attr_t *attr)

uapi_nv_read_with_attr

读取指定NV数据项的值,同时获取key的属性值,读取成功时返回ERRCODE_SUCC,其他返回错误码。

key

要读取的NV项的key ID,用于索引。

kvalue_max_length

*kvalue指向空间所能存储数据的最大值,单位:Byte。

*kvalue_length

实际读取到的数据长度。

*kvalue

指向保存读取数据的buffer的指针。

*attr

获取到的NV项的属性。

errcode_t uapi_nv_get_store_status(nv_store_status_t *status)

uapi_nv_get_store_status

获取NV存储空间使用情况,获取成功时返回ERRCODE_SUCC,其他返回错误码。

*status

指向保存NV状态数据的指针。

errcode_t uapi_nv_set_restore_mode_all(void);

uapi_nv_set_restore_mode_all

设置NV全量恢复出厂标记,备份成功时返回ERRCODE_SUCC,其他返回错误码。

说明:该接口可实现备份区全部数据的恢复,工作区内没有进行备份数据将会被删除,即全量恢复后工作区和备份区的内容完全一致,调用后不会立即恢复,将在重新启动后进行恢复操作。

errcode_t uapi_nv_set_restore_mode_partitial(const nv_restore_mode_t *restore_mode);

uapi_nv_set_restore_mode_partitial

设置NV部分恢复出厂标记,设置成功时返回ERRCODE_SUCC,其他返回错误码。

*restore_mode

指向恢复标记结构体的指针。

通过控制恢复标记结构体内region_mode数组中的标记为0或者1,实现对指定的region区的数据恢复出厂。

说明:该接口可实现将备份区内指定region的数据恢复到工作区,标记为0的region区的数据将会保留工作区原数据,标记为1的region区内的数据恢复为备份区的数据(注:该region区域内未备份的数据将会被删除),调用后不会立即恢复,将在重新启动后进行恢复操作。

表 1 region区域划分表

恢复区域

key_id

region_0

[0x0001,0x1000)

region_1

[0x1000,0x2000)

region_2

[0x2000,0x3000)

region_3

[0x3000,0x4000)

region_4

[0x4000,0x5000)

region_5

[0x5000,0x6000)

region_6

[0x6000,0x7000)

region_7

[0x7000,0x8000)

region_8

[0x8000,0x9000)

region_9

[0x9000,0xA000)

region_10

[0xA000,0xB000)

region_11

[0xB000,0xC000)

region_12

[0xC000,0xD000)

region_13

[0xD000,0xE000)

region_14

[0xE000,0xF000)

region_15

[0xF000,0xFFFF)

说明:

  • NV恢复出厂时,最小单位为一个region区,不支持进行单独NV项的恢复。

  • “uapi_nv_set_restore_mode_all”和“uapi_nv_set_restore_mode_partitial”两个函数仅是设置NV恢复出厂的标记,实际恢复出厂的操作需要在复位设备后执行。

开发指引

下述为NV读写接口的使用指引。API调用处以加粗突出。

  1. 写入默认Normal类型NV。

    uint8_t *test_nv_value; /* 要写入的NV value保存在test_nv_value中 */
    uint32_t test_len = 15; /* 长度为test_len ,示例中为15*/
    uint16_t key = TEST_KEY; /* TEST_KEY 为该key的ID*/
    errcode_t nv_ret_value = uapi_nv_write(key, test_nv_value, test_len);
    if (nv_ret_value != ERRCODE_SUCC) {
        return ERRCODE_FAIL;
    }
    return ERRCODE_SUCC;
    
  2. 写入带属性NV(配置永久属性,其他略)。

    uint8_t *test_nv_value; /* 要写入的NV value保存在test_nv_value中 */
    uint32_t test_len = 15; /* 长度为test_len,例中为15 */
    uint16_t key = TEST_KEY;
    nv_key_attr_t attr = {0};
    attr.permanent = true;/* 永久属性设为true */
    attr.encrypted = false;
    attr.non_upgrade = false;
    errcode_t nv_ret_value = uapi_nv_write_with_attr(key, test_nv_value, test_len, &attr, NULL);
    if (nv_ret_value != ERRCODE_SUCC) {
        return ERRCODE_FAIL;
    }
    /* APP PROCESS */
    return ERRCODE_SUCC;
    
  3. 读取NV。

    uint16_t key = TEST_KEY;
    uint16_t key_len= test_len;
    uint16_t real_len= 0;
    uint8_t *read_value = malloc(key_len);
    if (read_value == NULL) {
        return ERRCODE_MALLOC;
    }
    if (uapi_nv_read(key, key_len, &real_len, read_value) != ERRCODE_SUCC) {
        /* ERROR PROCESS */
        uapi_free(read_value);
        return ERRCODE_FAIL;
    }
    /* APP PROCESS */
    free(read_value);
    return ERRCODE_SUCC;
    
  4. 读取NV及属性。

    uint16_t key = TEST_KEY;
    uint16_t key_len = test_len;
    uint16_t real_len = 0;
    uint8_t *read_value = malloc(key_len);
    nv_key_attr_t attr = {false, false, false, 0};
    ext_errno nv_ret = uapi_nv_read_with_attr(key, key_len, &real_len, read_value, &attr);
    if (nv_ret != ERRCODE_SUCC ) {
    
        uapi_free(read_value);
        return ERRCODE_FAIL;
    } 
    free(read_value);
    return ERRCODE_SUCC;
    

说明: 开发指引只是API接口的测试用例,为用户提供简单的sample参考,sample中省略了宏、部分变量、回调函数的定义过程和业务处理过程。

注意事项

  • uapi_nv_write:默认不对所存储的key添加额外属性(是否永久存储、是否加密存储等)。

  • uapi_nv_write_with_attr:可同时配置key属性和注册回调函数。在WS63V100中回调函数可以忽略,传NULL即可。

  • NV项存储在Flash中时,以Flash器件的sector为单位进行管理。NV页的数量默认配置为4页。对于4060Byte的sector,除去管理结构,单个非加密NV项的有效数据最大不应超过4060Byte。

  • NV属性结构体和NV空间状态结构体说明详见“nv.h”文件。

NV项汇总

NV_ID

NV 说明

NV value说明

0x3

保留NV项

N/A

0x4

保留NV项

N/A

0x5

MAC地址

MAC地址的6字节。

0x6

频偏温补开关

  • 0:关闭
  • 1:开启

0x7

频偏温补补偿值

细调补偿值,取值范围[-127,127],共8个值,对应补偿到温度区间[-40,-20), [-20,0), [0,20), [20,40),[40,60),[60,80),[80,100),[100,~)。

0x2003

国家码

  • 67:表示字符‘C’
  • 78:表示字符‘N’

0x2004

数采开关状态

  • 0:关闭状态
  • 1:开启状态

0x2005

漫游开关

  • 0:关闭漫游
  • 1:开启漫游

0x2006

11r开关

  • 0:开启over air
  • 1:开启over ds

0x2007

配置Wi-Fi 11ax TXBF能力位

  • 0:关闭
  • 1:开启

0x2008

配置Wi-Fi LDPC模式开关

  • 0:关闭
  • 1:开启

0x2009

配置Wi-Fi接收STBC特性开关

  • 0:关闭
  • 1:开启

0x200A

配置是否使能以HE ER SU格式发包

  • 0:开启SU配置
  • 1:关闭SU配置

0x200B

配置DCM发送能力开关

  • 0:不支持DCM
  • 1:BPSK
  • 2:QPSK
  • 3:16-QAM

0x200C

配置是否支持106-tone发包

  • 0:不支持
  • 1:支持

0x200D

配置Wi-Fi AMSDU小包聚合(<128Byte)的最大聚合个数。

支持配置范围:1~4。

0x200E

配置发送amsdu开关

  • 0:关闭
  • 1:开启

0x200F

配置ampdu+amsdu联合使能开关

  • 0:关闭
  • 1:开启

若关闭则仅能使用ampdu进行报文发送。

0x2010

配置Wi-Fi最大发送A-MPDU聚合报文数量

支持配置范围:2~32。

0x2011

配置Wi-Fi最大接收A-MPDU聚合报文数量

支持配置范围:1~32。

0x2012

配置聚合报文发送窗口大小

支持配置范围:2~64。

0x2013

最大user数量

支持范围1~6

0x2015

WiFi断连后不上报lwip

  • 0:上报
  • 1:不上报

0x2016

linkloss开关

  • 0:开启linkloss
  • 1:关闭linkloss

0x2018

跨协议探测开关

  • 0:关闭
  • 1:开启

默认开启跨协议探测

0x2019

配置er_su发送动态决策阈值

支持配置范围:1~32。

0x2050

射频插损

插损补偿值,精度1dB。

0x2051

射频校准开关

每bit表示一个校准项。

0x2052

射频数据开关

每bit表示一个数据项。

0x2053

大区功率配置FCC

根据国家码选择大区功率配置,参考软件开发指南的国家码功能配置。

0x2054

大区功率配置ETSI

根据国家码选择大区功率配置,参考软件开发指南的国家码功能配置。

0x2055

大区功率配置JAPAN

根据国家码选择大区功率配置,参考软件开发指南的国家码功能配置。

0x2056

大区功率配置通用

根据国家码选择大区功率配置,参考软件开发指南的国家码功能配置。

0x2057

RSSI补偿值

RSSI默认补偿值,单位:dB。

0x2058

校准参考功率

上电校准功率参考,单位:0.1dB。

0x2059

高功率拟合曲线默认值

拟合曲线系数。

0x205A

低功率拟合曲线默认值

拟合曲线系数。

0x205B

拟合曲线放大系数默认值

拟合曲线系数。

0x205C

校准数据

数据。

0x205D

认证开关

  • 0:关闭
  • 1:开启

0x20A0

BSLE最大功率档位

  • 若设置为7,可以使用的档位是0~7,每档对应-6、-2、2、6、10、14、16、20;
  • 若设置为3,可以使用的档位是0~3,每档对应-6、-2、2、6。

0x20A1

GOLDEN板开关

0:关闭

1:开启

默认关闭,仅golden板手动打开

0x20A4

BSLE第7档目标功率值

  • 默认值20
  • 若设置为20,每档对应-6、-2、2、6、10、14、16、20;
  • 若设置为22,每档对应-4、0、4、8、12、16、18、22。
  • 设置范围18~23

0x20A5

BSLE边带降功率开关

  • 默认值1
  • 若设置1,则开启边带降功率;
  • 若设置为0,则关闭边带降功率。

0x20A6

BSLE边带降功率信道

默认值:0,78,255,255,255,255,255,255

代表第0、78信道降功率,255表示不降功率,提供8个自定义降功率信道

0x20A7

BSLE边带降功率功率值

默认值:8,12,255,255,255,255,255,255

代表第0信道功率降到8dBm、第78信道功率降到12dBm,255表示不降功率,降功率需要和0x20A6配合使用,存在一一对应的关系。

0x20A8

调度排布间隔

默认值:8

payload传输发送时间+ifs+payload传输接收时间+ifs

设置范围:5~8

0x20A9

解调模式切换开关

默认值:0

0:差分维特比解调

1:差分解调

0x20AA

调度预排开关

默认值:1

  • 0:关闭调度预排
  • 1:打开调度预排

0x20AB

channel scan开关

默认值:1

  • 0:关闭channel scan
  • 1: 打开channel scan

0x2100~0x211F

雷达性能参数

靠近、存在、距离跟踪参数等,按照架高、敏感度、遮挡材料等情况的标定值。

0x2140

雷达控制参数

  • 架高

    0:1米

    1:2米

    2:3米

  • 敏感度

    0:一般

    1:更敏感

  • WIFI模式

    0:STA

    1:softAP

  • 遮挡材料

    0:无遮挡

    1:金属或PCB板遮挡

  • 融合距离跟踪

    0:不启用

    1:启用

  • 融合AI

    0:不启用

    1:启用