This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ILLOPA exception on C167CR-LM

Hello,
I developed an emmbedded application for a C167CR-LM.
In this application I've some very big data structures stored in internal RAM (IDATA) and some dynamic list managed using malloc and free.
For dynamic allocation I define the pool:

unsigned char far equivalence_pool[0x4000];

init_mempool (equivalence_pool, sizeof (equivalence_pool));

In my application there is a IRQ routine on a Timer T6 with a period of 0.5 ms.

In some situations the ILLOPA exception is trapped an the application crashes.
It generally happens when many digital input (linked to port P2 pins) are active together.

I tried to increase the user stack with no effect.

Adding 2 calls to printf in the IRQ routine, ILLOPA is not generated.

Have you some suggestions for help me how to investigate this problem?

Testing with Mon166 the trap routines are not available, and using Simulator is too complex cause the hardware and input sequences to generate.

Thanks,
Marco

  • I you sure you are not exceeding the size of IDATA?

  • Yes, because I know the dimension of my memory and then because building the application the Compiler would generate a warning message on exceeding the size of IDATA.
    But thi Warning is not present.

    Thanks.

  • could it be that your T6 ISR corrupts something critical for the main loop or another ISR?

  • The routine is too long to print it here.

    Therefore it's good because it was part of an old application, ant its the main function in my application.

    Thanks to all.

  • Therefore it's good because it was part of an old application, ant its the main function in my application.

    no no no Marco, the fact that is used to work means nothing - maybe there is a hidden bug in it you never encountered? you must post more details to allow further analysis.

  • Here the 1/4 part of the code:

    void Timer6Interrupt(void) interrupt 0x26 using Timer6Bank
    {
            UINT i;
            UBYTE countEnc, gapEnc, cnt;
            UINT checkRB;
            bit errRB;
            long comptime;
            UINT metaldata;
    
            UBYTE ErrScan = 0; // ** MTL **  eventuale errore di scansione matrice
            UBYTE ErrReset = 0;// ** MTL **  eventuale errore di reset buffer
            UBYTE ErrEqu = 0;  // ** MTL **  eventuale errore di normalizzazione equivalenze
            UBYTE ErrLab = 0;  // ** MTL **  eventuale errore di normalizzazione etichette
            UBYTE ErrCat = 0;  // ** MTL **  eventuale errore di catalogazione etichette
            UBYTE ErrDel = 0;  // ** MTL **  eventuale errore di eliminazione equivalenze
    
    
            // ** NEW ** Calcolo Tempo di Idle
            StopT1Read = T1;
            comptime = (long)StopT1Read - (long)StartT1Idle;
            if ((comptime) < 0)
                    IdleTicks = PERF_TIMER + comptime;
            else
                    IdleTicks = comptime;
    
            // ** NEW ** Ci interessa il minimo Tempo di Idle perche' verra'
            // trasmesso il suo valore percentuale insieme allo stato
            // Tale valore viene resettato per le prime 5 ricezioni del
            // comando STS (transitorio) dopodiche entrera' a regime
            if (IdleTicks < MinIdleTicks)
                    MinIdleTicks = IdleTicks;
    
            // ** NEW ** Calcolo Tempo di Cycle
            comptime = (long)StopT1Read - (long)StartT1Cycle;
            if ((comptime) < 0)
                    CycleTicks = PERF_TIMER + comptime;
            else
                    CycleTicks = comptime;
            StartT1Cycle = StopT1Read;
    
    
            errRB = 0;
    
    
    
    
    // ================== GESTIONE RICERCA METALLI =======================
            if (MetalDetection.Enable) {
    
    // ************************* CONTATORI *******************************
    
                    // Sezione 1 - Ritardi e abilitazioni
                    if (MetalDetection.Encoder == 0xFF) {
                            // Ritardi e campionamenti a tempo
    
                            for (i = 0; i < MTL_BUFNUM; i++) {
    
                                    // Contatore trigger di attivazione
                                    if (MetalCounter[i].StartCount != NO_COUNT) {
                                            MetalCounter[i].StartCount--;
    
                                            if (MetalCounter[i].StartCount <= 0) {
    
    //      printf("\nFine StartCount T su buffer %d\n",i);
    
    
                                                    MetalCounter[i].ReadEnable = 1;
                                                    MetalCounter[i].Active = 1;
                                                    MetalCounter[i].Broken = 0;
                                                    MetalCounter[i].StartCount = NO_COUNT;
                                                    ErrReset = ResetBuf(i); // Resetto il buffer i
                                            }
                                    }
    
                                    // Contatore trigger di disattivazione
                                    if (MetalCounter[i].StopCount != NO_COUNT) {
                                            MetalCounter[i].StopCount--;
    
                                            if (MetalCounter[i].StopCount <= 0) {
    
    //      printf("\nFine StopCount T su buffer %d\n",i);
    
    
                                                    MetalCounter[i].EndDoc = MetalDetection.SensorsDelay;
                                                    MetalCounter[i].StopCount = NO_COUNT;
                                            }
                                    }
    
                                    // Contatore timer di campionamento
                                    if (MetalCounter[i].Timer != NO_COUNT) {
                                            MetalCounter[i].Timer--;
    
                                            if (MetalCounter[i].Timer <= 0) {
    
    
    //      printf("\nFine Timer T su buffer %d\n",i);
    
    
                                                    MetalCounter[i].ReadEnable = 1;
                                                    MetalCounter[i].Timer = NO_COUNT;
                                            }
                                    }
    
                                    // Contatore bit di dato valido
                                    if (MetalCounter[i].CountValid != NO_COUNT) {
                                            MetalCounter[i].CountValid--;
    
                                            if (MetalCounter[i].CountValid <= 0) {
    
    //      printf("\nFine CountValid T su buffer %d\n",i);
    
    
                                                    MetalCounter[i].Valid = 0;
                                                    MetalCounter[i].CountValid = NO_COUNT;
    
                                                    // Abilitazione invio report LENTO1
                                                    MetalDetection.SendRepEnable = 1;
                                            }
                                    }
    
                            } // for (i = 0; i < MTL_BUFNUM; i++) - Tempo
    
                    }//to be continued
    

  • Here the 2/4 part of the code:

    ...
                            // Ritardi e campionamenti a spazio
    
                            countEnc = ENCPORT[0];
    
                            for (i = 0; i < MTL_BUFNUM; i++) {
    
                                    // Contatore trigger di attivazione
                                    if (MetalCounter[i].StartCount != NO_COUNT) {
    
                                            gapEnc = abs(countEnc - MetalCounter[i].EncPrev);
    
                                            if (gapEnc > MAX_GAP) { // l'encoder e' passato per lo zero
                                                            // Calcolo il decremento interpretando la direzione di
                                                            // conteggio dell'encoder
                                                    MetalCounter[i].StartCount -= (countEnc > MAX_GAP) ?
                                                                                                            (0xFF - countEnc + MetalCounter[i].EncPrev) :
                                                                                                            (0xFF + countEnc - MetalCounter[i].EncPrev);
                                            }
                                            else
                                                    MetalCounter[i].StartCount -= gapEnc;
    
                                            if (MetalCounter[i].StartCount <= 0) {
    
    //      printf("\nFine StartCount su buffer %d\n",i);
    
    
                                                    MetalCounter[i].ReadEnable = 1;
                                                    MetalCounter[i].Active = 1;
                                                    MetalCounter[i].Broken = 0;
                                                    MetalCounter[i].StartCount = NO_COUNT;
                                                    ErrReset = ResetBuf(i); // Resetto il buffer i
                                            }
                                    }
    
                                    // Contatore trigger di disattivazione
                                    if (MetalCounter[i].StopCount != NO_COUNT) {
    
                                            gapEnc = abs(countEnc - MetalCounter[i].EncPrev);
    
                                            if (gapEnc > MAX_GAP) { // l'encoder e' passato per lo zero
                                                            // Calcolo il decremento interpretando la direzione di
                                                            // conteggio dell'encoder
                                                    MetalCounter[i].StopCount -= (countEnc > MAX_GAP) ?
                                                                                                            (0xFF - countEnc + MetalCounter[i].EncPrev) :
                                                                                                            (0xFF + countEnc - MetalCounter[i].EncPrev);
                                            }
                                            else
                                                    MetalCounter[i].StopCount -= gapEnc;
    
                                            if (MetalCounter[i].StopCount <= 0) {
    
    //      printf("\nFine StopCount su buffer %d\n",i);
    
    
                                                    MetalCounter[i].EndDoc = MetalDetection.SensorsDelay;
                                                    MetalCounter[i].StopCount = NO_COUNT;
                                            }
                                    }
    
                                    // Contatore timer di campionamento
                                    if (MetalCounter[i].Timer != NO_COUNT) {
    
                                            gapEnc = abs(countEnc - MetalCounter[i].EncPrev);
    
                                            if (gapEnc > MAX_GAP) { // l'encoder e' passato per lo zero
                                                            // Calcolo il decremento interpretando la direzione di
                                                            // conteggio dell'encoder
                                                    MetalCounter[i].Timer -= (countEnc > MAX_GAP) ?
                                                                                                            (0xFF - countEnc + MetalCounter[i].EncPrev) :
                                                                                                            (0xFF + countEnc - MetalCounter[i].EncPrev);
                                            }
                                            else
                                                    MetalCounter[i].Timer -= gapEnc;
    
                                            if (MetalCounter[i].Timer <= 0) {
    
    //      printf("\nFine Timer su buffer %d\n",i);
    
    
                                                    MetalCounter[i].ReadEnable = 1;
                                                    MetalCounter[i].Timer = NO_COUNT;
                                            }
                                    }
    
                                    // Contatore bit di dato valido
                                    if (MetalCounter[i].CountValid != NO_COUNT) {
    
                                            gapEnc = abs(countEnc - MetalCounter[i].EncPrev);
    
                                            if (gapEnc > MAX_GAP) { // l'encoder e' passato per lo zero
                                                            // Calcolo il decremento interpretando la direzione di
                                                            // conteggio dell'encoder
                                                    MetalCounter[i].CountValid -= (countEnc > MAX_GAP) ?
                                                                                                            (0xFF - countEnc + MetalCounter[i].EncPrev) :
                                                                                                            (0xFF + countEnc - MetalCounter[i].EncPrev);
                                            }
                                            else
                                                    MetalCounter[i].CountValid -= gapEnc;
    
                                            if (MetalCounter[i].CountValid <= 0) {
    
    //      printf("\nFine CountValid su buffer %d\n",i);
    
    
                                                    MetalCounter[i].Valid = 0;
                                                    MetalCounter[i].CountValid = NO_COUNT;
    
                                                    // Abilitazione invio report LENTO1
                                                    MetalDetection.SendRepEnable = 1;
                                            }
                                    }
    
                                    // La lettura attuale diventa lettura precedente
                                    // per il prossimo interrupt da Timer6
                                    MetalCounter[i].EncPrev = countEnc;
    
                            } // for (i = 0; i < MTL_BUFNUM; i++) - Spazio
    
                    } // Fine Sezione 1 - Ritardi e abilitazioni
    
    //to be continued
    

  • That ISR is very seriously broken. It is many, many, many times too large and tries to do things a 0.5ms ISR should not try to do.

    Do split your code into ISR to collect events and a main loop that process the events. Your ISR shouldn't be larger than what you can view at the same time without selecting a microscopic font.

    How have you made sure that for any sequence of input stimuli, your ISR manages to do all work in 0.5ms? If y ou can't guarantee that - why even bother to have the code in the ISR if it isn't critical enough that it _must_ be done within 0.5ms?

  • Here the 3/4 part of the code:

    // ************************* LETTURA SENSORI *************************
    
                    // le nuove versioni (VerHw = 1) hanno gli ingressi attivi alti
                    metaldata = (Hw) ? (~P2 & MaskInSpeed) : (P2 & MaskInSpeed);
    
                    // Shift per isolare solo i sensori (0 e 1 vanno all'encoder,
                    // 2-10 vanno ai sensori, 11 va' al trigger)
                    metaldata = metaldata >> (NInputSpeed - 9 - 1);
                    metaldata &= 0x01FF;
    
                    // Interpretazione ingressi tramite polarity
                    metaldata ^= MetalDetection.SensorsPolarity;
    
    
    // ***************** SCANSIONI  RICERCA METALLI **********************
    
                    // Sezione 2 - Scansione documento e matrice
    
                    for (i = 0; i < MTL_BUFNUM; i++)
                    {
                            if (MetalCounter[i].ReadEnable)
                            {
                                    if (MetalCounter[i].EndDoc == NO_ENDDOC)
                                    {
                                            // Salvo sulla matrice di scansione la prima barriera di sensori
                                            ScanMatrix[i][0][ScanDoc[i].TotCol] = metaldata & 0x0001;
                                            ScanMatrix[i][2][ScanDoc[i].TotCol] = (metaldata >> 2) & 0x0001;
                                            ScanMatrix[i][4][ScanDoc[i].TotCol] = (metaldata >> 4) & 0x0001;
                                            ScanMatrix[i][6][ScanDoc[i].TotCol] = (metaldata >> 6) & 0x0001;
                                            ScanMatrix[i][8][ScanDoc[i].TotCol] = (metaldata >> 8) & 0x0001;
    
                                            if (ScanDoc[i].TotCol >= MetalDetection.SensorsDelay)
                                            {
    
    //      if (ScanDoc[i].TotCol == MetalDetection.SensorsDelay)
    //              printf("\nStart lettura seconda barriera su buffer %d\n",i);
    
    
                                                    // Salvo sulla matrice di scansione la seconda barriera di sensori
                                                    ScanMatrix[i][1][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                            (metaldata >> 1) & 0x0001;
                                                    ScanMatrix[i][3][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                            (metaldata >> 3) & 0x0001;
                                                    ScanMatrix[i][5][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                            (metaldata >> 5) & 0x0001;
                                                    ScanMatrix[i][7][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                            (metaldata >> 7) & 0x0001;
    
                                                    // Analizzo la colonna appena completata per identificare le regioni
                                                    ErrScan = ScansioneMatrice(i, ScanDoc[i].TotCol - MetalDetection.SensorsDelay);
                                            }
    
                                            if (++ScanDoc[i].TotCol == MTL_SCAN_COLS)
                                            {
                                                    // Ho superato la dimensione massima del buffer: chiudo la scansione
                                                    // documento abilitando la lettura solo della seconda barriera
    
    //      printf("\nRaggiunto limite su buffer %d\n",i);
    
    
                                               MetalCounter[i].EndDoc = MetalDetection.SensorsDelay;
                                                    MetalCounter[i].Broken = 1;
                                                    MetalCounter[i].StopCount = NO_COUNT;
                                            }
    
                                            // Inizializzo il contatore per la prossima scansione
                                            MetalCounter[i].Timer = MetalDetection.Timing;
    
                                    }
                                    else // if (MetalCounter[i].EndDoc == NO_ENDDOC)
                                    {
                                            // Siamo a fine documento: completo la lettura salvando sulla
                                            // matrice di scansione solo la seconda barriera di sensori
                                            ScanMatrix[i][1][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                    (metaldata >> 1) & 0x0001;
                                            ScanMatrix[i][3][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                    (metaldata >> 3) & 0x0001;
                                            ScanMatrix[i][5][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                    (metaldata >> 5) & 0x0001;
                                            ScanMatrix[i][7][ScanDoc[i].TotCol - MetalDetection.SensorsDelay] =
                                                                                                                                                                    (metaldata >> 7) & 0x0001;
    
                                            // Analizzo la colonna appena completata per identificare le regioni
                                            ErrScan = ScansioneMatrice(i, ScanDoc[i].TotCol - MetalDetection.SensorsDelay);
    
                                            // Decremento il contatore di fine documento
                                            MetalCounter[i].EndDoc--;
    
                                            if (MetalCounter[i].EndDoc)
                                            {
    //to be continued
    

  • Here the 4/5 part of the code:

            // Continuo la chiusura lettura documento
                                                    ScanDoc[i].TotCol++;
                                                    // Inizializzo il contatore per la prossima scansione
                                                    MetalCounter[i].Timer = MetalDetection.Timing;
                                            }
                                            else
                                            {
    
    //      printf("\nFine scansione su buffer %d\n",i);
    
                                                    // La scansione del documento e' terminata
                                                    MetalDetection.LastRead = i;
                                                    ScanDoc[i].TotCol -= (MetalDetection.SensorsDelay - 1);
                                                    MetalCounter[i].Active = 0;
                                                    MetalCounter[i].EndDoc = NO_ENDDOC;
                                                    MetalCounter[i].Timer = NO_COUNT;
                                                    MetalCounter[i].EquEnable = 1;
                                                    MetalDetection.BufAvailable = 1;
    
                                                    // Viene aggiornato lo stato della scheda secondo lo
                                                    // stato della memoria di allocazione dinamica, ma non
                                                    // viene generato un report dello stato slave, pertanto
                                                    // il nuovo stato verra' trasmesso al primo invio
                                                    // programmato
                                                    if (ErrMemory)
                                                    {
                                                            Stato |= ERROR_MTL;
                                                    }
                                                    else
                                                    {
                                                            Stato &= ~ERROR_MTL;
                                                    }
                                            }
                                    } // if (MetalCounter[i].EndDoc == NO_ENDDOC)
    
                                    // Disabilito la lettura sensori
                                    MetalCounter[i].ReadEnable = 0;
    
                            } //if (MetalCounter[i].ReadEnable)
    
                    } // for (i = 0; i < MTL_BUFNUM; i++)
    
    
    // **************** ELABORAZIONI RICERCA METALLI *********************
    
                    for (i = 0; i < MTL_BUFNUM; i++)
                    {
    
                            // Sezione 3 - Normalizzazione equivalenze
    
                            if (MetalCounter[i].EquEnable)
                            {
                                    MetalCounter[i].EquEnable = 0;
                                    ErrEqu = NormalizzaEquivalenze(i);
                                    MetalCounter[i].LabEnable = 1;
    
    //      printf("\nNormalizzazione equivalenze eseguita su buffer %d\n",i);
    
                            } //if (MetalCounter[i].EquEnable)
    
    
                            // Sezione 4 - Normalizzazione etichette
    
                            if (MetalCounter[i].LabEnable)
                            {
                                    MetalCounter[i].LabEnable = 0;
                                    ErrLab = NormalizzaEtichette(i);
                                    MetalCounter[i].CatEnable = 1;
    
    //      printf("\nNormalizzazione etichette eseguita su buffer %d\n",i);
    
                            } //if (MetalCounter[i].LabEnable)
    
    
                            // Sezione 5 - Catalogazione etichette
    
                            if (MetalCounter[i].CatEnable)
                            {
                                    MetalCounter[i].CatEnable = 0;
                                    ErrCat = CatalogaEtichette(i);
                                    MetalDetection.LastComplete = i;
                                    ErrDel = EliminaEquivalenze(i);
    
            printf("\n TotCol per buffer %d = %d\n",i, ScanDoc[i].TotCol);
    /*      printf(" SamplesCount per buffer %d = %d\n",i, ScanDoc[i].SamplesCount);
            printf(" RegionsCount per buffer %d = %d\n",i, ScanDoc[i].RegionsCount);
            printf(" NumRegions per buffer %d = %d\n",i, ScanDoc[i].NumRegions);
            printf(" LargerRegionSamples per buffer %d = %d\n",i, ScanDoc[i].LargerRegionSamples);
            printf(" HigherRegionHeight per buffer %d = %d\n",i, ScanDoc[i].HigherRegionHeight);
            printf(" HigherRegionLength per buffer %d = %d\n",i, ScanDoc[i].HigherRegionLength);
            printf(" LongerRegionHeight per buffer %d = %d\n",i, ScanDoc[i].LongerRegionHeight);
            printf(" LongerRegionLength per buffer %d = %d\n\n\n",i, ScanDoc[i].LongerRegionLength);
    */
                                    // Set del bit di dato valido
                                    MetalCounter[i].Valid = 1;
                                    MetalCounter[i].CountValid = MetalDetection.DlyValid;
    
                                    // Abilitazione invio report LENTO1
                                    MetalDetection.SendRepEnable = 1;
    
                            // Se la gestione e' a spazio leggo lo stato dell'encoder
                                    if (MetalDetection.Encoder != 0xFF)
                                            MetalCounter[i].EncPrev = ENCPORT[0];
    
                            } //if (MetalCounter[i].CatEnable)
    
    
                    } // for (i = 0; i < MTL_BUFNUM; i++)
    
            } // if (MetalDetection.Enable)
    
    
    // =============== GESTIONE RICERCA METALLI: FINE ====================
    
    
                    countEnc = ENCPORT[0];
    
    //to be continued
    

  • Here the 5/5 part of the code:

    // ================== GESTIONE RILETTURA USCITE ======================
                    if (NOutputSpeed) {
                      if (!RB_Cnt) {
                    // controllo della rilettura di tutte le uscite
                              checkRB =     ((~Output) ^    P5) & MaskOutSpeed;
                                    for     (i=0; i<NOutputSpeed; i++) {
                                      if (EnableRB[i] && (checkRB &     (1<<i))) {
                                              CountErrRB++;
                                                    errRB =1;
                                            }
                                    }
                                    RB_Cnt = NO_COUNT;
                            }
                            if (RB_Cnt != NO_COUNT)
                                    RB_Cnt--;
                    }
    // ===================== GESTIONE RITARDI ===========================
                    if (NDly) {
            // gestione canali ritardati
                            for (i=0; i<NDly; i++) {
                    // se nel ciclo precedente è cambiato lo stato dell'uscita viene
                    // controllato se si è verificato un errore di rilettura (se abilitata)
                                    if(EnableRB[Dly[i].Output] && (!Dly[i].Status)) {
                                            if(((~Output) ^ P5) & (0x0001 << Dly[i].Output)) {
                                                    CountErrRB++;
                                                    errRB = 1;
                                            }
                                            Dly[i].Status = NO_COUNT;
                                    }
                                    if (Dly[i].Status != NO_COUNT)
                                            Dly[i].Status--;
                                    if (Dly[i].Encoder == 0xFF) {
                            // -------------- Ritardi a tempo -------------------------------
                                            if (Dly[i].CountDlyOn != NO_COUNT)      {
                                                    Dly[i].CountDlyOn--;
                                                    if (Dly[i].CountDlyOn < 0) {
                                                            Output |= (0x0001 << Dly[i].Output);
                                                            Dly[i].Status = RB_DELAY;
                                                            Dly[i].CountDlyOn = NO_COUNT;
                                                    }
                                            }
                                            if (Dly[i].CountDlyOff != NO_COUNT)     {
                                                    Dly[i].CountDlyOff--;
                                                    if (Dly[i].CountDlyOff < 0) {
                                                            Output &= ~(0x0001 << Dly[i].Output);
                                                            Dly[i].Status = RB_DELAY;
                                                            Dly[i].CountDlyOff = NO_COUNT;
                                                    }
                                            }
                                    }
                                    else {
                            // -------------- Ritardi a spazio (encoder) ----------------------
                                            if (Dly[i].CountDlyOn != NO_COUNT) {
                cnt = abs(countEnc - countON[i]);
                if (cnt > MAX_GAP)
                  Dly[i].CountDlyOn -= (countEnc > MAX_GAP) ? (0xFF - countEnc + countON[i]):
                                                                (0xFF + countEnc - countON[i]);
                else Dly[i].CountDlyOn -= cnt;
    //                                              Dly[i].CountDlyOn -= abs(countEnc - countON[i]);
                                                    countON[i] = countEnc;
                                                    if (Dly[i].CountDlyOn <= 0) {
                                                            Output |= (0x0001 << Dly[i].Output) ;
                                                            Dly[i].Status = RB_DELAY;
                                                            Dly[i].CountDlyOn = NO_COUNT;
                                                    }
                                            }
                                            if (Dly[i].CountDlyOff != NO_COUNT) {
                cnt = abs(countEnc - countOFF[i]);
                if (cnt > MAX_GAP)
                  Dly[i].CountDlyOff -= (countEnc > MAX_GAP) ? (0xFF - countEnc + countOFF[i]):
                                                                (0xFF + countEnc - countOFF[i]);
                else Dly[i].CountDlyOff -= cnt;
    //                                              Dly[i].CountDlyOff -= abs(countEnc - countOFF[i]);
                                                    countOFF[i] = countEnc;
                                                    if (Dly[i].CountDlyOff <= 0) {
                                                            Output &= ~(0x0001 << Dly[i].Output);
                                                            Dly[i].Status = RB_DELAY;
                                                            Dly[i].CountDlyOff = NO_COUNT;
                                                    }
                                            }
                                    }
                            }
                    // attuazione dei canali di uscita
                            SetOut(Output);
                    }
    
    
                    // trasmissione su CAN della condizione di errore sul PDO di stato
                    // se si è verificato almeno un errore di rilettura
                    if (errRB && (!(Stato & ERROR_RB))) {
                            T8R = 1;
                            Stato |= ERROR_RB;
                            CAN_MSGOBJ[STATO].msg_ctl = CPUUPD_SET;
                            CAN_MSGOBJ[STATO].msg_cfg = MSG_CFG(1, CANDIR_TRANSMIT, 0);
                            CAN_MSGOBJ[STATO].msg[0] = Stato;
                            CAN_MSGOBJ[STATO].msg_ctl = CPUUPD_CLR & TXRQ_SET;
    }
            StartT1Idle = T1;
    }
    

  • This ISR rotine is a quarter of another one in another application for the same boards in the same plant, and it runs always good ...

  • There are stunt drivers that can drive their cars on two wheels - that doesn't mean that it is good to drive a car with two wheels in the air...

  • your ISR is miles long. it contains wasteful references to array elements, multiple loops...
    try what Per suggested: move the whole block outside of interrupt context - put it in a function and call it from your main loop. what happens then?
    again: the fact that code works means nothing beyond that it does not fail on that hardware, under certain circumstance