STM32H7 my array is corupting my ISR timmers

Hi i need help to find out how i am corupting my ISR.

I have just written a simple routine to trap errors so that i can report them and help with debugging, espcially my interupt timings.

When i i run it i noticed that my timer interupts became corupted for no reason. that i can find anyway. here is the code.

> 
> /*
> MyErrREPORT.cpp
> Ver:  1.0.0.1
> Date: 2 APR 2024
> */
> 
> #include "MyErrReport.h"
> #include "MyRtc.h"
> 
> uint32_t errEIDcounter;
> uint32_t errCADcounter;
> uint32_t errPARcounter;
> uint32_t errPAKcounter;
> uint32_t errSAPcounter;
> uint32_t errSAWcounter;
> 
> const char* errKindLU[] ={  "ERROR", 
>                             "WARNING", 
>                             "OTHER"};
> 
> const char* errTypeLU[] ={  "CADENCE", 
>                             "PARCEL", 
>                             "PACKET",
>                             "SAMPLE",
>                             "SAMWIN"};
> 
> errTableStruct errTable[]={};                            
> 
> void ReportError(int errType, int errKind, const char* errFunction,
>                  uint16_t errUCID, const char* errComment, bool errPrint){
> 
>     int n = sizeof(errTable)/sizeof(errTable[0]);
>     n++;
>     char intChar[5];
> 
>     // Add to Error Array
>     errTable[n].errID = errEIDcounter++;
>     errTable[n].errTime =  getRealTimeClock();               
>     errTable[n].errType = errType;
>     errTable[n].errKind = errKind;
>     strcpy(errTable[n].errMessage, errComment);
>     strcpy(errTable[n].errFunction, errFunction);
>     errTable[n].errUCID = errUCID;
>     errTable[n].errReported = FALSE;
> 
>     // Inc error counters
>     if(errType == ERT_CADENCE){errCADcounter++;}
>     if(errType == ERT_PARCEL){errPARcounter++ ;}
>     if(errType == ERT_PACKET){errPAKcounter++ ;}
>     if(errType == ERT_SAMPLE){errSAPcounter++ ;}
>     if(errType == ERT_SAMWIN){errSAWcounter++ ;}
> 
>     //If True Print to Serial
>     if (errPrint == TRUE){
>         Serial.print("\tEXCEPTION: " );
>         Serial.print(errKindLU[errKind]); Serial.print(", ");
>         Serial.print(errTypeLU[errType]); Serial.print(", ");
>         Serial.print(errFunction); Serial.print(", ");
>         Serial.print(errUCID); Serial.print(", ");
>         Serial.println(errComment);
>         
>     }
> }

and here is the header.

/*  BUCKOS HEADER FILE   MyLCD.h
    Header file for      MyLCD.cpp

    Version:   001
    Date:       6 March 2024
    Board:      Arduino Portenta H7 (PH7)
    Extra:      PH7 Breakoutboard
    uP:         ST STM-32
*/

// This header is for my USB setting 

//#pragma once
#ifndef MyErrReport
#define MyErrReport

#include <Arduino.h>
#include <Arduino_PortentaBreakout.h>
#include "ProjConfig.h"
#include "MyRTC.h"

// Structure Error Table
    typedef struct {
        uint32_t errID;             // unique error id
        uint64_t errTime;             // timeStamp
        int errType;                // Type as per errTy
        int errKind ;           // ERROR, WARNING, OTHER
        char errFunction[16];    // Call function 
        uint16_t errUCID;           // Call ID to trace exact error
        char errMessage[42];        //
        bool errReported;           // Error sent to Puter
        } errTableStruct;

//errTableStruct errTable[];


#define ERY_ERROR   0
#define ERY_WARNING 1
#define ERY_OTHER   2
extern const char* errKindLU[];


// Structure Error type
#define ERT_CADENCE 0
#define ERT_PARCEL  1
#define ERT_PACKET  2
#define ERT_SAMPLE  3
#define ERT_SAMWIN  4
extern const char* errTypeLU[];


extern uint32_t errEIDcounter;
extern uint32_t errCADcounter;
extern uint32_t errPARcounter;
extern uint32_t errPAKcounter;
extern uint32_t errSAPcounter;
extern uint32_t errSAWcounter;
//extern uint32_t errEIDcounter;

void ReportError(int errType, int errKind, const char* errFunction,
                 uint16_t errUCID, const char* errComment, bool errPrint);

#endif

The Timer interupts are handled by libarays built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_TimerInterrupt

When i start to write data to my errTable it actually writes to the ISR_Timer obj that was created via the “Portenta_H7_TimerInterupt” librays.

For example when i debug and stop at the “errTable[n].errID = errEIDcounter++;” line and hold my mouse over it. It will say ISRT and an address x24001888, instead of “errTableStruct errTable[0]” as i would expect.

Am i creating and declaring my arrays correctly?

This makes no sense. You’re creating a zero-length array of type errTableStruct. Its sizeof(errTable) is zero.

(The return register r0 is loaded with the value #0)

The code above will compute n to be 0 (as 0 / 88, to be exact). Then you even increment by one, so it’ll be 1. You then use that as an index into the errTable, which again doesn’t exist. So it’ll be vastly overwriting memory. The current “write index” n isn’t even created as a global variable so it’ll be the same number each time the function is entered.

You seem to be expecting that errTable is a dynamically allocated list (see: linked list) that you can just add to. This is not the case. You have created an zero-length preallocated array.

Even if you said

errTableStruct errTable[10]={};

you would have allocated a 10-entry error table. Good. But then you will still have to keep track of which entry has been written to and which not (e.g., an index number). What do you do when all 10 entries have been written to? Go back to overwriting the first entry? That’s a circular buffer then. Throw an error? That’s a one-time use of a preallocated array then.

You want true, dynamic-sized lists? std::list<errTableStruct> errTable; it is then from #include <list> or std::vector<errTableStruct> errTable> from#include <vector> (see differences), in C++ code. This will use malloc during runtime though to allocate the newly needed memory, which is frowned upon because it can lead to out-of-memory errors if you’re not careful. Statically sized arrays should be preferred.

1 Like

Thanks. Yes i do want to dynamically use my arrays. the plan was to go no more that say 20 deep, and save to a table on my SD card.

In the short term i have created a #define ERR_TABLE_SIZE 20 and set my index as global and make sure i dont go larger if (errTableIndex < ERR_TABLE_SIZE){

Thanks for the link to the “Vectors vs List” discussion (Vectors v Lists ). Lots of good info there.

Cheers

A follow up quick Q.

What is the best most robust way to declare the index .

int errTableIndex = 0;
OR
volatile int errTableIndex = 0;

From my reading it should just be int errTableIndex = 0; as there will not be an other infulence on errTableIndex. Is this correct?