Problemi con puntatore su vettore interrupt

Buongiorno a tutti.

Ho messo insieme alcune righe di codice che impostano un interrupt sull'overflow del timer generandomi una chiamata allo stesso vettore ogni secondo (ma questo tanto è ininfluente)
All'interno di questo interrupt vado ad effettuare una chiamata ad una void con parametri, tramite un puntatore alla stessa, contenuto in una struttura.
All'interno della stessa struttura è contenuto anche un puntatore uint8_t che contiene il valore delll'area di memoria dove sono presenti dei dati che voglio passare alla funzione menzionata sopra.

il codice 'looks like above':

//struttura dati task
struct TaskData
{
	void (*functionPointer)(uint8_t *);
	uint8_t * parameterPointer;
};


// questo è il vettore dell'interrupt
ISR(TIMER1_COMPA_vect)
{
  seconds++;
  if (seconds == UPDATE_INTERVALL )
  {
    if(task_data.functionPointer !=NULL)
    {
      task_data.functionPointer(task_data.parameterPointer); 
    }
  }
}

Il codice in oggetto riesce tranquillamente ad effettuare la chiamata alla funzione , ma il parametro non viene passato.
Ho provato anche a sostituire

 task_data.functionPointer(task_data.parameterPointer);

con

uint8_t params[2] = {1,0};
task_data.functionPointer(params);

Nel secondo caso i parametri vengono passati correttamente.
Avete qualche idea?
Grazie.

Sbaglio o dovresti sostituire

task_data.functionPointer(task_data.parameterPointer);

con

task_data.functionPointer(&task_data.parameterPointer);

tu chiedi un indirizzo, nel caso successivo passi un vettore che in C è implicitamente un indirizzo.

In effetti ti sbagli, perchè il parametro passato è già un puntatore, quindi un indirizzo.
Dereferenziando come hai mostrato tu, nemmeno compila.

Arduino non è un compilatore C++ (anche se parziale)?

A me questo Arduino lo compila, sintassi tipica di C++ per il primo parametro (non del C)

struct TaskData
{ void (*functionPointer)(uint8_t *);
  uint8_t * parameterPointer;
};

void xfunc(int &a,int b, int *c)
{ Serial.println(a);
  Serial.println(b);
  Serial.println((int)c);
}

void yfunc(struct TaskData& p1,struct TaskData* p2)
{
}

void setup()
{ int var=10;
  TaskData varTD;
  Serial.begin(9600);
  xfunc(var,var,&var);
  yfunc(varTD,&varTD);
}

void loop()
{
}

Scusa ma non mi sembra che stiamo parlando della stessa cosa.

struct TaskData
{ 
  void (*functionPointer)(uint8_t *);
  uint8_t * parameterPointer;
};

void xfunc(uint8_t * params)
{ 
}


void setup()
{ 
  uint8_t arr[2] = {2,0};
  xfunc(&arr);
}

void loop()
{
}

Vedi se ti compila questo.

A me interessa capire cosa c'è che non và a livello di concetto, non una scappatella per farlo compilare. :wink:

Quell'esempio tuo per forza non lo compila. Quello è già un vettore perciò un puntatore.
La mia spiegazione non è una scappatella.
Alle funzioni un compilatore C/C++ passa di default i parametri variabili e strutture per copia, i vettori per funzione.
(Vedi il link che ti ho messo)
Ti stò solo dicenendo che se passi alla tua funzione un vettore non devi mettere & mentre se passi una struttura si.

struct TaskData
{ void (*functionPointer)(uint8_t *);
  uint8_t * parameterPointer;
};

void xfunc(uint8_t * params)
{ }

void yfunc(struct TaskData *p)
{ }

void setup()
{ TaskData xTD;
  uint8_t arr[2] = {2,0};
  xfunc(arr);           // vettore, perciò puntatore
  yfunc(&xTD);       // struct perciò ne passo l'indirizzo altrimenti mi passa una copia
}

void loop()
{ }

infatti se provi a compilare, questo funziona.

Scusami , c'è stato un miss-undestand, avevo dato per scontato che nel post iniziale avessi scritto che passavo un vettore di valori ed invece ho controllato e non c'è!!!! :disappointed_relieved:

E' stata una mia mancanza, lungi da me pensare che stai a dì fregnacce, ci mancherebbe!! :grin:

Facendo dei test sul simulatore ho scoperto un altra cosa strana:

//struttura dati task
struct TaskData
{
	void (*functionPointer)(uint8_t *);
	uint8_t * parameterPointer ;
};
 
TaskData t;

//setup
void setup()
{
  Serial.begin(57600);
  uint8_t params[2] = {2,0};
  t.functionPointer = test;
  t.parameterPointer = params;
  Serial.print((uint16_t)t.parameterPointer,HEX);
  Serial.print(" - ");
  Serial.println(*t.parameterPointer,HEX);
}


//inizio del ciclo
void loop()
{
  delay(250);
  Serial.print((uint16_t)t.parameterPointer,HEX);
  Serial.print(" - ");
  Serial.println(*t.parameterPointer,HEX);
  delay(250);
}

output generato :

8F4 - 2
8F4 - 5 :fearful:
8F4 - 5 :fearful: :fearful:
8F4 - 5 :fearful: :fearful: :fearful:
...

Pensavo tu passassi tutta la struttura. Quel che ho detto io è in generale sul passaggio di strutture come parametri.
Nel tuo caso specifico CREDO di aver capito.

task_data.functionPointer(task_data.parameterPointer);
stai passando un parametro come pointer ad una variabile che è già pointer
mentre
uint8_t params[2] = {1,0};
task_data.functionPointer(params);
passi un puntatore

nel secondo caso puoi leggere subito i parametri mentre nel secondo devi ulteriormente usare l'indirizzo.
nel primo caso è come se tu usassi un uint8_t* * pointer a pointer

Ok tutto comincia a quagliare.

Ho trovato la spiegazione anche all'ultimo codice postato.
Praticamente non posso utilizzare un puntatore in questo caso, perchè andrei a valorizzarlo con l'indirizzo di memoria di una variabile che subito dopo esce dallo scope, e questo mi giustifica il valore cambiato, sicuramente nel frattempo sarà stato valorizzato da qualcos'altro...

Cambierò il tipo di dati nella struttura da uint8_t * ad un vettore uint8_t [2] .

Ora provo a mettere in campo la modifica per vedere se funziona.

Alla fine pare che la problematica sia del tutto scollegata dal fatto che la funzione venga chiamata dalla routine ISR.

Grazie!!