这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【分享开发笔记,赚取电动螺丝刀】S32K146使用CRC模块校验镜像失败的问题调

共1条 1/1 1 跳转至

【分享开发笔记,赚取电动螺丝刀】S32K146使用CRC模块校验镜像失败的问题调查

高工
2025-03-22 06:15:21   被打赏 30 分(兑奖)     打赏

【问题背景】

在之前适配CRC(S32K146使用CRC模块校验数据  )帖子中,我们已经验证了CRC32功能正常,我们在使用IAR生成的镜像在末端添加CRC校验码,使用CRC模块进计算和IAR生成的值进行比较发现校验失败了,IAR的CRC32校验功能网上介绍也比较多,在此不做重点介绍,本地IAR 环境参数如下:

image.png


【问题调查】

因为CRC硬件算法功能我们本地已经验证过算法的正确性,所以开始一致怀疑是IAR生成的镜像的CRC 的正确性,本地将生成的镜像使用在线工具进行校验发现IAR生成的镜像校验码也是正确的。IAR 生成的镜像校验码为0x9c80e558

image.png

使用在线工具验证生成的镜像的CRC校验码和IAR生成的一致。

image.png

至此我们可能进入死胡同了,CRC功能和IAR生成的校验码都是经过验证是正确的,但是以下测试代码硬件CRC校验计算的值和IAR生成的是不一致的,以下验证代码计算结果如下:

unsigned int  image_check(char argc,char *argv[])
{
    CRC_DRV_Deinit(INST_CRC_1);
    CRC_DRV_Init(INST_CRC_1,&crc_1_Cfg0);
    CRC_DRV_WriteData(INST_CRC_1,(uint8_t *)0,0xffffc);
    printf("crc32 %08x,IAR %08x \r\n",CRC_DRV_GetCrcResult(INST_CRC_1),*(((unsigned long *)0xffffc)));

上述代码运行结果硬件CRC计算的结果看上去是不正确的

image.png

既然CRC和IAR 都是经过验证没问题的,会不会是运行时软件读取的flash的内容和生成的镜像是有区别的?带着这个想法,软件运行起来后通过仿真器将flash 的全部内容dump 出来和原始的bin 文件进行比较,比较后发现果然是软件读取的flash 的内容和编译后的是在0x40d 处是不一样的。

crc_compare.png

至此我们已经发现了问题的原因,至于为什么不一样我们需要进一步研究下,0x40d存储的是什么内容呢?我们先查看linkfile发现S32K146 的 0x400~040f 保存的flash 的配置数据。

image.png

image.png

image.png

对应的代码配置如下

image.png

从上述配代码配置注释可知,0x40d对应的FOPT 配置,手册中对该配置说明如下

image.png

image.png

不一样的正好是bit1 的保留处理的信号,怀疑是这个保留的bit 软件读取总是0 从而出发了上述异常。

在IAR环境中,针对这种下载和读取不一致的问题可以开启镜像下载校验,这样就会在debug 下载的时候就暴露出找个问题,对应的配置如下,建议开启该选项开启该选项后会先下载然后校验,下载过程相对会耗时些。

image.png

开启后我么下载就会报出如下的错误,跟我们之前分析的原因也是一致的,只是之前我们没有开启对应镜像校验功能所以没发现该问题。

image.png


【解决方法】

知道了问题原因,我们就可以针对问题点进行解决。

解决方案1:

既然这个bit 是保留的没有使用,我们可以直接修改代码配置将默认的0x40d配置修改为0xfd,这样就不会出现上述异常了。

image.png

配置修改为0x7d,修改后编译代码运行,发现这次IAR 生成的CRC和 CRC模块计算的保持一致了。

image.png

解决方案2:

毕竟上述配置会修改默认的配置代码,虽然手册是保留未使用的bit,也不确定芯片是否有特殊的用途该bit,我们可以分段校验把0x40d的检验数据更新成0x7f这样就不需要修改NXP的默认配置。

修改代码如下:

unsigned int  image_check(char argc,char *argv[])
{
    CRC_DRV_Deinit(INST_CRC_1);
    CRC_DRV_Init(INST_CRC_1,&crc_1_Cfg0);
    CRC_DRV_WriteData(INST_CRC_1,(uint8_t *)0,0x40d);
    uint8_t data_0x40d = 0x7f;
    CRC_DRV_WriteData(INST_CRC_1,(uint8_t *)&data_0x40d,1);
    CRC_DRV_WriteData(INST_CRC_1,(uint8_t *)0x40e,0xffbee);

    printf("crc32 %08x,IAR %08x \r\n",CRC_DRV_GetCrcResult(INST_CRC_1),*(((unsigned long *)0xffffc)));

修改后代码验证CRC 和 IAR 的也是匹配的。

image.png

上述两种修改方案个人倾向与第二种,第二种不会修改默认配置,因为手册里也没有写这个bit 写0 会不又有潜在的问题,不确定芯片原厂的芯片设计该bit 是否有特殊用途只是手册上未说明罢了。



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]