Pages: [1]   Go Down
Author Topic: Problemi con puntatore su vettore interrupt  (Read 541 times)
0 Members and 1 Guest are viewing this topic.
MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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':

Code:

//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

Code:
task_data.functionPointer(task_data.parameterPointer);

con

Code:

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

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

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 77
Posts: 4648
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

my name is IGOR, not AIGOR

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In effetti ti sbagli, perchè il parametro passato è già un puntatore, quindi un indirizzo.
Dereferenziando come hai mostrato tu,  nemmeno compila.
« Last Edit: January 29, 2013, 04:50:53 am by niki77 » Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 77
Posts: 4648
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Arduino non è un compilatore C++ (anche se parziale)?
http://www.html.it/pag/15499/parametri-per-valore-o-per-riferimento/

A me questo Arduino lo compila, sintassi tipica di C++ per il primo parametro (non del C)
Code:
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()
{
}
« Last Edit: January 29, 2013, 05:32:43 am by nid69ita » Logged

my name is IGOR, not AIGOR

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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.  smiley-wink
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 77
Posts: 4648
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
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.
« Last Edit: January 29, 2013, 06:05:02 am by nid69ita » Logged

my name is IGOR, not AIGOR

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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'è!!!!  smiley-sad-blue

E' stata una mia mancanza, lungi da me pensare che stai a dì fregnacce, ci mancherebbe!!  smiley-mr-green

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

Code:
//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  smiley-eek-blue
8F4 - 5  smiley-eek-blue smiley-eek-blue
8F4 - 5  smiley-eek-blue smiley-eek-blue smiley-eek-blue
...
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

ivrea (to)
Offline Offline
Faraday Member
**
Karma: 77
Posts: 4648
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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




Logged

my name is IGOR, not AIGOR

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!!
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Pages: [1]   Go Up
Jump to: