本次分享内容基于沁恒的芯片,型号为ch32v203c8t6。
一、什么是flash?
Flash(闪存)是一种非易失性存储技术,这意味着即使在断电的情况下,它也能保留存储的数据。
1.1 基本原理
Flash 基于 EEPROM(电可擦可编程只读存储器)技术发展而来,通过控制晶体管浮栅上的电荷来存储数据。当对浮栅注入或移除电荷时,晶体管的阈值电压会发生变化,以此来表示二进制的 “0” 和 “1”。
1.2 特点
非易失性:这是 Flash 最为重要的特性之一。与 RAM(随机存取存储器)不同,在设备断电后,Flash 中的数据不会丢失。这使得它非常适合用于长期数据存储,如存储操作系统、应用程序和用户数据等。
可擦除和重写:Flash 允许用户对存储的数据进行擦除和重新写入操作。不过,它的擦除操作通常是以块为单位进行的,而不是像 RAM 那样可以按字节进行随机访问和修改。
抗震性强:由于 Flash 没有像传统硬盘那样的机械部件(如盘片和磁头),因此它对震动和冲击具有很强的耐受性。这使得它在一些对稳定性要求较高的环境中得到广泛应用,如移动设备、工业控制和航空航天等领域。
读写速度差异:一般来说,Flash 的读取速度较快,但写入速度相对较慢。而且,随着使用时间的增加,Flash 的写入速度可能会进一步下降。
1.3 存储器映射表中的位置
备注:本次要操作的区域就是CodeFLASH。起始地址为:0x0800 0000。大小为224KB。
二、几种手册中常见的flash
1.1 System flash
1.1.1 基本概念
System Flash(系统闪存)是电子设备里的一种非易失性存储介质,它在设备运行过程中发挥着关键作用。System Flash属于非易失性存储器,即使设备断电,其所存储的数据也不会丢失。这一特性使得它非常适合用来保存设备启动和正常运行所必需的重要信息。
1.1.2 存储器映射表中的位置
1.1.3 主要功能
存储系统软件:用于存放设备的操作系统。例如,计算机的 Windows、Linux 系统,智能手机的 Android、iOS 系统等都存储在系统闪存中。设备启动时,会从这里加载操作系统到内存,然后操作系统开始运行并管理设备的各种资源。
保存固件程序:设备的固件也存储在系统闪存里。固件是一种特殊的软件,它为硬件提供底层的控制和支持,比如路由器的固件负责控制网络连接、数据转发等功能,智能手表的固件管理着显示、传感器数据处理等操作。
存储启动程序:包含设备的启动代码,也就是引导程序。当设备通电后,首先会运行引导程序,它的作用是初始化硬件设备,检测硬件状态,然后将操作系统加载到内存中,完成设备的启动过程。
2.1 Code flash
2.1.1 基本概念
“Code Flash” 通常指代码闪存,它是一种非易失性存储介质,在嵌入式系统和电子设备中扮演着至关重要的角色。
Code Flash 属于闪存(Flash Memory)的一种,非易失性意味着即便设备断电,其所存储的数据也不会丢失。它专门用于存储程序代码,为设备运行提供指令基础。
2.1.2 存储器映射表中的位置
2.1.3 主要功能
存储程序代码:这是 Code Flash 最核心的功能。它会存放嵌入式系统、微控制器、单片机等设备运行所需的程序代码。例如,在智能家居设备中,Code Flash 存储着控制设备各项功能(如开关控制、模式切换)的代码;在汽车电子控制单元(ECU)里,它存储着控制发动机、变速器等部件运行的代码。
支持设备启动:当设备上电启动时,系统会从 Code Flash 中读取启动代码,完成硬件初始化等操作,然后加载主程序到内存并开始执行,确保设备能正常开启并运行。
三、flash编程解读
3.1 标准flash编程测试
3.1.1 代码功能概述
主要功能是对芯片的闪存(Flash)进行编程测试,包括擦除指定范围内的闪存页、向擦除后的闪存区域写入数据,以及验证写入的数据是否正确。
3.1.2 第一步:解锁。
调用 FLASH_Unlock 函数来解锁闪存,因为在对闪存进行擦除和编程操作之前,需要先解锁才能进行写操作。
FLASH_Unlock();
3.1.3 第二步:读取原始数据
通过 for 循环,依次读取从地址 Fadr 开始的每个 32 位数据,并使用 printf 函数打印出每个地址及其对应的值。
for(i=0; i<Fsize; i++) {
printf("adr-%08x v-%08x\r\n", Fadr +4*i, *(u32*)(Fadr +4*i));
}
3.1.4 第三步:清除标志位。
计算要擦除的页数并清除闪存标志位。
(1)(结束地址 - 起始地址)/ (一页闪存尺寸) = 要擦除的页数。
(2)调用函数 FLASH_ClearFlag 清除各个标志位。
//清除各个标志位
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP |FLASH_FLAG_WRPRTERR);
3.1.4 第四步:擦除闪存页。
调用 FLASH_ErasePage 函数擦除指定地址的闪存页。
FLASH_ErasePage(xxx);
3.1.5 第五步:写数据
FLASH_ProgramHalfWord 函数以半字(16 位)为单位向闪存写入数据 Data,每次写入后地址增加 2 字节。
3.1.1.5 第四步:写数据
FLASH_ProgramHalfWord 函数以半字(16 位)为单位向闪存写入数据 Data,每次写入后地址增加 2 字节。
3.1.6 第六步:验证写入的数据
使用 while 循环,遍历写入数据的地址范围,通过指针读取闪存中的数据,并与要写入的数据 Data 进行比较。如果发现不相等的情况,将 MemoryProgramStatus 设置为 FAILED,表示写入验证失败。
while((当前地址 < 写入页结束地址) && (MemoryProgramStatus != FAILED))
{
if((*(__IO uint16_t*) Address) != 要写入的数据)
{
MemoryProgramStatus = FAILED;
}
Address += 2;
}
3.1.7 第七步:锁定闪存
调用 FLASH_Lock 函数锁定闪存,防止后续意外的写操作。
FLASH_Lock();
有需要源码的可翻主页,+qun。
如有侵权,联系删除。