如下所示说明,均使用 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寄存器说明
在这里插入图片描述

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐