小猫爪:S32K3学习笔记20:S32K3之SCST及其应用

1 前言

  这篇文章来简单介绍一下NXP针对core test为S32K3设计的SCST(core self-test code)软件,并且将描述如何将SCST集成在自己的工程中并将其应用起来。

2 SCST简介

  SCST的原理如下:在这里插入图片描述
  SCST说白了就是针对S32K3的M7核的RTL模式,架构,指令集等等特征设计出可以测试M7核是否正常运行的一段汇编代码,这段代码里面无外乎就是主动去触发和响应中断呀,去做一些整型和浮点型计算,反正就是去干一些核经常干的事情,验证一下核的功能是否正常,此为SCST。

3 移植

  1. 先将SCST的所有文件移植到自己的工程里,如下:
    在这里插入图片描述
  2. 添加SCST的头文件,c部分如下:
    在这里插入图片描述
    Assembly部分如下:
    在这里插入图片描述
  3. 根据自己的编译器,添加相应的预宏定义,GCC对应__GNUC__,Green Hill对应__ghs__,IAR对应__IAR_SYSTEMS_ASM__。由于我这里使用的S32DS的工程,里面预宏定义已经定义了GCC,所以不需要再额外定义__GNUC__。
  4. 另外由于很多assembly文件都包含了c指令,所还需要增加一个编译选项,不同编译器根据下表来选择:
编译器选项options
GreenHills-preprocess_assembly_files
GCC-x assembler-with-cpp
IAR无需添加
  1. 除此之外,个别core test会用到一个reserved的地址M7_DEVICE_RESERVED_ADDR,所以需要在assembly的预宏定义中定义这个宏,如下:
    在这里插入图片描述

  2. 修改链接文件将一些段链接到合适的位置,这些段应该所链接位置以及这些段的内容具体如下:

sector链接位置描述
.m7_scst_test_codeFLASH包含了SCST的所有测试代码
.m7_scst_test_branch_code0FLASH分支测试代码0
.m7_scst_test_branch_code1FLASH分支测试代码1
.m7_scst_test_shell_codeFLASH调用测试的接口函数
.m7_scst_vector_tableFLASHSCST自定义中断向量表
.m7_scst_rom_dataFLASH常量
.m7_scst_ram_dataRAM全局变量
.m7_scst_test_shell_dataRAM调用测试的接口函数所用的全部变量
.m7_scst_ram_data_target0RAM恢复现场所用的数据0
.m7_scst_ram_data_target1RAM恢复现场所用的数据1
.m7_scst_ram_test_codeRAM给fetch test使用的变量

  FLASH部分如下:
  在这里插入图片描述

  RAM的sram_data部分如下:
  在这里插入图片描述
  到此,移植准备工作全部完成了。

4 应用

  SCST一共提供了50项测试,对应的测试项ID为0~49,截取一部分如下(其他请参考《M7_S32K3xx_SCST_User_Manual.pdf》):
在这里插入图片描述
  表中详细列出了每一测试项的测试ID(测试项索引), 参考签名值(当前测试项的正确返回值,如果测试项返回结果不等于参考签名值,那么标定该测试项未通过),用户中断阻塞时间(测试过程中,会更换中断向量表,从而让用户ISR堵塞),测试执行时间(整个测试项所用的时间),所用栈大小(使用的栈为编译器所划的Stack)。那么怎么在代码中实现这些测试呢?

4.1 启动测试

  启动SCST的测试项非常简单,只牵扯到一个函数,三个变量。其中一个函数为:

m7_scst_uint32_t m7_scst_execute_core_tests(m7_scst_uint32_t start, m7_scst_uint32_t end)

  可以通过这个函数来启动SCST测试项,形参start为起始测试项ID,形参end为结束测试ID。举个例子,如果如下调用:

test_result = m7_scst_execute_core_tests(049);//启动第1测试项到第49测试项,依次进行
test_result  = m7_scst_execute_core_tests(00);//测试第0测试项
test_result  = m7_scst_execute_core_tests(11);//测试第1测试项

  三个变量如下:

/*保存了最后一次测试项的ID,如果一次性启动所有测试项,中间有测试项出现错误未通过,
导致测试终止,那么则可以读取这个值来确定是哪个测试项未通过*/
extern m7_scst_uint32_t m7_scst_last_executed_test_number; 

/*记录了最后一次测试项的返回值,如果一次性启动所有测试项,中间有测试项出现错误未通过,
导致测试终止,那么则可以读取这个值来了解未通过测试项的错误返回值*/
extern m7_scst_vuint32_t m7_scst_accumulated_signature;

/*指定注入错误通道,可以在启动测试项之前,通过指定这个参数来向指定测试项注入错误,
注入错误会导致测试未通过*/
extern m7_scst_uint32_t m7_scst_fault_inject_test_index;

4.2 使能FPU相关测试项

  SCST50项测试有13项测试是针对FPU的,可以在m7_scst_configuration.h中配置是否使能FPU相关的core test选项,如下:

#define M7_SCST_SPFPU_TESTS                 1U

  另外,如果激活了FPU测试,那么就需要在编译选项中激活单精度FPU硬件,如下:
在这里插入图片描述
  其他编译器对应编译选项如下:

编译器选项options
GreenHills-fpu=vfpv3_d16
GCC-mfpu=fpv5-d16
IAR–cpu Cortex-M7.fp.sp

4.3 49号测试项中的MPU配置

  如果在应用代码中使能了MPU配置,那么其中49号测试项m7_scst_loadstore_test7对MPU的配置也有要求,具体要求以及MPU配置代码如下:

void MPU_config()
{
/*------------------------------------------------------------------------*/
/* MPU region 0 */
/*------------------------------------------------------------------------*/
*MPU_RNR = 0x00000000;
/* Configure MPU region 0 base address to SCST_RAM_TARGET0 */
*MPU_RBAR = (m7_scst_uint32_t)&SCST_RAM_TARGET0;
/* Configure MPU region 0
- XN: Not executable
- AP: S:RW U:RW Full access
- TEX: 0
- S: Not shareable
- C: Not cacheable
- B: Not bufferable
- SRD: 0b00000000
- SIZE: 32 B
- EN: Enabled
*/
*MPU_RASR = 0x13000009;
/*------------------------------------------------------------------------*/
/* MPU region 1 */
/*------------------------------------------------------------------------*/
*MPU_RNR = 0x00000001;
/* Configure MPU region 1 base address to SCST_RAM_TARGET1 */
*MPU_RBAR = (m7_scst_uint32_t)&SCST_RAM_TARGET1;
/* Configure MPU region 1
- XN: Not executable
- AP: S:RW U:-- Privileged access only
- TEX: 0
- S: Not shareable
- C: Not cacheable
- B: Not bufferable
- SRD: 0b00000000
- SIZE: 32 B
- EN: Enabled
*/
*MPU_RASR = 0x11000009;
/* Enable MPU
- PRIVDEFENA: 1 (Use default memory map as region -1 for privileged access)
- HFNMIENA: 0 (Disable MPU for handlers with priority less than 0)
- ENABLE: 1
*/
*MPU_CTRL = 0x00000005;
}

  当然了,如果你没有使能MPU,那么就没有什么影响。

4.4 特殊的0~5号测试项

  在50个测试中,0 ~ 5号测试项比较特殊,如果在Handle模式下启动0 ~ 5号测试项的话,那么就需要在m7_scst_configuration.h中配置一些宏,将其由默认值改为以下值:

#define M7_SCST_EXECUTION_MODE M7_SCST_HANDLER
#define M7_SCST_SVC_EXCEPTION_LOW 1U
#define M7_SCST_PENDSV_EXCEPTION_LOW 1U
#define M7_SCST_SYSTICK_EXCEPTION_LOW 1U

  如果systick中断被使能了,那么还需要修改这个宏,如下:

#define M7_SCST_SYSTICK_IS_RUNNING 1U

4.5 应用代码示例

  相关测试代码如下:

void SCST_example(void)
{
	//给第10号测试项注入错误
	m7_scst_fault_inject_test_index = 10;

	//启动0~27号测试项
	m7_scst_execute_core_tests(0, 27);
	//判断最后一次测试项ID是否为10
	if(m7_scst_last_executed_test_number != 10)
	{
		while(1);
	}

	//再次启动0~27号测试项
	m7_scst_execute_core_tests(0, 27);
	//判断最后一次测试项ID是否为35
	if(m7_scst_last_executed_test_number != 27)
	{
		while(1);
	}
	//判断最后一次测试项返回值是否为35号测试的参考签名值
	if(m7_scst_accumulated_signature == 0x7F0BF5A3U)
	{
		while(1);
	}

	//启动29~49号测试项
	m7_scst_execute_core_tests(29, 49);
	//判断最后一次测试项ID是否为48
	if(m7_scst_last_executed_test_number != 49)
	{
		while(1);
	}
	//判断最后一次测试项返回值是否为49号测试的参考签名值
	if(m7_scst_accumulated_signature == 0x2F6AB216U)
	{
		while(1);
	}

	//m7_scst_execute_core_tests(28, 28); //28号测试项暂时有问题,待解决
}

  注意①:SCST测试项是可以在应用程序中周期性启动的。
  注意②:在测试代码中,我跳过了第28号测试项,因为在测试过程中,发现该项测试无法通过,发现死在了一条STREX指令,这是因为这条指令是给FLASH的一个地址执行写操作,但是在MCAL代码中SystemInit中有一个配置MPU的操作,默认是将FALSH配置成了禁止写性所以我们有两种方法让第28测试项通过,第一种就是将FLASH的读写属性改成可写,第二种就是直接Disable MPU,具体如下:

/*配置FLASH区域为可写*/
rasr[2]=0x020B002BUL;
/*Disable MPU*/
S32_MPU->CTRL &= (~S32_MPU_CTRL_ENABLE_MASK);

  个人觉得这应该是条bug,看官方是否会在后面将其修复。
  至此,关于SCST的应用就全部介绍完毕了。

END

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小猫爪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值