2. 系统FLASH硬件写保护功能
本章主要介绍如何将系统flash的代码与资源区域设置为写保护状态。分为以下几个部分:
2.1. A0芯片配置系统flash写保护说明
- A0芯片配置系统flash写保护的步骤如下:
1、将用户使用的系统flash的写保护参数添加到下载目录的csv表格。(具体说明对应小节:添加系统flash写保护参数与指令)
2、将csv表格通过flash写保护工具转换成成dir文件(具体说明对应小节:flash写保护工具说明),并且作为资源文件下载到系统flash中(下载步骤具体说明对应小节:写保护参数下载说明)。
3、开启SDK的系统flash写保护功能,观察打印是否出现写保护配置成功的提示。(具体说明对应小节:程序中开启与关闭写保护功能)
2.1.1. 添加系统flash写保护参数与指令
如下对于A0的芯片,用户可自行根据需要使用的flash的datasheet,在flash_wp_info.csv文件中添加写保护参数以及相关指令,下文以华邦W25Q32 FLASH为例,介绍根据手册添加参数。
2.1.1.1. Flash SR1、SR2寄存器和写保护范围
在flash datasheet中,可通过查找关键字“BP1”快速找到SR1寄存器,查找关键字“LB1”快速找到SR2寄存器;
检查SR1寄存器中是否有SEC、TB、BP2、BP1、BP0位,检查SR2寄存器是否有CMP位;
![]()
![]()
图2.4 flash SR1与SR2寄存器
通过查找关键字“Density”快速搜索写保护列表,并查看flash支持的写保护范围。
![]()
![]()
图2.5 flash写保护范围
2.1.1.2. 如何添加flash写保护参数
打开flash_wp_info.csv文件并根据3.1.1中的信息填写参数,我司配置flash写保护范围从0地址开始,向后覆盖。
表格找到上一组flash数据空两至三行后,在第一行填写flash标号、flash id以及写使能(Write Enable)指令。
![]()
flash标号、ID以及写使能指令信息
第二行开始填写flash写保护参数,最大支持9组flash写保护参数。
通过保护范围的大小,设置SEC、TB、BP0、BP1、BP2(不同的flash SEC和TB标识可能是其它,如BP4、BP3)和CMP的值。
例如:当CMP = 0时,SEC TB BP2 BP1 BP0为0b01101,可保护000000h - 0fffffh范围内1MB的数据。
![]()
图2.7 flash写保护范围填写说明1
当CMP = 1时,SEC TB BP2 BP1 BP0为0b00001,可保护000000h - 3effffh范围内4032KB的数据。
![]()
图2.8 flash写保护范围填写说明2
2.1.1.3. flash读写SR1、SR2指令
Flash配置写保护时,需要读写SR1、SR2 寄存器。查找手册找到读写SR1、SR2的指令,并填入表格中。
如果datasheet上有31H命令,优先使用分开写SR1、SR2模式;
![]()
图2.9 flash 分开写SR1和SR2寄存器指令
若上述分开写SR1、SR2模式在芯片运行中添加写保护不成功,则使用01H指令连续写SR1、SR2模式;
![]()
图2.10 flash 连续写SR1和SR2寄存器指令
部分Flash不存在SR2寄存器,则无需写SR2相关指令。
![]()
图2.11 flash只读写SR1寄存器指令
2.1.2. flash写保护工具说明
- SDK的下载目录(路径:apps\app\post_build\bd49\mbox_flash\)中存放有“flash_write_protect”文件夹,文件夹中包含以下文件:
flash_wp_info.csv:该文件以文本形式记录各种flash的写保护参数
csv2dir.bat:该脚本实现将上述csv文件转成小机可识别的dir_sys_info文件
![]()
图2.1 flash写保护工具
其中,flash_wp_info.csv文件中涵盖了内封系统flash的部分型号。对于A0芯片,用户可自行根据使用的flash型号datasheet添加相应的写保护参数以及指令。
添加完成后,点击csv2dir.bat脚本,即可生成dir_sys_info文件,将该文件放在下载目录中,添加到download.bat的资源文件中下载到小机中,小机即可识别并添加写保护。
运行csv2dir.bat脚本时,需要注意是否有执行成功。
![]()
图2.2 csv2dir.bat脚本执行成功显示信息
没有执行成功时,需要关注错误信息,重新修改flash_wp_info.csv文件;下图的错误信息显示同时存在两组相同的flash写保护参数。
![]()
图2.3 csv2dir.bat脚本执行失败显示信息
2.1.3. 写保护参数下载说明
添加好写保护参数后,根据2.1的说明执行脚本生成dir_sys_info文件,并将其添加到SDK资源列表中,小机通过路径搜索找到该文件并进行解析。
![]()
图2.12 download_bat.c中将dir_sys_info添加到资源列表中
![]()
图2.13 小机识别flash写保护信息文件路径
2.2. 内封系统flash芯片(即非A0芯片)配置系统flash写保护说明
AW30N支持新的内封系统flash写保护策略,固件API接口与AD18一致,isd_config.ini、download.bat配置发生变化,具体请参考文档:OTP_CFG(VOTP)区域配置说明
- 玩具系列支持新的内封flash写保护策略的芯片:
玩具系列支持写保护策略的芯片
AD18N、AW30N
- 内封系统flash芯片(即非A0芯片)配置系统flash写保护的步骤如下:
1、获取系统flash的写保护参数,通过配置下载目录,并下载到芯片。具体请参考文档`OTP_CFG(VOTP)区域配置说明 <https://doc.zh-jieli.com/Tools/zh-cn/dev_tools/toolchains/otp_cfg.html>`
2、开启SDK的系统flash写保护功能,观察打印是否出现写保护配置成功的提示。(具体说明对应小节:程序中开启与关闭写保护功能)
2.3. 程序中开启与关闭写保护功能
SDK中默认会在内置flash初始化的最后,配置flash写保护状态。
![]()
图2.1 SDK中添加写保护位置
2.3.1. 相关函数说明
2.3.1.1. 函数int norflash_set_write_protect(u8 enable_write_protect)
- 该函数实现开启或关闭系统flash写保护功能,其中参数:
- Enable_write_protect
1:开启写保护
0:关闭写保护
- 返回值
开启写保护成功:写保护的最大地址(即flash的0~返回值这块区域保护);
关闭写保护成功/开启写保护失败:
- 失败问题原因分析步骤:
1.开写保护打印(在app_config.c里EEPROM区的打印打开);2.检查打印,如果没有任何打印直接返回0,则用户直接跳到步骤3;如果只打印写保护失败打印,则跳到步骤4;如果打印寄存器值和失败打印,则跳到步骤53.写保护参数没有放进flash当中,用户可以按照文档逐步操作:4.如果使用的是A0芯片,确认自己使用的系统flash写保护参数是否在csv烧写文件里;确认app.bin + 资源文件少于对应flash的最小保护区域,用户可以在下载目录里加一些无用的资源文件,观察写保护的区域是否出现变化。5.把flash手册和打印信息保存联系深圳办或者钉钉开源群联系开发人员。
2.3.1.2. 函数int norflash_write_protect_config(struct device *device, u32 addr, struct flash_wp_arg *p)
- 该函数实现配置flash写保护范围,其中参数:
device:设备句柄,传NULL即可;
addr:写保护截止范围,传代码资源区后的地址;
p:flash写保护参数;
- 返回值:
开启写保护成功:写保护最大地址;
关闭写保护成功/开启写保护失败:0
2.3.1.3. 函数u16 norflash_read_sr1_sr2(void)
该函数实现获取系统flash的Status Register 1和Status Register 2寄存器,其返回值高8位为SR2,低8位为SR1;
2.3.1.4. 函数u32 flash_code_protect_callback(u32 offset, u32 len)
该函数实现软件上限制驱动操作系统flash(存放代码的flash).
系统flash进行写或擦除操作前会回调该函数,判断会操作到代码与资源区域,则不进行相应操作;
- 可减低程序跑飞导致程序意外擦写flash的概率。其中参数:
offset:设备进行写或擦除操作的地址
len:设备进行写或擦除操作的长度
- 返回值:
开启写保护成功:写保护最大地址;
关闭写保护成功/开启写保护失败:0
2.3.2. 常见问题说明
2.3.2.1. 系统flash保护csv文件说明(A0芯片使用)
用户需要了解写保护参数文件的一些相关意思:
1. 芯片flash型号2. 芯片flash_id3. flash的最小保护区域![]()
csv文件简单了解
2.3.2.2. 写保护失败
写保护失败现象有三:
1. 打印直接返回0,没有写保护失败打印;2. 打印返回0,有写保护失败(set write protect fail);3. 打印返回0,有相关寄存器配置和写保护失败打印(set write protect fail);写保护失败原因有三(一一对应上面失败现象):
1. 写保护参数没有烧写到系统flash当中;2. 系统flash的最小写保护区域大于app.bin + 资源文件,涉及到了VM区域就会写保护失败;3. 某些系统flash配置特殊,需要找开发人员协助;