ARM C ++ - как поместить константные члены во флэш-память? - PullRequest
4 голосов
/ 10 октября 2011

У меня есть этот код

class IO {
 public:       
    IO(LPC_GPIO_TypeDef* port, int pin) : _pin(pin), _port(port) {};        

    const int _pin;
    LPC_GPIO_TypeDef* const _port;


    void test() {
        LPC_GPIO0->FIOSET = 0;
    }

};

IO led1(LPC_GPIO0, 5);

int main() {
    led1.test();

    return 0;
}

Когда я скомпилирую его, я получу

text       data     bss     dec     hex  filename
656        0          8     664     298  lpc17xx

Я ожидаю, что переменные const _port и _pin будут храниться во флэш-памяти, поскольку они помечены как const изначения инициализации известны во время компиляции, но они размещаются в разделе .bss.Есть ли способ заставить их храниться во флеш-памяти?

РЕДАКТИРОВАТЬ: Я пробовал это:

struct IO {

    LPC_GPIO_TypeDef* port;
    int pin;

    void test() const {
        //_port->FIOSET = _pin;

        LPC_GPIO0->FIOSET = 0;
    }

};

const IO led1 = {LPC_GPIO0, 5};

text       data     bss     dec     hex filename
520        0          0     520     208 lpc17xx

, кажется, добиваться цели.Почему не работает с классами?

Ответы [ 5 ]

2 голосов
/ 10 октября 2011

Параметры для конструктора являются переменными, вы присваиваете переменную const, что нормально в конструкторе, но в то время как умный оптимизатор может обнаружить появление константных выражений в статической реализации, вы, вероятно, спрашиваете lot, поскольку общий случай требует, чтобы конструктор принял переменные, и для общего случая будет сгенерирован код.

Вероятно, вы можете достичь того, что хотите, используя класс шаблона, и передать порт / вывод в качестве аргументов шаблона, а не аргументов конструктора.

Это может зависеть от компилятора, но по моему опыту вы должны объявить переменную как статическую константу, чтобы принудительно заставить ее во Flash, но это не сработает для того, что вы пытаетесь сделать.

1 голос
/ 10 октября 2011

Используйте новое размещение для создания экземпляра класса в определенной ячейке памяти:

void * memPtr = 0x???????;
IO* ptrIO = new(memPtr) IO(LPC_GPIO0, 5);
1 голос
/ 10 октября 2011

Он не работает с классами, потому что вы по сути инициализируете const с помощью вызова функции (ctor).Это похоже на const int foo = rand() в глобальном масштабе: const, но не на выражение интегральной константы.

Код struct не вызывает ни ctor, ни для самого struct, ни для какого-либо члена.

0 голосов
/ 12 октября 2011

Линия IO led1(LPC_GPIO0, 5); делает две вещи. Он говорит компилятору выделить структуру для чтения / записи длиной 8 байт, а затем вызвать функцию инициализации viz. Конструктор инициализирует его LPC_GPIO0 и 5 соответственно в доступной для записи статической памяти. Эта инициализация выполняется конструктором, который запускается перед вызовом вашей основной функции

Ваш второй пример не включает функцию инициализации, а именно. конструктор, но представляет собой простую инициализацию неизменяемой памяти для `LPC_GPIO0 и 5 соответственно, и поэтому может быть помещен непосредственно в текстовый раздел.

В конечном счете, это проблема оптимизации, и поскольку конструктор встроен и тривиален, его можно полностью устранить. Однако это, вероятно, требует степени интеллекта, которой нет у вашего компилятора.

0 голосов
/ 10 октября 2011

Я думаю, вы увидите, что это так. Раздел data пуст, что, вероятно, означает, что ваши константы были сохранены в разделе text. Текстовый раздел предназначен только для чтения и вполне может находиться в NOR ROM, выполняемом на месте, в зависимости от того, как создаются и запускаются образы ROM. (Раздел bss не учитывается, так как он сам по себе не содержит никаких данных, а скорее сообщает загрузчику, сколько дополнительной памяти необходимо для 0 инициализированных переменных.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...