S32K328的片上flash使用记录
本文介绍了基于S32K3_RTD_5_0_0 API对S32K328片上Flash的操作方法。Flash分为8KB UTEST、128KB Data Flash和8MB Code Flash三部分。读取使用C40_Ip_Read接口,支持数据比对验证。编程操作以64位为最小单位(8字节),最大支持128字节写入,需先解锁扇区。擦除最小单位为8KB扇区,同样需先解锁。常见错误包括HardFault_
如下所示说明,均使用 S32K3_RTD_5_0_0 版本的API接口操作;
1:S32K328的片上flash划分
总空间大小,8KB-UTEST + 128KB-data flash + 8MB-code flash
2:读取
使用 C40_Ip_Read 接口读取数据没有遇到什么问题;读完之后可以使用 C40_Ip_Compare 对比一下数据看看;
static int read_code_flash(rt_uint32_t offset, rt_uint8_t *buf, rt_size_t size)
{
int result = 0;
C40_Ip_StatusType c40_read_status=C40_IP_STATUS_ERROR;
rt_uint32_t addr = s32k328_onchip_code_flash.addr + offset;
{
c40_read_status = C40_Ip_Read(addr, size, buf);
if (C40_IP_STATUS_SUCCESS == c40_read_status)
{
result = size;
}
/* Compare data */
// if (C40_IP_STATUS_SUCCESS != C40_Ip_Compare(addr, size, buf))
// {
// result = FALSE;
// }
}
return result;
}
3:写入或编程
最小编址单位为 2 个字(64 位,8byte),数据必须 64 位对齐。最多可同时编程 4 页,1 页为 8 个字(256 位)。一次编程操作最多可以更改 1024 位(128byte)。
编程操作将位的逻辑值从 1 改为 0,这意味着不允许从 0 改为 1 的编程操作,并且在执行任何编程操作之前需要擦除 Flash 存储器。
在执行编程操作之前,必须先解锁包含指定地址的扇区。对锁定的扇区或超级扇区执行编程操作,操作会失败,并且 MCRS[PEP]位会报告错误。
注意:如果需要一次性写入>128byte数据,需要重新封装一下接口,内部自己做判断;
/* Unlock sector */
if (C40_IP_STATUS_SECTOR_PROTECTED == C40_Ip_GetLock(start_sector))
{
C40_Ip_ClearLock(start_sector, S32K328_C40_DOMAIN_ID_VALUE);
}
//TODO 下面可能会跨扇区写入,好像没影响
while(addr_offset < total_size)
{
c40_write_status = C40_Ip_MainInterfaceWrite(addr+addr_offset, overplus_size, &buf[addr_offset], S32K328_C40_DOMAIN_ID_VALUE);
do
{
c40_write_status = C40_Ip_MainInterfaceWriteStatus();
}
while (C40_IP_STATUS_BUSY == c40_write_status);
}
4:擦除
擦除操作是指将扇区或块中的所有位设置为 1 的流程。最小擦除单位可以是扇区,扇区大小为8KB。要擦除扇区或块,必须在擦除操作之前将其解锁。
注意:实际操作时候,发现没有擦除快的接口;擦除块也需要自己封装接口,内部进行判断
/* Unlock sector */
if (C40_IP_STATUS_SECTOR_PROTECTED == C40_Ip_GetLock(start_sector))
{
C40_Ip_ClearLock(start_sector, S32K328_C40_DOMAIN_ID_VALUE);
}
/* Erase sector */
c40_erase_status = C40_Ip_MainInterfaceSectorErase(start_sector, S32K328_C40_DOMAIN_ID_VALUE);
if (c40_erase_status == C40_IP_STATUS_SUCCESS)
{
do
{
// 擦除之后必须调用该接口,不然会报 EHV 错误; 很容易就busy了...
c40_erase_status = C40_Ip_MainInterfaceSectorEraseStatus();
}
while (C40_IP_STATUS_BUSY == c40_erase_status);
}
常见报错
1:C40_Ip_MainInterfaceSectorErase 报段错误 HardFault_Handler
此时可以查看 RWE 寄存器,如果为1的话,大概率就是 在APP运行的快内擦除数据了;需要将APP区和数据区分不同的block存储
RWE寄存器说明
更多推荐



所有评论(0)