第4章:Flash编程操作
好,咱们今天聊聊Flash编程。说实话,这是很多工程师刚接触S32K3时最容易踩坑的地方。我自己带过好几个项目,每次看到有人把Page编程和Sector编程搞混,我就知道——嗯,得好好讲讲这个。
4.1 编程命令序列
S32K3的Flash编程,不是你想写就能写的。它有一套严格的命令序列。我刚开始做的时候也觉得麻烦,后来吃过亏才明白——这套机制是为了保护数据安全。
基本的编程流程是这样的:
- 解锁Flash:先写解锁序列,把Flash控制器从保护状态释放出来
- 配置时钟:确保Flash时钟频率在允许范围内,我一般设成80MHz
- 写入命令:把编程命令写到Flash控制器的命令寄存器
- 提供地址和数据:告诉控制器你要写哪里、写什么
- 启动命令:置位启动位,Flash控制器开始干活
- 等待完成:轮询状态寄存器,或者等中断通知你
- 校验结果:读回数据,确认写对了
核心要点:整个命令序列必须连续执行,中间不能被打断。我曾经见过有人在这中间插了个中断服务函数,结果Flash直接挂了——嗯,血的教训。
来看一段实际的代码:
/* Flash编程命令序列示例 */
void Flash_Program(uint32_t address, uint64_t data) {
/* 1. 等待前一个命令完成 */
while (FTFC->FSTAT & FSTAT_CCIF_MASK == 0);
/* 2. 解锁Flash */
FTFC->FSTAT = FSTAT_FCNFEF_MASK | FSTAT_FPVIOL_MASK |
FSTAT_ACCERR_MASK | FSTAT_RDCOLERR_MASK;
/* 3. 写入地址和数据 */
FTFC->FCCOB3 = (address >> 16) & 0xFF;
FTFC->FCCOB2 = (address >> 8) & 0xFF;
FTFC->FCCOB1 = address & 0xFF;
FTFC->FCCOB7 = (data >> 32) & 0xFFFFFFFF;
FTFC->FCCOB6 = data & 0xFFFFFFFF;
/* 4. 写入命令码并启动 */
FTFC->FCCOB0 = 0x06; /* Page编程命令 */
FTFC->FSTAT = FSTAT_CCIF_MASK;
/* 5. 等待完成 */
while (FTFC->FSTAT & FSTAT_CCIF_MASK == 0);
/* 6. 检查错误 */
if (FTFC->FSTAT & (FSTAT_FPVIOL_MASK | FSTAT_ACCERR_MASK)) {
/* 处理错误 */
}
}
4.2 Page编程与Sector编程的区别
这两个概念,说白了就是「写多少」的问题。我经常跟团队里的人说:选错了编程方式,性能差十倍不止。
| 特性 | Page编程 | Sector编程 |
|---|---|---|
| 编程单位 | 8字节(1 Page) | 4KB(1 Sector) |
| 典型耗时 | 约20-30μs | 约1-2ms |
| 适用场景 | 小数据更新、参数存储 | 批量数据写入、固件升级 |
| 擦除要求 | 目标地址必须已擦除 | 自动擦除(部分实现) |
| 中断影响 | 可中断 | 不可中断 |
Page编程:每次写8个字节。你想想看,如果你只是更新一个温度传感器的校准值,总共才4个字节,用Page编程最合适。我有个项目就是用它来存设备序列号的,每次上电读一次,运行中基本不动。
Sector编程:一次写4KB。这玩意儿适合大批量写数据。比如OTA升级时,一次下载几百KB的固件,用Sector编程效率高得多。但要注意——Sector编程期间不能响应中断,这个坑我踩过。
警告:千万不要在Page编程时跨Page边界!比如你从地址0x1000开始写8字节没问题,但从0x1005开始写——完蛋,数据会乱掉。我曾经帮一个客户排查过这个问题,查了三天才发现是地址没对齐。
4.3 编程时序
时序这东西,说白了就是「什么时候能干什么事」。S32K3的Flash编程时序有几个关键点:
- 命令启动时序:从写命令寄存器到启动位置位,必须在4个总线周期内完成
- 编程执行时间:Page编程约20μs,Sector编程约1.5ms(典型值)
- 恢复时间:编程完成后,需要等待约1μs才能进行下一次操作
我个人的习惯是:在编程前后各加一个小的延时,确保时序裕量。虽然数据手册说不需要,但实际项目中,电源波动、温度变化都会影响时序。
实战技巧:如果你用RTOS,建议把Flash编程放在一个独立的任务里,优先级设低一点。这样即使编程时间长,也不会影响关键任务的实时性。我在一个ADAS项目里就是这么干的,效果很好。
还有一个容易忽略的点:编程电压。S32K3的Flash编程需要内部升压到约10V。如果供电电压不稳,编程可能会失败。我建议在编程前检查一下电源状态,至少保证VDD在3.0V以上。
最后说一句:Flash编程不是天天都要做的事。大部分时间,你的代码只是在读Flash。但一旦需要写,就必须严格按照规范来。嗯,这就是为什么我把这部分放在课程前面——基础打牢了,后面才不容易翻车。