主题中讨论的其他器件:HALCOGEN、 SEGGER
您好!
是否有什么想法 在执行 VIM_SRAM_parity 测试后偶尔会导致多个 FBPARERR 调用、并且在进入 FBPARERR 函数时、PARFLG 为0、因此不应出现任何奇偶校验错误?
伪代码:
锁定调度程序
禁用 IRQ
(笑声)
否则(eTest =DIAG_TEST_CPU_VIM)
{
if (ptTest->eTest == VIM_SRAM_parity)
{
DBG_PRINT ("VIM PARTEST 开始:%u us\r\n",HAL_u32TimeGet ());
}
bRetVal = sl_SelfTest_VIM (ptTest->eTest);
if (ptTest->eTest == VIM_SRAM_parity)
{
DBG_PRINT ("VIM PARTEST 结束:%u us,FLG:0x%x\r\n",HAL_u32TimeGet (),SL_vimParREG->PARFLG);
}
failInfo = ST_PASS;//通用变量始终通过
}
(笑声)
启用 IRQ
解锁调度程序
##伪代码结束
这种代码会生成以下调试打印
DIAG:测试已启动、53247080 ms
已跳过 CCM 测试
VIM PARTEST 开始:1716472897us
VIM PARTEST 结束:1716472932us、FLG:0x0
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716472985us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473042 us ===
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473098 us ===
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473154us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473210us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473266us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473322us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 171647338us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 17164734us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473490 us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473546us ==
==VIM_PARFLG:0x0 =
===VIM RAM 奇偶校验错误-通道:2 @ 1716473602us ==
DIAG:测试通过、53259080 ms
我的 FBPARERR 函数看起来是这样的(基本上与 halcogen 版本完全相同、但这不会尝试恢复矢量内容、因为 sl_ESM_Init()& vimChannelMap()修改了矢量、因此 Halcogen 代码会恢复错误的矢量):
_IRQ
静态空 vimParityErrorHandler( void )
{
typedef volatile struct vimRam
{
t_isrFuncPTR ISR[VIM_CHANNELS];
} vimRAM_t;
#define vimRAM ((vimRAM_t *) 0xFFF82000U)
/*标识损坏的地址*/
uint32 u32ErrorAddr = VIM_ADDERR;
/*识别信道编号*/
uint32 u32ErrorChannel =(uint32)((u32ErrorAddr & 0x1FFU)>> 2U);
/*清除奇偶校验错误标志*/
if (VIM_PARFLG == 0U)
{
DBG_PRINT ("\r\n=VIM_PARFLG:0x%x =\r\n"、VIM_PARFLG);
}
VIM_PARFLG = 1U;
if (u32ErrorChannel < VIM_CHANNELS)
{
(void) vimRAM->ISR[ u32ErrorChannel ];/*lint !e9078 !e923 */* r11.4 & r11.6 pd *//重新读取同一个矢量
if (VIM_PARFLG!= 0U) //测试是否再次出现奇偶校验错误
{
dbg_print_panic ("\r\n\r\n=VIM RAM 奇偶校验错误-永久错误:%u =\r\n\r\n"、u32ErrorChannel);
WOS_vInfiniteLoop ();
}
其他
{
/*临时错误,确认参数已足够*/
DBG_PRINT ("\r\n=VIM RAM 奇偶校验错误-通道:%u @%u us =\r\n"、u32ErrorChannel、HAL_u32TimeGet ()));
}
}
其他
{
dbg_print_panic ("\r\n\r\n==VIM RAM 奇偶校验错误-通道错误:%u =\r\n\r\n"、u32ErrorChannel);
WOS_vInfiniteLoop ();
}
}
这是我的 FBPARERR 分配:
vimInit();
/*覆盖 HALCoGen 函数、因为它会从 ROM 表中恢复矢量、但矢量由 SafeTI 和修改
vimChannelMap()函数--从 ROM 恢复不可靠,需要自己的备份 RAM 表
但是、每次执行修改 VIM RAM 的操作时、它也需要手动更新*
VIM_FBPARERR =(uint32) vVimParityErrorHandler;/*lint !e9074 !e923 *//* r11.1 & r11.6 pd */
在所有这些打印过程中、很少发生、例如2小时内一次、甚至很少发生、 在每12秒运行一次的 VIM_SRAM_奇 偶校验测试之后、每次都会发生这种情况、因此类似于~每1000次测试都会导致 FBPARERR 调用、当这种情况发生时、FBPARERR 会连续多次被调用、如打印和代码所示 PARFLG =0、因此任何人都不应调用该 FBPARERR 函数。
另请注意、在退出 VIM_SRAM_parity 测试时、PARFLG 已经为0、在这种情况下、就像在没有发生虚假 FBPARERR 调用的情况下一样、以下是 OK / NORMAL 情况的一个示例:
DIAG:测试已开始、62843080
已跳过 CCM 测试
VIM PARTEST 开始:2722538305us
VIM PARTEST 结束:2722538340us、FLG:0x0
DIAG:测试通过、62855080
此处还有1张打印输出 PAR_FLG 的照片、可以看到、调用 PAR_FLG 时、虚假呼叫之间的"us"时间现在比调用 PAR_FLG 时的~~38us 更短
VIM PARTEST 开始:49076996us
VIM PARTEST 结束:49077029us、FLG:0x0
===VIM RAM 奇偶校验错误-通道:2 @ 49077063us ===
===VIM RAM 奇偶校验错误-通道:2 @ 49077101us ==
===VIM RAM 奇偶校验错误-通道:2 @ 49077139us ==
===VIM RAM 奇偶校验错误-通道:2 @ 49077176us ==
…
问题1:为什么 FBPARERR 地址偶尔被调用、即使 PARFLG 为0?
问题2: 为什么 FBPARERR 地址被伪调用多次、以防它被调用一次、因为奇偶校验错误处理程序函数会测试奇偶校验错误不再有效-如果它仍然有效、它通过保持在这个处理程序函数内的无限循环来将 CPU 暂停至 IRQ/FIQ 模式?
问题3:为什么 FBPARERR 地址调用看起来仅出现在 VIM_SRAM_parquiation_test 之后?
问题4:是否有任何建议要做什么或如何避免这些意外的 FBPARERR 地址调用? 显然、应该首先检查 PARLFG、如果为0、则不执行任何操作- HalCoGen 函数看起来有与进入奇偶校验处理程序函数时它不检查 PARFLG 相同的问题...
我还将"防护装置打印"设置为模模块中断、以确定在 SafeTI 中用于测试 VIM 的"保留"VIM 矢量将不会被调用。 看不到这种幻象打印、所以没有人真正调用这个矢量、所以 VIM 不应该尝试加载那个矢量、这意味着 VIM 不应该检测到奇偶校验错误、这意味着即使一次也不应该调用 FBPARERR 地址...
void phantomInterrupt (void)
{
/*用户代码开始(2)*/
#include "macros.h"
DBG_PRINT ("IRQ:幻象\r\n");
/*用户代码结束*/
}
我还启用了来自 ESM 的 IRQ 通知器、出现了情况奇偶校验错误(通道15)、并且在这些虚假调用之前/之后 ESM IRQ 都没有信号、表明 VIM 中没有真正的奇偶校验错误
esmREG->IESR1 =(uint32)((uint32) 0U << 31U)
(笑声)
|(UINT32)((UINT32) 0U <<16U)
|(uint32)((uint32) 1U <<15U)
|(UINT32)((UINT32) 0U << 14U)