小猫爪:S32K3学习笔记15-S32K3之SEMA42和INTM

1 前言

  这一节来看看S32K3上面的两个小东西,有之锦上添花,那就是SEMA42(Semaphores2)和INTM(Interrupt Monitor)。这两者之间并没有什么关联,只是这两个小东西内容比较少,所以我给放到了一起。

2 SEMA42

2.1 简介

  SEMA42是建立在XRDC基础上的一个硬件信号量模块,如果要使用SEMA42,那么就一定需要使能XRDC。SEMA42是为了解决避免在多核系统中,多核同一时间访问共享资源混乱的问题而设计的硬件信号量机制,其机制也是及其的简单,其功能框图如下所示:
在这里插入图片描述
  SEMA42一个有16个信号量通道,每一个通道都有一个叫做Gate的玩意,那这个Gate是可以被任何一个Domian的核通过软件来锁定的(这里的锁定指的是这个Gate只对当前Domain开放),一旦被锁住,那么其他Domian里面的核访问都会被这个Gate给截住,从而访问失败(Domain的含义可参考XRDC文章)。在这里一定要搞清楚的一点就是,SEMA42并不是针对不同的核设置的信号量,而是针对不同的Domian设置的信号量。所以如果将S32K324的M7_0和M7_1放在了同一个Domain,那么这个时候SEMA42是没有用的,该混乱还是会混乱。所以在配置XRDC的Domain的时候千万不要把两个核放在同一个Domian里面,傻子才会这么配。

  注意:SEMA42只有在写访问申请的时候才会起作用,也就是说,就算共享资源被Domain0锁住,那么这个时候Domain1的Master是可以正常读的。但是为了数据同步,在进行软件设计时,一般都是只有获取到信号量后,才会进行接下来的读写操作。

2.2 MCAL配置

  要使用SEMA42也是非常的简单,只需要在Rm模块中使能SEMA42,如下:
在这里插入图片描述
  然后就可以在XRDC的Memory Config和Peripheral Config中为相关的共享资源(这里的共享资源指的可被不同Domain访问的外设和Memory)分配SEMA42通道,如下:
在这里插入图片描述
  这样配置后,SEMA42的通道就和相应的外设和Memory区域绑定在了一起,当一个Master对共享资源发起写访问申请后,在DdACP评估阶段之前就会先查看这个时候共享资源的SEMA42通道的Gate是否其他Domain锁着,如果没有被其他Domain被锁着的话,就可以继续进行DdACP评估流程。

  另外如果在这里没有配置SEMA42的话,有些特殊的外设也可以在其对应的模块来使能SEMA42,比如在Fls模块中,面对双核同时访问Flash的情况,就可以通过使能Fls Multi Core Syncronization Enable选项来使能SEMA42,如下:
在这里插入图片描述
  这里需要注意的是,SEMA42通道的Gate的锁定和解锁都是通过软件来手动实现的,当然MCAL的驱动函数给你写好了,不用管。所以在规划多核软件时,访问共享资源时,都是先上锁,再访问,再解锁的形式来进行相关操作,另外也可以使用SEMA42来实现对一个虚拟资源的信号量控制。

  MCAL为SEMA42提供了非常方便的CDD API接口,分别如下:

//获取信号量状态
Rm_Sema42_CoreType Rm_SemaphoreGetStatus(Rm_Sema42_ChannelType ChannelNumber);
//上锁,即获取信号量
Std_ReturnType Rm_SemaphoreLockGate(Rm_Sema42_ChannelType ChannelNumber);
//解锁,即释放信号量
Std_ReturnType Rm_SemaphoreUnlockGate(Rm_Sema42_ChannelType ChannelNumber);
//复位SEMA42的单个通道
void Rm_SemaphoreResetGate(Rm_Sema42_ChannelType ChannelNumber);
//复位SEMA42的所有通道
void Rm_SemaphoreResetAllGates(void);

3 INTM

3.1 简介

  INTM其实就是一个专门监控中断响应的看门狗,主要监测的是一个中断从request到acknowledged的时间有没有超时,如果超时则会报告错误给FCCU模块。INTM总共有四个通道,即INTM最大可同时监测四个中断。INTM的功能框图如下:
在这里插入图片描述
  工作机制也是非常简单,其流程如下:

  1. 配置 INTM_IRQSEL来选择触发INTM_TIMER开始计时的中断号
  2. 配置INTM_LATENCYa来规定超时时间
  3. 配置INTM_MM来使能INTM模块开始监控
  4. INTM检测到第1步配置的中断号对应的中断申请,INTM_TIMER开始计时
  5. 如果在第2步规定的时间内通过写INTM_IACK停止INTM_TIMER计时,则正常
  6. 如果没有在第2步规定的时间内停止INTM_TIMER,而导致超时,INTM_STATUS置位,INTM发送一个错误信号至FCCU模块

3.2 MCAL配置和代码处理

  首先需要需要在Mcu模块中打开INTM的外设时钟:
在这里插入图片描述
  INTM的配置在MCAL被集成到了Platform中, 如下:
在这里插入图片描述
  然后对INTM通道进行配置,如下:
在这里插入图片描述
  这里我选择让INTM0监控PIT0,所以需要在PIT0中断的callback函数里面调用函数Platform_AckIrq来停止INTM的Timer,如下:

void Gpt_Pit0_CH0_Notification(void)
{
	volatile uint32_t cnt;
	/* if INTM fault injection is enabled. */
	if(INTMFaultInjectFlag > 0){
		INTMFaultInjectFlag = 0;
		/* delay some time to let INTM timeout occur. */
		TestDelay(16000000);
	}
	/* writing INTM ACK register to clear the timeout timer. */
	Platform_AckIrq(IntmChannel_0);

    if ((Dio_LevelType)STD_LOW == LED0_RED_level)
    {
    	LED0_RED_level = (Dio_LevelType)STD_HIGH;
    }
    else
    {
    	LED0_RED_level = (Dio_LevelType)STD_LOW;
    }
	/* toggle LED D28 on White Board */
    Dio_WriteChannel(DioConf_DioChannel_LED0_RED, LED0_RED_level);
	return;
}

  接下来就是代码里面的处理了,INTM检测到中断响应超时后会将错误发送给FCCU,所以我们需要在FCCU中进行处理,INTM占据的是FCCU通道是NCF6,如果使能了NCF6通道的Alarm中断,就可以在Alarm中添加相关处理代码如下:

eMcem_ErrRecoveryType eMcemUserAlarmHandler( eMcem_FaultType nFaultId )
{
	uint32_t u32FccuFaults = 0;
	uint32_t u32FaultAddr = 0;

	/* read fault information */
	eMcem_GetErrors( &faultContainer );
	eMcem_Fccu_GetErrors( &u32FccuFaults, &u32FccuFaults );

	/* Must clear faults in time (within 10ms after fault detected), 
	otherwise FCCU enters fault state and reset occurred. */
	eMcem_ClearFaults( nFaultId );
	/* print message showing execution of FCCU Alarm Handler. */
	printf("FCCU alarm handler. FCCU_NCF=0x%X, Fault_ID=%d.\r\n", (unsigned int)u32FccuFaults, (unsigned int)nFaultId);
	printf("faultContainer = 0x%08X, 0x%08X, 0x%08X. \r\n", (unsigned int)faultContainer.au32Faults[0], (unsigned int)faultContainer.au32Faults[1], (unsigned int)faultContainer.au32Faults[2]);

    //...........
    //...........
   
	/* if it's NCF6 fault - INTM interrupt monitor error */
	if(u32FccuFaults & FCCU_NCF_S_NCFS6_MASK)
	{
		eMcemUserIntmFaultHandler();//用户可根据自己进行相关处理
		eMcem_ClearFaults( nFaultId );
		return EMCEM_ERR_RECOVERED;
	}
	
	//...........
    //...........
}

END

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小猫爪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值