沁恒 RISC-V 蓝牙芯片 FLASH 操作以及分区管理 ...... 矜辰所致
...... 更新更大容量 CH584x 芯片部分                   2025/12/3

前言

要合理使用一块芯片,熟悉其内部 Flash 的分区管理是必不可少的。

本文我们说明一下沁恒 RISC-V 蓝牙芯片 Flash 的分区以及读写操作。

我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

一、 Flash 分区

本文以 CH585 芯片为例,其他芯片都可根据手册和代码确定,方法在文中会有说明。

1.1 基本分区介绍

在官方的芯片手册《CH585DS1》文档中,第一页芯片介绍的时候就有说明:

在这里插入图片描述

在文档第 2 章《系统结构及存储器》 2.3 小结也有表格说明:

在这里插入图片描述

本文我们讨论的是 Flash 存储器区域,对应的映射地址是:0x0000 0000 —— 0x0007 FFFF 的部分。

其他系列的芯片手册也有明显的标注,可以自行查看。

针对上面的的官方说明,我绘制了一张图示说明:

在这里插入图片描述

目前来说 CH585 在沁恒微 32 位 RISC-V 里面此系列芯片中 Flash 和 SRAM 是最大的了,除了另一个带以太网接口的 CH32V208 系列达到 480K Flash。
更新: CH584x 最大 ,480+24+512 K RAM 96 K

InfoFlash 区域保存了一些出场信息,类似 芯片 ID 、RF 频偏、LDO 校准等等信息,不建议改(虽然手册上提示部分区域可以配置)。

BootLoader 区域官方的 BootLoader 主要用来做产品 ISP 下载升级的工作,产品能够 USB 下载,串口下载,串口免按键下载全靠它了。

DataFlash 和 CodeFlash 就是官方帮客户区分好的 Flash 区域,一个区域用来放代码,一个区域用来放掉电保存的数据。在工程中对两个区域操作的函数也不一样,这个在本文后面会有测试说明。

要明确知道的是,它们和上面两块区域本质上是都是同一块 Flash 区域,只是官方为了方便应用,自己划分了开了不同的区域。 理论上,用户是可以自己区分的,只不过官方的示例和很多软件是配合了这个分区开发使用的,这里并不建议开发者胡来。

1.2 BLE 应用使用区域

应用区域即便是同一芯片不同版本的 EVT 可能会有调整,随着系列芯片的不断推出,需要做一些兼容,以官网最新为例,在应用上用户是可以自行修改的。

上面的0x0007 0000 ~ 0x 0007 8000 区,即 DataFlash 区是留给客户保存数据的部分,但是如果使用蓝牙应用,蓝牙配对,Mesh 组网,OTA 升级等的数据也被保存在这部分区域,用户需要注意一下如果使用到对应的部分功能自己的数据不要和这些数据重叠了,当然用户也可以自己修改地址存放,直接在程序中修改宏定义即可 。

这里我们也用一张示意图来说明一下:

再次提醒一下,下图区域为 Flash 的0x0007 0000 ~ 0x 0007 8000 区域。不同芯片的地址可能有区别,具体的可查看代码中的定义。

在这里插入图片描述

上面这些区域的划分在代码中都有体现的,只是刚学习的时候,很容易搞不清楚。

大家可以自己打开工程查看,比如在主机工程中的CONFIG.h 文件中(这个文件怎么快速找到,通过某些通用的宏定义跳转就过来了,比如#if(defined(BLE_MAC)) && (BLE_MAC == TRUE) 中的 BLE_MAC),有关于 BLE 配对绑定信息存储区域的宏定义如下:

在这里插入图片描述

如果使用蓝牙 Mesh,在配网发起者例程provisioner_vendor 中的app_mesh_config.h 中有关于 Mesh 网络信息存储区域的宏定义如下:

在这里插入图片描述

在带有 OTA 功能的工程中 ota.h 中有 OTA 标志位存放的地址:

在这里插入图片描述

这里特别说明,上面 BLE_SNV_ADDROTA_DATAFLASH_ADD 重复了,是因为确实博主目前手头的 EVT 包就是这样的,写错了,已经和沁恒微工程师反馈确认。 但为什么我上面写出图表说明,是因为和沁恒微工程师请教过,默认 DataFlash 应用就是上图那么区分。只是后来出了不同的芯片做兼容,可能一下忽略了,但是沁恒微的 FAE 响应速度还是很快的, 相信很快就能改正 。

二、 FLASH 读写

那了解了 Flash 的分区,我们来学习一下 Flash 的读写操作。

这个官方提供了现成的示例:

在这里插入图片描述

先跑一遍示例,再来看后面,读写数据太简单了,大家自己过一遍即可。

2.1 函数说明

库函数把操作 DataFlash 和 CodeFlash 的函数做了区分。

DataFlash 操作(带 EEPROM 名字):


  • EEPROM_READ(StartAddr,Buffer,Length)
  • 擦除
    EEPROM_ERASE(uint32_t StartAddr, uint32_t Length)

  • EEPROM_WRITE(StartAddr,Buffer,Length)

CodeFlash 操作(带 FLASH_ROM 名字):


  • FLASH_ROM_READ(uint32_t StartAddr, void *Buffer, uint32_t len)
  • 擦除
    FLASH_ROM_ERASE(StartAddr,Length)

  • FLASH_ROM_WRITE(StartAddr,Buffer,Length)
  • 校验
    FLASH_ROM_VERIFY(StartAddr,Buffer,Length)

2.2 Flash 操作注意事项

  • 首先是大家跑示例会发现读取 Codeflash ,擦除后读出来并不是 0xFF,这是正常的,MCU内核有加解密。
    在这里插入图片描述

  • Codeflash 最小擦除单位为 4096字节。

  • DataFlash 操作函数的地址参数都是基于 0x70000 的 基地址的偏移,比如EEPROM_READ(0, TestBuf, 500); 就是从Flash 地址为0x70000 的位置读取数据。

  • DataFlash 最小擦除单位为 256字节(CH585)。

  • 操作 Flash 的函数,在库中已包含失能/恢复中断 ,无需应用层代码再添加。

  • 写 Flash之前一定要擦除,不论是 DataFlash 还是 CodeFlash

  • 操作 CodeFlash ,地址,长度,buffer 长度,都按 4 字节的整数倍!!!
    不按照4字节出问题的情况太多了= =!

  • 操作 DataFlash 相对要求没那么严格,在 CH585 上是可以 1 字节操作的,我做了个测试:
    在这里插入图片描述
    但是官方建议4字节对齐,考虑到通用性和移植, 地址还是建议 4 字节对齐。

根据官方的宏,列了个表格:

概念 官方宏 数值 分区 备注
Page(页) EEPROM_PAGE_SIZE 256 B
Block(块) EEPROM_BLOCK_SIZE 4096 B
Data-Flash 最小擦除 EEPROM_MIN_ER_SIZE 256 B Data 区 可单页擦,也可整块擦 (CH585)
Code-Flash 最小擦除 注释里说明 4096 B Code 区 只能用4 KB (页)擦
最小写粒度 EEPROM_MIN_WR_SIZE 1 B Data 区 实际硬件仍 4 B 对齐,库自动补
最小写粒度 FLASH_MIN_WR_SIZE 4 B Code 区 必须 4 B 倍数,否则 HardFault

2.3 擦写时间和寿命

这部分直接在官方芯片手册的最后 参数 章节里有说明,沁恒 RISC-V内核的 CH5Xx 蓝牙 MCU 此处参数相差不大。

在这里插入图片描述
注: 上面文字中的 “扇区” 即为 Block(块)4096 字节。

三、 其他相关说明

本小节作为补充内容,记录一下一些特别型号的说明,保持持续更新…

3.1 CH592A 和 CH584X

CH592A 和 CH584X 的 Dataflash 和 CodeFlash 擦除单位都为 4K !
所以他们的 DataFlash 中 Ble 配对绑定数据存储地址为 0x7 7000 ,偏移 0x7000

更新:
CH584x芯片
Flash:480K(codeflash) +24K(BootLoader )+512K(dataflash)
RAM :96 K

3.2 连续操作 Flash 的场景

我们知道,操作 Flash 函数会自动关闭中断,那么在实际应用中,什么场景下可能会因为关闭中断导致问题呢?

下面说明引用沁恒微官方电子社区:

无线库中连续操作 flash 的场景,只有 mesh 组网中会出现:一块 SNV 扇区存满,整理/搬移 dataflash 的网络信息时,根据信息的碎片化程度,可能会连续操作 2+s,那么如果还同时连接上了 BLE 且超时时间协商 <2s,会断连。跑 mesh+BLE,可以把 BLE 的超时时间拉长点,整理 flash 期间丢几个包后还可以继续交互 BLE 连接事件。
.
BLE和2.4GRF场景下,在“配对”时会存储对端设备的一些信息到dataflash中,但字节长度不大,且发生在连接期间,不影响连接后的运行。

如何安排 Flash 操作以尽可能避免和蓝牙任务冲突?

应用层添加 flash 代码,可以将大面积的 flash 操作分散处理,让 BLE 连接事件有足够的时间可以穿插执行。
.
如果无法避免连续操作数K字节 flash 的场景,有两种思路调整 BLE 配置:

  1. (常用处理)在操作flash前,重新协商连接参数,加大连接间隔及连接超时时长。连接间隔拉长到>操作flash的事件开销,能不丢包是最好。flash操作完成后再次协商连接参数,还原。
  2. (有待测试)配置latency参数,允许BLE从机能够忽略N个连接事件。比较适用于BLE键盘的场景,帮助BLE键盘在没有按键按下时降低功耗,有按键时又可以及时上传。理论可行,有待测试的区别点是:BLE键盘是“主动忽略”连接事件;连续擦写flash场景下,MCU是“被动忽略”连接事件。

结语

本文主要给大家介绍了 CH585 芯片的内存分布,读写操作。

东西并不复杂,但是切记要牢记注意事项,这里建议大家在以后应用中,只要是 Flash 写操作都按照 4 字节对齐来操作,避免不必要的麻烦。

好了,本文就到这里。谢谢大家!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐