- 概述
最近有一些客户反馈,在产品中有时因为代码的问题导致 Flash 有一些固定部分被擦写掉,从而导致程序在运行中出现一些奇怪的问题,甚至变砖。为了避免在运行过程中出现这个问题,我们可以在 BootLoader 里面或者应用代码的开端处添加 Flash 锁定的功能,锁定一部分不用改变的 Flash 空间。以下就以 QN9080 为例。
- 功能分析
在需要实现这个功能时,我们首先要查阅 QN9080 的 UserManual,从里面查找相应的功能。在 UserManual 中的第28节中有关于 Flash 锁定与保护相关说明,如下图所示:
在 Flash 中有一段数据是用于锁定跟保护 Flash 的,地址中的一个 bit 对应一个最小保护单位 page(2KB)。Flash 总共有 512KB,分为两个 Block,一个 Block 大小为 256KB。所以总共有 32 个Byte数据用来操作每一个 page 的锁定情况,其中地址如下图所示:
其中可以看到,除了那32个 Byte 之外还有一个 Byte 用来表示配置 SWD 时的保护状态以及是否使能大规模擦除(mass erase)。其中 page erase lockbit 与后面 mass erase,flash protection 的在 SWD操作时以及代码运行时的真值表如下图所示:
SWD 操作:
代码运行时:
所以简单来说,我们要做的就是在代码运行之初或者直接在 Bootloader 中对这些 Flash 位置进行操作,从而达到对 Flash 的锁定与保护。
- 代码实现过程
接下来我们就基于 QN9080 的 Bootloader 代码来添加 Flash 的 page lockbit 的操作。
- 如下图所示,我们在 Flash 初始化之后添加 page lockbit 的操作,其中具体的函数 SDK 有提供,详情可以参考 c 文件。
其中结构体 user_lockbit.lockCtrl0~8 分别就是上述的33个Byte 数据内容,其中 user_lockbit.lockCtrl8 只有最低一个 Byte的数据有效,对应 0x7F820 的数据。其中我们设置user_lockbit.lockCtrl0 跟 user_lockbit.lockCtrl4 为 0xFFFFFFFC,即最低两位为0,分别对应将 Block0 以及 Block1 的开始各两个 Page 进行保护。所以换算下来就是 0x00~ 0x0FFF 以及 0x40000 ~ 0x40FFF 这8KB 数据进行锁定。
我们对 0x40000 之后的代码进行擦写的操作,分别在 0x40000 以及 0x41000 中写入 36 字节的数据,数据内容如下图所示:
- 注意事项
在本文中,我们展示的是在demo 的情况下来进行 Flash 的锁存操作,需要注意的是,在进行锁存的操作之后,后续任何 Flash 的擦写操作都是需要以一个 page 为单位进行擦除;除此之外在解锁对应的 page 后,该 page 会重置为 0xFF 的数据状态。后续如有其它注意事项,会在本文中或后续文章中添加,敬请期待。
- 参考文档
- UM11023 — QN908X user manual
- Cortex-M4 TRM — ARM Cortex-M4 Processor Technical Reference Manual
评论