Other Parts Discussed in Thread: HALCOGEN, SEGGER
Hello,
Any ideas what might cause multiple FBPARERR calls occasionally after the VIM_SRAM_PARITY_TEST test is performed and when entering FBPARERR-function the PARFLG is 0 so there should not be any parity errors?
Pseudocode:
Lock scheduler
Disable IRQ
...
else if( eTest == DIAG_TEST_CPU_VIM )
{
if( ptTest->eTest == VIM_SRAM_PARITY_TEST )
{
DBG_PRINT( "VIM PARTEST start: %u us\r\n", HAL_u32TimeGet() );
}
bRetVal = SL_SelfTest_VIM( ptTest->eTest );
if( ptTest->eTest == VIM_SRAM_PARITY_TEST )
{
DBG_PRINT( "VIM PARTEST end: %u us, FLG: 0x%x\r\n", HAL_u32TimeGet(), sl_vimParREG->PARFLG );
}
failInfo = ST_PASS; // / generic variable always PASS
}
...
Enable IRQ
Unlock scheduler
## end of pseudocode
That kind of code generates following debug prints
DIAG: tests started, 53247080 ms<CR><LF>
CCM tests skipped<CR><LF>
VIM PARTEST start: 1716472897 us<CR><LF>
VIM PARTEST end: 1716472932 us, FLG: 0x0<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716472985 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473042 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473098 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473154 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473210 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473266 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473322 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473378 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473434 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473490 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473546 us ===<CR><LF>
<CR><LF>
===VIM_PARFLG: 0x0 ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 1716473602 us ===<CR><LF>
DIAG: tests passed, 53259080 ms<CR><LF>
And my FBPARERR function looks like this (basically pretty much same as halcogen version, but this does not try to restore the vector content since SL_ESM_Init() & vimChannelMap() modifies vectors so Halcogen code would restore wrong vector):
__irq
static void vVimParityErrorHandler( void )
{
typedef volatile struct vimRam
{
t_isrFuncPTR ISR[VIM_CHANNELS];
} vimRAM_t;
#define vimRAM ((vimRAM_t *)0xFFF82000U)
/* Identify the corrupted address */
uint32 u32ErrorAddr = VIM_ADDERR;
/* Identify the channel number */
uint32 u32ErrorChannel = (uint32)((u32ErrorAddr & 0x1FFU) >> 2U);
/* Clear Parity Error Flag */
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 */ // re-read same vector
if( VIM_PARFLG != 0U ) // test if again parity error
{
DBG_PRINT_PANIC( "\r\n\r\n===VIM RAM PARITY ERROR - permanent error: %u ===\r\n\r\n", u32ErrorChannel );
WOS_vInfiniteLoop();
}
else
{
/* temporary error, acknowledge of the parflg was enough */
DBG_PRINT( "\r\n===VIM RAM PARITY ERROR - channel: %u @ %u us ===\r\n", u32ErrorChannel, HAL_u32TimeGet() );
}
}
else
{
DBG_PRINT_PANIC( "\r\n\r\n===VIM RAM PARITY ERROR - Channel error: %u ===\r\n\r\n", u32ErrorChannel );
WOS_vInfiniteLoop();
}
}
And here is my FBPARERR assignment:
vimInit();
/* Override HALCoGen function since it restores vectors from ROM table, but vectors are modified by SafeTI &
vimChannelMap() function --- restoring from ROM is not reliable, own backup RAM table would be needed
but it would need also manual updating everytime when operation is made which modifies VIM RAM */
VIM_FBPARERR = (uint32)vVimParityErrorHandler; /*lint !e9074 !e923 */ /* r11.1 & r11.6 PD */
Over all this printing happens quite rarely, like once in 2 hours or even more seldom, and it looks to happen every time right after that VIM_SRAM_PARITY_TEST which is run every 12sec so it is like ~every 1000th tests causes that FBPARERR call and when that happens the FBPARERR is called multiple times in a row and as you can see from prints & code the PARFLG == 0 so no one should not even call that FBPARERR function.
Also notice that PARFLG is already 0 when exiting the VIM_SRAM_PARITY_TEST also in this case like it is in a case where that spurious FBPARERR call does not happen, here is one example of OK/normal case:
DIAG: tests started, 62843080<CR><LF>
CCM tests skipped<CR><LF>
VIM PARTEST start: 2722538305 us<CR><LF>
VIM PARTEST end: 2722538340 us, FLG: 0x0<CR><LF>
DIAG: tests passed, 62855080<CR><LF>
Here is also 1 print with out PAR_FLG prints and as can be seen the "us" time between spurious calls are now smaller ~38us vs ~56us when PAR_FLG is called
VIM PARTEST start: 49076996 us<CR><LF>
VIM PARTEST end: 49077029 us, FLG: 0x0<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 49077063 us ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 49077101 us ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 49077139 us ===<CR><LF>
<CR><LF>
===VIM RAM PARITY ERROR - channel: 2 @ 49077176 us ===<CR><LF>
....
Question1: Why FBPARERR address gets occasionally called even PARFLG is 0?
Question2: Why that FBPARERR address is spuriously called multiple times in case it gets called once, since the parity error handler function tests that parity error is not active anymore - if it still active it halts the CPU into IRQ/FIQ mode by staying in infinite loop inside this handler function?
Question3: Why that FBPARERR address calls looks to came only right after the VIM_SRAM_PARITY_TEST?
Question4: any suggestions what to do or how to avoid those unexpected FBPARERR address calls? Obviously PARLFG should be checked first and in case that is 0, nothing shall be done - HalCoGen function looks to have same problem that it does not check PARFLG when entering parity handler function...
I have also set "guard print" to phanton interrupt to determine that this "reserved" VIM vector which is used in SafeTI to test VIM will not be called. This phantom printing is not seen so no one really calls this vector so VIM should not try to load that vector meaning that VIM should not detect that parity error either meaning that FBPARERR address should not get called even once...
void phantomInterrupt(void)
{
/* USER CODE BEGIN (2) */
#include "macros.h"
DBG_PRINT( "IRQ: Phantom\r\n" );
/* USER CODE END */
}
I have also enabled IRQ notifier from ESM is case parity error comes (channel 15) and that ESM irq is not signalled either before/after those spurious calls indicating that there is not real parity error in VIM
esmREG->IESR1 = (uint32)((uint32)0U << 31U)
...
| (uint32)((uint32)0U << 16U)
| (uint32)((uint32)1U << 15U)
| (uint32)((uint32)0U << 14U)