查看: 175|回复: 0

[分享] NXP FRDM-MCXA153开发板+IAR CRC工程

[复制链接]

该用户从未签到

4

主题

4

帖子

0

注册会员

Rank: 2

积分
87
最后登录
2024-4-25
发表于 2024-3-19 15:54:49 | 显示全部楼层 |阅读模式
本帖最后由 eefocus_3892820 于 2024-3-19 15:54 编辑

NXP MCXA系列MCU内部有硬件(Cyclic Redundancy Check)CRC模块,可以用于CRC的计算。
对应的CRC支持常见的CRC-16和CRC-32算法(通过配置对应的GPOLY和CTRL寄存器):
CRC16.png

CRC32.png

下面的CRC模块的框图:
CRC32BlockDiagram.png

对应有3个寄存器:
DATA: 用于接收要计算的数据并保存对应的计算结果
GPOLY: 用于配置CRC多项式
CTRL: 用于配置CRC的选项

CRC计算的操作顺序:
1. 配置CTRL[TCRC]选择CRC-16或者CRC-32
2. 配置CTRL[TOR],CTRL[TOTR]和CTRL[FXOR]选择对应的CRC选项
3. 配置GPOLY选择对应的CRC多项式
4. 写1到CTRL[WAS]使能CRC种子写操作
5. 写CRC种子到DATA寄存器
6. 写0到CTRL[WAS]使能CRC数据写操作
7. 写数据到DATA寄存器(每次写数据到DATA寄存器之后,CRC会进行计算,并把计算的结果保存到DATA寄存器)
8. 写完所有的数据之后,从DATA寄存器读取对应的CRC计算结果

NXP的SDK里面提供了对应的API用于CRC的配置,计算和读取操作。

打开SDK里面\boards\frdmmcxa153\driver_examples\crc\iar下面的CRC工程并进行编译,下载调试,串口助手会打印出对应的CRC计算信息:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CRC Peripheral Driver Example

Test string: 123456789
CRC-16 CCIT FALSE: 0x29b1
CRC-16 MAXIM: 0x44c2
CRC-16 KERMIT: 0x2189
CRC-32: 0xcbf43926
CRC-32 POSIX: 0x765e7680
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CRCOutput.png


下面介绍如何在IAR里面build的时候生成对应Flash地址区域的checksum,并使用MCXA系列MCU内部的CRC模块进行计算对应Flash地址区域的checksum,然后与之前IAR工具生成的checksum进行比较,来检查对应Flash地址区域的完整性。

下面是IAR工具里面对应CRC32的配置:
Fill pattern: 0xFF (0xFFFF在Arm Cortex-M里面是未定义的指令,如果PC错误地指向了对应填充的地址,会产生Fault)
Start address: 0x0
End address: 0x0001FFFB(对应的checksum放到地址0x0001FFFC ~ 0x0001FFFF)
Algorithm: CRC32(对应的Poly自动选择为0x04C11DB7)
Complement: 1's complement(对应的XorOut为0xFFFFFFFF)
Initial value: 0xFFFFFFFF(对应的Init为0xFFFFFFFF) (同时不勾选Use as input)
Bit order: 选择 LSB first(对应RefIn = TRUE, RefOut = TRUE)
需要勾选Reverse byte order within word
ChecksumConfiguration.png

在ICF文件添加对应的命令,将checksum放到地址0x0001FFFC:
  1. place at address mem: 0x0001FFFC            { section .checksum };
复制代码


在代码里面添加下面的跟checksum相关的声明:
  1. /* Linker generated symbols */
  2. extern uint32_t const __checksum;
  3. extern uint32_t __checksum_begin;
  4. extern uint32_t __checksum_end;
复制代码

在代码里面的while (1)循环里面添加下面的代码:
  1. /* ***************
  2. * CRC-32 *
  3. *************** */
  4. InitCrc32(base, 0xFFFFFFFFU);

  5. /* Calculate the code flash using CRC calculation unit                   */
  6. CRC_WriteData(base, (uint8_t *)&__checksum_begin,
  7. ((uint32_t)&__checksum_end - (uint32_t)&__checksum_begin + 1u));

  8. /* Read the calculated checksum                                       */
  9. checksum32 = CRC_Get32bitResult(base);

  10. PRINTF("CRC-32: 0x%x\r\n", checksum32);

  11. /* Compare the calculated CRC with the previously stored CRC       */
  12. if (__checksum != checksum32)
  13. {
  14.     PRINTF("Flash checksum is NOK\r\n");
  15. }
  16. else
  17. {
  18.     PRINTF("Flash checksum is OK\r\n");
  19. }
复制代码
编译工程,在Build窗口里面会显示对应IAR生成checksum的相关信息:
checksum计算的开始地址是0x0,结束地址是0x1'fffb,同时计算出来的checksum放到地址0x1'fffc,对应的值是0x80aa501
BuildLog.png

同时生成的MAP文件里面会列出对应checksum相关symbol的信息:
__checksum放到地址0x1'fffc(大小是4bytes)
__checksum_begin {Abs}是0x0 (对应checksum计算的开始地址是0x0)
__checksum_end {Abs}是0x1'fffb(对应checksum计算的结束地址是0x1'fffb)
CRCMap.png

下载调试,串口调试助手显示利用CRC模块计算出来的checksum是0x80aa501,与IAR工具计算出来的checksum一致,对应Flash地址区域的完整性是OK的:
ChecksumUART.png
在if (__checksum != checksum32)代码处打断点,断点触发后,查看对应CRC的DATA寄存器:
对应CRC的DATA寄存器的值是0x80aa501:
CrcDebug.png

注意:有时候工具生成的checksum和代码里面计算出来的checksum可能不一致,需要检查两边的配置是否一致(对应的种子,选项,数据的顺序,计算的范围等),可以先比较1个字节,然后4个字节, 看看哪里配置不一致)。可以借助网上的crc计算工具:
https://crccalc.com/

至此在IAR里面利用IAR工具生成对应Flash地址区域的checksum,在代码里面使用MCXA系列MCU内部的CRC模块进行计算对应Flash地址区域的checksum,然后与之前IAR工具生成的checksum进行比较,来检查对应Flash地址区域的完整性的介绍就到这里







回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2024-4-27 23:55 , Processed in 0.115201 second(s), 21 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表