c ++ 11 обобщенных атрибутов с avr __progmem__

Следующий код компилируется как ожидается с avr-g ++ 4.8.1:
(код должен разделяться на разные единицы перевода, чтобы увидеть какой-либо результат, потому что оптимизатор удалит все эффекты при вставке инструкций)

x.h:

struct X
{
uint8_t a;
};

x.cpp:

extern const X x __attribute__ ((__progmem__)) = { 1 };

main.cpp:

#include "x.h"extern const X x __attribute__ (( __progmem__ ));

int main()
{
PORTB = pgm_read_byte(& (x.a));
return 0;
}

Результаты в (objdump -d):

0000001a <x>:
1a:   01 00                                               ..
...

2e:   ea e1           ldi r30, 0x1A   ; 26
30:   f0 e0           ldi r31, 0x00   ; 0
32:   c8 95           lpm

результат в порядке.

В: Почему нельзя писать на с ++ 11:

 extern const X x [[__progmem__]] = { 1 };

это приводит к предупреждению «x.cpp: 8: 32: warning: ‘PROGMEM«директива атрибута игнорируется [-Wattributes]», и код не работает, потому что переменная x хранится в ram, а не во flash.

Следующий вопрос связан с использованием методов класса, которые должны обрабатывать элементы данных по-разному в отношении хранения во флэш-памяти или оперативной памяти.

хиджры:

    class A
{
private:
uint8_t a;

public:
constexpr A( uint8_t _a): a(_a) {}

void Store() const; // Q:should be something like const __attribute__((__PROGMEM__)) ???
void Store();
};

a.cpp:

   #include "a.h"
void A::Store() const
{
PORTB=pgm_read_byte(&a);
}

void A::Store()
{
PORTB=a;
}

extern const A a_const PROGMEM ={ 0x88 };
A a_non_const={ 0x99 };

main.cpp:

extern const A a_const;
extern A a_non_const;int main()
{
a_const.Store();
a_non_const.Store();

return 0;
}

Код работает нормально, но не работает, если объявления var:

extern const A a_const_non_flash={ 0x11 };

Поскольку квалификатора const для void Store () const недостаточно, чтобы решить, что var хранится во flash / ram. Есть ли какая-нибудь хитрость для этого?

2

Решение

Решение для первой части моего вопроса довольно просто:

extern const X x __attribute__ ((__progmem__)) = { 1 };
extern const X x [[gnu::__progmem__]] = { 1 };

Проблема заключалась в отсутствии атрибута gnu :: before.

1

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

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