1. VM 掉电存储说明
- 下面分为4个部分来介绍VM的基本原理与特点:
1.1. VM 记忆的基本原理
SDK提供了 vm掉电记忆存储功能 ,该功能用于在 内置flash里保存断电之后还需要保存的信息。
1、VM会将自己所分得的内部FLASH区域划为A,B两块区域,
2、例如A区域负责记录VM数据,B区域此时处于空闲状态,当A区域数据趋于饱和时,会把A区域的数据整合到B区域(即格式整理),后续B区域记录VM数据,A区域处于空闲状态,以此往复。
3、若此时格式整理后,A区域原有数据没有被擦除(未调用擦除函数)
4、用户去读取数据,会读取到原有区域的数据(即旧数据),导致数据错误或者读不到数据。
1.2. VM 记忆的系统局限性
VM的数据记忆主要记录到系统flash中,系统flash中存放着整个系统的代码,大量的代码需要在系统flash中执行;
VM的数据记忆过程中有可能需要对系统flash进行擦除操作;
系统flash在被擦除时不可以被访问,且不同的flash擦除时间不一致;
基于以上几点 当VM触发到系统flash擦除时,这时系统flash代码是不能执行的 ,典型的现象就是 解码卡音。
为了优化上述的问题,编写新的NEW VM驱动,在一定程度上改善此问题。
1.3. NEW VM的预擦除
为了解决解码时,擦除系统flash可能导致的卡音,new vm尽量不在系统繁忙时对系统flash进行擦除;
new vm提供了预擦除函数nvm_pre_erasure_next,可以在系统空闲时对系统flash当前与空闲区进行 提前预擦除、或 滞后擦除;
new vm的写函数在AB区格式整理时,也不会对老区域进行擦除,而依赖预擦除在空闲时擦除;(未擦除再次上电会有老数据残留风险)
1.4. NEW VM常见BUG
部分客户在使用NEW VM,自己编写功能中,遗忘或者未能合理调用预擦除功能导致,数据不能有效更新;
此问题有两种解决方式:
1、在写入数据后,系统掉电或关机前,调用预擦除;(推荐)
2、打开config_vm_erasure_after_format_en变量,打开此变量后,new vm驱动会在需要擦除时实时擦除系统flash,这样一来NEW VM驱动的行为将和老的VM一直,不再具备对卡音问题的优化;
1.5. VM 掉电存储使用说明
- VM记忆存储使用的步骤分为三步:
第一步:系统初始化时,调用函数vm_init_api()初始化VM功能。
第二步:使用vm_write()接口把需要保存的数据写入FLASH。
第三步:使用vm_read()接口读取写入的数据。
可参考”VM简单使用demo:”
1.6. VM 掉电存储版本简单说明
目前SDK中VM有新旧两个版本可以选择:
备注
旧版VM功能:
可存储id号数量:128个;
单次写入最大数据长度:128个byte;
没有cache管理;
没有预擦除功能;
备注
新版VM功能
可存储id号数量:512个;
单次写入最大数据长度:4096个byte;(若EEPROM分配给VM区域只有8K,则单次写入最大数据长度为:4092个byte);
增加cache管理,提升读取速度;
增加预擦除功能。
备注
新旧版本VM功能对比:
新版VM id号数量增多;
新版VM 单次写入最大数据长度增多;
新版VM 增加cache管理,提升VM读取速度;
新版VM 增加预擦除功能,可以在系统空闲时进行预擦除操作,可尽可能避免VM整理时关闭flash时间过长导致的卡音问题;
新版ID号 与 旧版index句柄 含义相同;
1.7. 新旧VM文件组成及版本选择
vm模块由vm_api.c和vm_api.h文件构成API层,包含ovm_api.c和nvm_api.c文件;
备注
在SDK 为 AD14/15/AC104的v1.7.0版本(包括1.7.0版本)以前版本,用户可在 vm_api.h 文件里选择使用新 / 旧版VM.
新旧VM功能选择
备注
在SDK 为 AD14/15/AC104的v1.7.0版本以后,vm配置选项更改位置,用户可在 app_config.h 文件里选择使用新 / 旧版VM.
新旧VM功能选择
1.8. VM相关参数介绍
对于新版VM
1.8.1. ID号(vm_api.h)
vm_write参数
重要
旧版VM ID号最多128个,新版VM ID号最多512个;(旧版VM index号在新版vm仍可通用)
新版VM ID号最多支持512个,且不再需要自定义对应ID的数据长度。
用户可在vm_api.h的VM_INDEX里添加自己的id号。
注意: 1~32号ID为系统使用,用户不可修改其顺序
旧版VM掉电存储记忆项的定义(vm_api.h)
1.8.2. 读/写入数据长度
vm_write参数length
重要
旧版VM读/写长度最多支持128个byte;
新版VM读/写长度最多支持4096个byte;
1.8.3. vm存储区域大小
重要
VM记忆的数据 是 EEPROM区划分出一定空间大小给VM使用,该区域大小可由下载目录里的isd_config.ini文件配置。 (该配置参数详细说明可参考”isd_config.ini文件介绍”)
- 注意:
VM存储区域大小分配的EEPROM空间不得低于8K字节,且需为4K字节的倍速,即8K,12K,16K等等。
VM区域大小设置”
1.8.4. 新版VM格式整理时缓存空间设置new_vm_buff(new_vm.h)
重要
new_vm_buff,该buff用于vm格式整理时数据的缓存。
该buff由 用户自定义最大id数量(BIT_MAP_SIZE) + 单个id在整理时数据缓存的最大长度(BIT_MAX_LEN) 两部分组成。
BIT_MAP_SIZE :即BIT_MAP:vm最多可以存储的id数量,固定为512个。
BIT_MAX_LEN :即VM格式整理时数据缓存的大小,该值越大,则整理速度越快,该值越小,则整理速度越慢。(注意:该buf与读/写数据最大长度为两个概念)
VM掉电存储记忆项的定义(nvm_api.c和new_vm.h)
1.8.5. 新版vm格式整理后是否立即擦除旧半区区域功能
config_vm_erasure_after_format_en
config_vm_erasure_after_format_en 用于控制新版vm格式整理后是否立即擦除旧半区区域;0 : 不立即擦除(默认值)1 : 立即擦除
重要
该功能直观影响为:打开该功能后,vm进行格式整理 会 调用到flash擦除,如果系统此时正在解码,那么解码可能会出现卡音的现象。
而默认关闭该功能后,vm进行格式整理 不会 调用到flash擦除,而是等到 系统空闲时程序员调用预擦除函数进行擦除动作 ,这样就不会影响到系统此时正进行的解码。
关闭该功能后,未在系统空闲时进行擦除动作,那么可能导致下次上电,VM读取到老旧的数据。
1.8.6. 新版vm是否支持多段读功能
config_vm_multiple_read_en
config_vm_multiple_read_en 用于控制新版vm是否支持多段读功能;0 : 不支持多段读(默认值)1 : 支持多段读
1.9. VM掉电记忆存储接口
1.9.1. 函数u32 syscfg_vm_init(u32 addr, u32 size)
- 此函数用来初始化vm虚拟存储系统,其中参数:
eeprom_saddr:vm区域的起始地址。
eeprom_size:vm区域的空间长度。
- 返回值:
成功:0;失败:错误号,可参考errno-base.h;
1.9.2. 函数u32 vm_write(u32 id,u8 *buf,u32 len)
- 此函数用来把对应hdl的数据存储到vm虚拟存储系统,其中参数:
hdl:访问vm的id。
buf:vm读数据buffer。
len:数据长度。
- 返回值:
成功:写入长度;失败:错误号,可参考errno-base.h;
1.9.3. 函数u32 vm_read(u32 id ,u8 *buf,u32 len)
- 此函数用来把对应hdl的数据从vm虚拟存储系统读出来,其中参数:
id:访问vm的id。
buf:vm读数据buffer。
len:数据长度。
- 返回值:
成功:写入长度;失败:错误号,可参考errno-base.h;
1.9.4. 函数 u32 vm_pre_erase(void)
此函数用于预擦除设备,在系统空闲时主动调用提前擦除flash,可尽量避免VM做整理时关flash时间过长导致卡音问题;该函数只有在新版VM处生效,旧版VM没有该功能。示例:音乐模式下,500MS消息来时若系统处于空闲状态,则会进行预擦除动作:图2.1 系统空闲预擦除动作
1.9.5. 函数 nvm_pre_erasure_next(NEW_VM_OBJ *p_nvm, u16 using_next, u16 idle_next)
此函数为NEW VM中独有接口,由2.4 函数 u32 vm_pre_erase() 调用,用于系统空闲时选择擦除当前VM已存储的数据往后的flash扇区,以及空闲VM需要往后擦除的flash扇区数,用户可自行修改需要擦除的flash扇区数,其中参数:
1、p_nvm:NEW VM句柄指针; 2、using_next:当前VM存储块需要往后擦除的flash扇区数; 3、idle_next:空闲VM存储块需要往后擦除的flash扇区数; 4、返回值:无
1.10. VM常见问题介绍
1.10.1. VM简单使用demo:
用户可在app/bsp/start/flash_init.c里的vm_init_api()函数找到demo示例。
vm_demo
1.10.2. 调整VM区域大小设置:
节省VM占用系统空间可以从两个地方入手:
- 减少VM区域大小。
具体参考上面”vm存储区域大小”章节的 vm存储区域大小 部分
- 新版VM可以减少VM格式整理时的缓存new_vm_buff
可以适当减少BIT_MAX_LEN的长度。
具体参考上面”新版VM格式整理时缓存空间设置new_vm_buff(new_vm.h)”章节的 新版VM格式整理时缓存空间设置 部分。
1.10.3. 新版VM在关机或者掉电后可能存在数据丢失BUG:
该问题原因可能有:
AD14v1.7.0、v1.8.0 voice_toy工程 app_ld.c文件缺少(*.data)段(优先排查);
解决办法: FAQ:AD14v1.7.0、v1.8.0 voice_toy工程new_vm存在掉电后读取数据错误问题?
系统在关机前格式整理后没有做预擦除动作。
1.10.4. VM格式整理原理:
VM格式整理原理:
VM功能将EEPROM区域划分为A、B两块,A块记录VM数据,B块处于空闲状态,当A块数据接近饱和时,会擦除B块并将A块的数据整合到B块,后续B块记录VM数据,A块处于空闲状态,以此往复。