Arduino: PROGMEM странным образом взаимодействует с лямбдой структуры - PullRequest
0 голосов
/ 19 июня 2020

Массив агрегированных структур progmem, содержащих указатели на функции, является потенциально полезным способом реализации кнопок GUI в системе с ограничением ОЗУ Atmega328p, и возможность назначать анонимные функции обратного вызова каждой кнопке значительно улучшит их полезность. По этой причине меня не устраивает массив агрегатных структур progmem, содержащий типичные указатели на функции.

Приведенный ниже код изолирует то, что я считаю ошибкой во взаимодействии между ключевым словом PROGMEM и структурой, содержащей lambda.

//main.cpp
#include <Arduino.h>

//syntactic sugar
typedef void (*Callback)();

void func() {
  Serial.println("Hello from simpleFunc");
};
const static Callback prgFuncCallback PROGMEM = func;

const static Callback prgLambdaCallback PROGMEM = []()  {
                                                          Serial.println("Hello from simple lambda");
                                                        };


struct TestStruct {
  Callback cb;
  uint8_t num;
};

//=====================================================

void ramFunc() {
  Serial.println("Hello from Ram struct's func");
}

const static TestStruct ramFuncStruct {
  ramFunc,
  1,
};

const static TestStruct ramLambdaStruct {
  [](){
    Serial.println("Hello from Ram struct's lambda");
  },
  2,
};

//=====================================================

void prgFunc() {
  Serial.println("Hello from Prg struct's func");
}

const static TestStruct prgFuncStruct PROGMEM {
  prgFunc,
  3,
};

const static TestStruct prgLambdaStruct PROGMEM {
  [](){
    Serial.println("Hello from Prg struct's lambda");
  },
  4,
};

//=====================================================

const static TestStruct structArr[] = {ramFuncStruct, ramLambdaStruct, prgFuncStruct, prgLambdaStruct};

//=====================================================

void setup() {
  Serial.begin(9600);

  prgFuncCallback();
  prgLambdaCallback();

  for (uint8_t i = 0; i < 4; i++) {
    uint8_t val = structArr[i].num;
    Serial.print(val,DEC);
    Serial.print(" : ");
    structArr[i].cb();
  }
}

void loop() {
}

/* Serial output:
    Hello from simpleFunc
    Hello from simple lambda
    1 : Hello from Ram struct's func
    2 : Hello from Ram struct's lambda
    3 : Hello from Prg struct's func
    1 :
*/

Исходя из результатов этой программы, кажется, что включение лямбда-выражения в структуру, которая хранится в progmem, повредит структуру. Мало того, что последний обратный вызов выполняется неожиданным образом, но и численное значение в этой структуре, похоже, также повреждено.

Это моя ошибка или сбой библиотеки Arduino? Возможно, каким-то образом требуется memcpy_P или pgm_read?

РЕДАКТИРОВАТЬ: Нет, автоматизированная система Stackoverflow, это не связано с «Передачей захвата лямбда-выражения в качестве указателя на функцию», потому что я не передаю здесь никаких лямбда-выражений. Я передаю лямбда-выражения без захвата, и это становится проблемой только после того, как они передаются в список инициализации фигурных скобок агрегированной структуры PROGMEM.

...