2012-10-21 2 views
0

J'ai deux tableaux. Et j'appelle une fonction à l'intérieur de main dans laquelle je suis en train de mettre à jour l'un des tableaux en fonction de certaines des valeurs de l'autre tableau.Comment passer un pointeur de tableau à une fonction?

volatile float32_t raw_data[3]; //this is being updated by an interrupt handler 
void get_acc(int32_t* acc_data, float32_t* raw_data) 
{ 
    acc_data[0] = (raw_data[0] - OFFSETX)/SENSX; //OFFSETX and SENSX defined as a macro 
    acc_data[1] = (raw_data[1] - OFFSETY)/SENSY; 
    acc_data[2] = (raw_data[2] - OFFSETZ)/SENSZ; 
} 
int main() 
{ 
    int32_t acc_data[3];  
    int32_t data_ready = 0; //being updated by interrupt handler 
    while(1) 
    { 
    if(data_ready) 
    get_acc(acc_data,raw_data); 
    } 
} 

Pour mon choc absolu, quand je regarde les variables en utilisant points d'arrêt et pas à pas dans get_acc, seul le premier acc_data [0] est mis à jour, tous les autres sont mis à 0, même si elles sont exécutées. Maintenant, ma première suspicion est que c'est quelque chose lié au pointeur, probablement l'adresse n'est pas mise à jour correctement. Parce que j'ai utilisé des tableaux de passage pour fonctionner comme ça où j'ai mis à jour les index de tableau dans une boucle for, pas manuellement. Quelqu'un peut-il donner un aperçu de ce qui pourrait être faux.

+0

Est-ce que raw_data est défini globalement? Si le pointeur raw_data n'est pas requis –

Répondre

2

Vous avez probablement subtiles erreurs de synchronisation ici:

  1. Comme Jonathan a souligné raw_data a perdu son match de qualification à l'intérieur de la fonction. L'utilisation d'une variable volatile de cette manière est un comportement non défini, même s'il n'y a pas de gestionnaire de signal impliqué.
  2. Il semble en outre que vos données sont touchées de manière asynchrone par un gestionnaire de signal. Le seul type de données à partir de C99 que vous pouvez toucher avec un tel gestionnaire de signal est sig_atomic_t. C11 va un peu plus loin et permet également d'autres types atomiques libres de verrouillage:

Lorsque le traitement de la machine abstraite est interrompue par la réception d'un signal, les valeurs des objets qui ne sont ni verrouillage sans atomique les objets de type volatil sig_atomic_t ne sont pas spécifiés, tout comme l'état de l'environnement en virgule flottante. La valeur de tout objet modifié par le gestionnaire qui n'est ni un objet atomique sans verrou ni de type volatile sig_atomic_t devient indéterminé lorsque le gestionnaire sort, tout comme l'état de l'environnement à virgule flottante s'il est modifié par le gestionnaire et non restauré à son état d'origine.

Comme vous le voyez, toucher des points flottants est considéré comme un refus.

1

Lorsque compilé le code (GCC 4.7.1 sous Mac OS X 10.7.5), je reçois un avertissement:

warning: passing argument 2 of ‘get_acc’ discards ‘volatile’ qualifier from pointer target type [enabled by default] 
note: expected ‘float32_t *’ but argument is of type ‘volatile float32_t *’ 

Je ne suis pas sûr que cela représente pour votre peine, mais il pourrait être un facteur. Je note que data_ready devrait également être volatile qualifié.

De plus, si vous compilez avec -Wshadow, vous obtenez:

In function ‘get_acc’: 
warning: declaration of ‘raw_data’ shadows a global declaration [-Wshadow] 

Ceci est plus une question de « risque de malentendu » que quelque chose de plus grave.

Cependant, en dehors de la différence de qualification, le code que vous montrez est propre et le compilateur devrait produire du code pour lire trois valeurs de raw_data et de traitement de celles en acc_data. Avez-vous regardé le langage d'assemblage généré pour la fonction?

Questions connexes