ARM C ++ - 如何将const成员放入闪存?

时间:2011-10-10 12:18:15

标签: c++ embedded const

我有这段代码

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变量存储在flash中,因为它们被标记为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 个答案:

答案 0 :(得分:2)

构造函数的参数是变量,您将变量赋给const,这在构造函数中是正常的,但是当智能优化器可能发现静态实例化中常量表达式的出现时,您可能会问很多,因为一般情况要求构造函数接受变量,并且将为一般情况生成代码。

您可以使用模板类实现所需,并将端口/引脚作为模板参数而不是构造函数参数传递。

它可能依赖于编译器,但根据我的经验,你必须将变量声明为静态const以强制它进入Flash,但这不适用于你想要做的事情。

答案 1 :(得分:1)

使用placement new在特定的内存位置创建类的实例:

void * memPtr = 0x???????;
IO* ptrIO = new(memPtr) IO(LPC_GPIO0, 5);

答案 2 :(得分:1)

它不适用于类,因为您实际上是通过函数调用(ctor)初始化const。这类似于全局范围内的const int foo = rand()const,但不是整数常量表达式。

struct代码不会调用任何ctor,也不会调用struct本身或任何成员。

答案 3 :(得分:0)

我想你会看到它确实如此。 data部分为空,这可能意味着您的常量存储在text部分中。文本部分是只读的,可能存在于就地执行NOR ROM中,具体取决于ROM映像的构建和运行方式。 (bss部分不计算,因为它不包含任何数据本身,而是告诉加载器0初始化变量需要多少额外内存。)

答案 4 :(得分:0)

IO led1(LPC_GPIO0, 5);行做了两件事。它告诉编译器分配长度为8个字节的读/写结构,然后调用intiailization函数即。 construcotr分别在可写静态存储器中将其初始化为LPC_GPIO0和5。此初始化由在调用主函数

之前运行的构造函数完成

您的第二个示例不涉及初始化功能即。一个构造函数,但是分别将非可变内存简单地初始化为“LPC_GPIO0和5”,因此可以直接放在文本部分中。

最终这是一个优化问题,因为构造函数内联且无关紧要,所以可以完全废除它。但是,这可能在一定程度上取决于编译器没有的智能。