2017-03-07 1 views
-1

J'essaye de lire la longueur de certaines chaînes dans la mémoire flash sur mon Arduino UNO. Le tableau string_table me pose des problèmes, si j'obtiens l'index de celui-ci avec quelque chose que le compilateur optimise à une constante, alors j'obtiens la valeur attendue. Si j'y accède avec quelque chose qui est une variable au moment de l'exécution, alors j'obtiens une réponse différente chaque fois que je le fais.Arduino accéder tableau produit des résultats inattendus

Je ne pense pas que ce soit spécifique à Arduino, car je ne semble pas appeler de fonctionnalités spécifiques à Arduino.

Code:

#include <avr/pgmspace.h> 

// Entries stored in flash memory 
const char entry_0[] PROGMEM = "12345"; 
const char entry_1[] PROGMEM = "abc"; 
const char entry_2[] PROGMEM = "octagons"; 
const char entry_3[] PROGMEM = "fiver"; 

// Pointers to flash memory 
const char* const string_table[] PROGMEM = {entry_0, entry_1, entry_2, entry_3}; 

void setup() { 
    Serial.begin(115200); 
    randomSeed(analogRead(0)); 

    int r = random(4); 
    Serial.print("random key (r) : "); 
    Serial.println(r); 
    Serial.print("Wrong size for key = "); 
    Serial.print(r); 
    Serial.print(" : "); 
    Serial.println(strlen_P(string_table[r])); 
    int i = 1; 
    Serial.print("Correct size for key = "); 
    Serial.print(i); 
    Serial.print(" : "); 
    Serial.println(strlen_P(string_table[i])); 
    Serial.println("====="); 

    Serial.println("Expected Sizes: "); 
    Serial.print("0 is: "); 
    Serial.println(strlen_P(string_table[0])); 
    Serial.print("1 is: "); 
    Serial.println(strlen_P(string_table[1])); 
    Serial.print("2 is: "); 
    Serial.println(strlen_P(string_table[2])); 
    Serial.print("3 is: "); 
    Serial.println(strlen_P(string_table[3])); 
    Serial.println("++++++"); 

    Serial.println("Wrong Sizes: "); 
    for (i = 0; i < 4; i++) { 
    Serial.print(i); 
    Serial.print(" is: "); 
    Serial.println(strlen_P(string_table[i])); 
    } 
    Serial.println("------"); 
    delay(500); 
} 

void loop() { 
    // put your main code here, to run repeatedly: 

} 

Résultats:

random key (r) : 1 
Wrong size for key = 1 : 16203 
Correct size for key = 1 : 3 
===== 
Expected Sizes: 
0 is: 5 
1 is: 3 
2 is: 8 
3 is: 5 
++++++ 
Wrong Sizes: 
0 is: 0 
1 is: 11083 
2 is: 3 
3 is: 3 
------ 
+1

Ce n'est pas C! Arduino n'est pas C! – Olaf

+1

Pourquoi les downvotes? C'est une question intéressante (étiquetée C++ maintenant). –

Répondre

2

De avr-libc - source code:

strlen_P() est implémenté comme une fonction en ligne dans le fichier d'en-tête avr/pgmspace.h , qui sera vérifier si la longueur de la chaîne est une constante et connue au moment de la compilation. Si elle n'est pas connue au moment de la compilation , la macro émettra un appel à __strlen_P(), qui calculera la longueur de la chaîne comme normale.

Cela pourrait expliquer cela (bien que l'appel à __strlen_P() aurait dû corriger cela).

Peut-être utiliser les éléments suivants à la place:

strlen_P((char*)pgm_read_word(&(string_table[i]))); 

Ou peut-être essayer en utilisant strlen_PF().

+0

'strlen_P ((char *) pgm_read_word (& (string_table [i])));' était la solution. Merci pour l'explication concise, et pour ne pas avoir voté ma question. – Morgoth