Доступ к массиву Arduino приводит к неожиданным результатам

Я пытаюсь прочитать длину некоторых строк во флэш-памяти на моем Arduino UNO. Массив string_table Это вызывает у меня проблемы: если я получу индекс с чем-то, что компилятор оптимизирует до постоянной, то я получу ожидаемое значение. Если я получаю к нему доступ с помощью переменной во время выполнения, то каждый раз получаю разные ответы.

Я не думаю, что это специфично для Arduino, так как я, кажется, не называю какую-либо специфическую функциональность Arduino.

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

}
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

Решение

От АРН-Libcисходный код:

strlen_P() реализуется как встроенная функция в avr/pgmspace.h
заголовочный файл, который проверит, является ли длина строки
постоянный и известный во время компиляции
. Если это не известно при компиляции
время макрос выдаст вызов __strlen_P() который будет тогда
рассчитать длину строки как обычно.

Это могло бы объяснить это (хотя призыв к __strlen_P() должен был это исправить).

Возможно используйте вместо этого следующее:

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

Или, может быть, попробуйте использовать strlen_PF(),

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]