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

发布于 2024-12-09 01:40:59 字数 942 浏览 0 评论 0原文

我有这段代码,

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

似乎可以解决问题。为什么它不适用于课程?

I have this code

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;
}

When i compile it i get

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

I'd expect const _port and _pin variables be stored in flash since they are marked const and initialization values are known at compile time, but they are allocated in .bss section. Is there any way to make them reside in flash memory?

EDIT:
I tried this:

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

seems to do the trick. Why doesn't it work with classes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

╄→承喏 2024-12-16 01:40:59

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

您可能可以使用模板类来实现您想要的目标,并将端口/引脚作为模板参数而不是构造函数参数传递。

它可能与编译器相关,但根据我的经验,您必须将变量声明为 static const 才能将其强制进入 Flash,但这对您想要执行的操作不起作用。

The parameters to the constructor are variables, you are assigning a variable to a const, which is OK in a constructor, but while a smart optimiser might spot the occurrence of the constant expressions in the static instantiation, you are probably asking a lot, since the general case requires the constructor to accept variables, and the code will be generated for the general case.

You could probably achieve what you want using a template class, and pass the port/pin as template arguments rather than constructor arguments.

It may be compiler dependent, but in my experience you have to declare a variable as static const to force it into Flash, but that will not work for what you are trying to do.

南城追梦 2024-12-16 01:40:59

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

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

Use a placement new to create an instance of the class in a specific memory location:

void * memPtr = 0x???????;
IO* ptrIO = new(memPtr) IO(LPC_GPIO0, 5);
流云如水 2024-12-16 01:40:59

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

struct 代码不会调用任何构造函数,无论是对于 struct 本身还是任何成员。

It doesn't work with classes because you're essentially initializing the const via a function call (ctor). That's similar to const int foo = rand() at global scope: const, but not an Integral Constant Expression.

The struct code doesn't invoke any ctor, neither for the struct itself nor for any member.

终止放荡 2024-12-16 01:40:59

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

I think you will see that it does. The data section is empty which probably means that your constants were stored in the text section. The text section is read-only and may well reside in execute-in-place NOR ROM depending on how your ROM images are built and run. (The bss section does not count since this does not contain any data per-se but rather tell the loader how much extra memory is needed for 0 initialized variables.)

回忆追雨的时光 2024-12-16 01:40:59

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

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

最终,这是一个优化问题,并且由于构造函数是内联的且微不足道的,因此可以完全消除它。然而,这可能需要你的编译器不具备的智能程度。

The line IO led1(LPC_GPIO0, 5); does two things. It tells the compiler to allocate a read/write structure of length 8 bytes long and then call the intiailization function viz. the construcotr to initialize it to LPC_GPIO0 and 5 respectively in writable static memory. This initialization is done by the constructor which is run before calling your main function

Your second example does not involve an intialization function viz. a constructor but is a simple initialization of non-changable memory to `LPC_GPIO0 and 5 respectively and can therefore be placed directly into the text section.

Ultimately this is an optimization issue and since the constructor is inlined and trivial it could be done away with entirely. However this probably takes a degree on intelligence that your compiler does not have.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文